diff --git a/docs/resources/gas-fees.md b/docs/resources/gas-fees.md index 3258be1f4cb..c8f9d2a7fa6 100644 --- a/docs/resources/gas-fees.md +++ b/docs/resources/gas-fees.md @@ -135,7 +135,7 @@ gnokey maketx addpkg \ -gas-fee 1000000ugnot \ -remote https://rpc.gno.land:443 \ -broadcast \ - -chainid staging \ + -chainid gnoland1 \ -simulate only \ YOUR_KEY_NAME ``` diff --git a/docs/resources/gnoland-networks.md b/docs/resources/gnoland-networks.md index b67d28fe402..7e01df9b649 100644 --- a/docs/resources/gnoland-networks.md +++ b/docs/resources/gnoland-networks.md @@ -2,10 +2,11 @@ ## Network configurations -| Network | RPC Endpoint | Chain ID | -|---------|------------------------------------------|-----------| -| Staging | https://rpc.gno.land:443 | `staging` | -| Test11 | https://rpc.test11.testnets.gno.land:443 | `test11` | +| Network | RPC Endpoint | Chain ID | +|-------------------|------------------------------------------|--------------| +| Betanet (current) | https://rpc.gno.land:443 | `gnoland-1` | +| Staging | https://rpc.staging.gno.land:443 | `staging` | +| Test11 | https://rpc.test11.testnets.gno.land:443 | `test11` | ### WebSocket endpoints @@ -68,8 +69,8 @@ After genesis has been replayed, the chain continues working as normal. ### Using the Staging network -The Staging network deployment can be found at [gno.land](https://gno.land), while -the exposed RPC endpoints can be found on `https://rpc.gno.land:443`. +The Staging network deployment can be found at [staging.gno.land](https://staging.gno.land), while +the exposed RPC endpoints can be found on `https://rpc.staging.gno.land:443`. #### A warning note @@ -113,7 +114,7 @@ Below you can find a breakdown of each existing testnet by these categories. ### Staging chain The Staging chain is an always up-to-date rolling testnet. It is meant to be used as -a nightly build of the Gno tech stack. The home page of [gno.land](https://gno.land) +a nightly build of the Gno tech stack. The home page of [staging.gno.land](https://staging.gno.land) is the `gnoweb` render of the Staging testnet. - **Persistence of state:** diff --git a/docs/users/explore-with-gnoweb.md b/docs/users/explore-with-gnoweb.md index 52b75a08cf6..a6ea915bc78 100644 --- a/docs/users/explore-with-gnoweb.md +++ b/docs/users/explore-with-gnoweb.md @@ -6,7 +6,7 @@ to explore the blockchain ecosystem. ## Networks -The main gnoweb instance is available at [gno.land](https://gno.land), which serves the Staging network. +The main gnoweb instance is available at [gno.land](https://gno.land), which serves the Betanet (`gnoland1`). The Staging network is accessible at [staging.gno.land](https://staging.gno.land). For a complete list of all available networks (testnets and more), see [Networks](../resources/gnoland-networks.md). @@ -74,7 +74,7 @@ func Render(path string) string { Based on the provided path, `gnoweb` queries the Gno.land network using the `qrender` ABCI query. It then renders the response data as Markdown. -The realm above can be found on the Staging network at [`gno.land/r/docs/hello`](https://gno.land/r/docs/hello). +The realm above can be found on the Staging network at [`gno.land/r/docs/hello`](https://staging.gno.land/r/docs/hello). While JS/TS clients for Gno exist and developers can create custom websites for their Gno.land applications as they see fit, the approach `gnoweb` takes with `Render()` @@ -90,7 +90,7 @@ Custom getter methods tailored to the specifics of the realm can be built instea All code uploaded to Gno.land is open-source and available for everyone to see, by design. -Visit the [`gno.land/r/docs/source`](https://gno.land/r/docs/source) realm to learn +Visit the [`gno.land/r/docs/source`](https://staging.gno.land/r/docs/source) realm to learn how you can do this. ## Alternative: Terminal UI with gnobro diff --git a/misc/deployments/gnoland-1/README.md b/misc/deployments/gnoland-1/README.md new file mode 100644 index 00000000000..68dc9a11610 --- /dev/null +++ b/misc/deployments/gnoland-1/README.md @@ -0,0 +1,99 @@ +# gnoland-1 — Hard Fork of gnoland1 + +`gnoland-1` is the upgraded successor to `gnoland1`. It is produced via a +coordinated hard fork at a governance-approved halt height. + +## Chain ID change + +| Old | New | +|----------|------------| +| gnoland1 | gnoland-1 | + +The hyphen was added to make the chain ID upgrade-compatible — `gnoland1` +could not support chain upgrades that preserve the chain ID cleanly because +the naming convention conflated chain identity with version. `gnoland-1` is +the permanent base name; future upgrades increment a suffix on a sub-release +tag (e.g., `chain/gnoland-1.1`). + +## What changed + +This hard fork bundles the following upgrades in one shot: + +- **`r/sys/params` halt height** (gnolang/gno#5368): GovDAO can now vote to + halt the chain at a specific block and enforce a minimum binary version on + restart. _(awaiting merge)_ +- **`r/gnops/valopers` fee = 0**: Registration fee was set to 0 via a GovDAO + transaction on gnoland1; preserved in genesis replay. No code change needed. +- **Namereg GovDAO whitelist** (gnolang/gno#5293): Namereg now checks GovDAO + membership before allowing name registration. ✅ _merged_ +- **GovDAO scripts** (gnolang/gno#5375): Updated scripts for the new chain. ✅ _merged_ + +**Not confirmed for this hard fork** (need explicit sign-off from Jae): +- Gas parameter updates (gnolang/gno#5291, #5289, #5274) + +## Upgrade workflow + +Approach: **Scenario A — genesis tx-replay with InitialHeight preservation**. +All historical txs from gnoland1 are exported with their original block heights +and timestamps, then assembled into the genesis for gnoland-1. The new chain +starts at `initial_height = halt_height + 1`, preserving height continuity. + +``` +gnoland1 (running) + │ + ├── [gnoland1.2] Operators rolling-update with halt_height config + │ + ├── Chain halts at GovDAO-approved height + │ + ├── Each validator runs migrate-from-gnoland1.sh ← NOT YET IMPLEMENTED + │ - tx-archive exports all txs with block height + timestamp + │ - genesis-assemble produces genesis.json for gnoland-1 + │ (chain_id=gnoland-1, initial_height=halt+1, original_chain_id=gnoland1) + │ + ├── Validators compare genesis.json SHA-256 + │ (must all match before anyone restarts) + │ + └── Validators restart with new binary + new genesis + chain-id: gnoland-1, starts at height halt+1 +``` + +## ⚠️ Migration script not yet written + +**The migration script (`migrate-from-gnoland1.sh`) is the critical missing +piece.** Until it exists and has been tested on a dry-run on test12, the +hard fork cannot happen. + +Blockers: +- `tx-archive genesis-assemble` command (companion to gnolang/gno#5411) +- `tx-archive` offline export from block store (no live node required) +- Jae's tm2 `GenesisDoc.InitialHeight` port (hard blocker for gnolang/gno#5411) +- test12 dry-run: full halt → export → genesis-assemble → restart + +See the TODO block inside `migrate-from-gnoland1.sh` for details. + +Dry-run target: test12 (see gnoland1/govdao-scripts/ for tooling). + +## GovDAO scripts + +The govdao scripts in `govdao-scripts/` are identical to those in +`../gnoland1/govdao-scripts/` but default to `CHAIN_ID=gnoland-1`. + +All scripts default to `GNOKEY_NAME=moul`, `CHAIN_ID=gnoland-1`, and +`REMOTE=https://rpc.gno.land:443`. Override via env vars. + +```bash +./govdao-scripts/add-validator-from-valopers.sh ADDR +./govdao-scripts/add-validator.sh ADDR PUBKEY [POWER] +./govdao-scripts/rm-validator.sh ADDR +./govdao-scripts/unrestrict-account.sh ADDR [ADDR...] +``` + +## Config + +Copy `config.toml` and edit the `# Change me` fields: + +```shell +mkdir -p gnoland-data/config +cp config.toml gnoland-data/config/config.toml +grep -n "Change me" gnoland-data/config/config.toml +``` diff --git a/misc/deployments/gnoland-1/config.toml b/misc/deployments/gnoland-1/config.toml new file mode 100644 index 00000000000..9d07079c679 --- /dev/null +++ b/misc/deployments/gnoland-1/config.toml @@ -0,0 +1,256 @@ +# Mechanism to connect to the ABCI application: socket | grpc +abci = "socket" + +# Database backend: pebbledb | goleveldb | boltdb +#* pebbledb (github.com/cockroachdb/pebble) +# - pure go +# - stable +#* goleveldb (github.com/syndtr/goleveldb) +# - pure go +# - stable +# - use goleveldb build tag +#* boltdb (uses etcd's fork of bolt - go.etcd.io/bbolt) +# - EXPERIMENTAL +# - may be faster is some use-cases (random reads - indexer) +# - use boltdb build tag (go build -tags boltdb) +db_backend = "pebbledb" + +# Database directory +db_dir = "db" + +# If this node is many blocks behind the tip of the chain, FastSync +# allows them to catchup quickly by downloading blocks in parallel +# and verifying their commits +fast_sync = true +home = "" + +# A custom human readable name for this node +moniker = "" # TODO: Change me! + +# Path to the JSON file containing the private key to use for node authentication in the p2p protocol +node_key_file = "secrets/node_key.json" + +# TCP or UNIX socket address for the profiling server to listen on +prof_laddr = "" + +# TCP or UNIX socket address of the ABCI application, +# or the name of an ABCI application compiled in with the Tendermint binary +proxy_app = "tcp://127.0.0.1:26658" + +##### app settings ##### +[application] + +# Lowest gas prices accepted by a validator +min_gas_prices = "" + +# State pruning strategy [everything, nothing, syncable] +prune_strategy = "syncable" + +##### consensus configuration options ##### +[consensus] + +# EmptyBlocks mode and possible interval between empty blocks +create_empty_blocks = true +create_empty_blocks_interval = "0s" +home = "" + +# Reactor sleep duration parameters +peer_gossip_sleep_duration = "10ms" # Do NOT change me, leave me at 10ms! +peer_query_maj23_sleep_duration = "2s" + +# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) +skip_timeout_commit = false +timeout_commit = "3s" # Do NOT change me, leave me at 3s! +timeout_precommit = "1s" +timeout_precommit_delta = "500ms" +timeout_prevote = "1s" +timeout_prevote_delta = "500ms" +timeout_propose = "3s" +timeout_propose_delta = "500ms" +wal_file = "wal/cs.wal/wal" + +##### private validator configuration options ##### +[consensus.priv_validator] +home = "" + +# Path to the JSON file containing the private key to use for signing using a local signer +local_signer = "priv_validator_key.json" + +# Path to the JSON file containing the last validator state to prevent double-signing +sign_state = "priv_validator_state.json" + +# Configuration for the remote signer client +[consensus.priv_validator.remote_signer] + +# Maximum number of retries to dial the remote signer. If set to -1, will retry indefinitely +dial_max_retries = -1 + +# Interval between retries to dial the remote signer +dial_retry_interval = "5s" + +# Timeout to dial the remote signer +dial_timeout = "5s" + +# Timeout for requests to the remote signer +request_timeout = "5s" + +# Address of the remote signer to dial (UNIX or TCP). If set, the local signer is disabled +server_address = "" + +# List of authorized public keys for the remote signer (only for TCP). If empty, all keys are authorized +tcp_authorized_keys = [] + +# Keep alive period for the remote signer connection (only for TCP) +tcp_keep_alive_period = "2s" + +##### mempool configuration options ##### +[mempool] +broadcast = true + +# Size of the cache (used to filter transactions we saw earlier) in transactions +cache_size = 10000 +home = "" + +# Limit the total size of all txs in the mempool. +# This only accounts for raw transactions (e.g. given 1MB transactions and +# max_txs_bytes=5MB, mempool will only accept 5 transactions). +max_pending_txs_bytes = 1073741824 # ~1GB +recheck = true + +# Maximum number of transactions in the mempool +size = 10000 # Advised value is 10000 +wal_dir = "" + +##### peer to peer configuration options ##### +[p2p] + +# Address to advertise to peers for them to dial +# If empty, will use the same port as the laddr, +# and will introspect on the listener or use UPnP +# to figure out the address. +external_address = "" # TODO: Change me! + +# Time to wait before flushing messages out on the connection +flush_throttle_timeout = "10ms" # Do NOT change me, leave me at 10ms! +home = "" + +# Address to listen for incoming connections +laddr = "tcp://0.0.0.0:26656" + +# Maximum number of inbound peers +max_num_inbound_peers = 40 + +# Maximum number of outbound peers to connect to, excluding persistent peers +max_num_outbound_peers = 40 # Advised value is 40 + +# Maximum size of a message packet payload, in bytes +max_packet_msg_payload_size = 1024 + +# Comma separated list of nodes to keep persistent connections to +persistent_peers = "" # Change me: update with gnoland-1 peer addresses after the hard fork + +# Set true to enable the peer-exchange reactor +pex = true + +# Comma separated list of peer IDs to keep private (will not be gossiped to other peers) +private_peer_ids = "" + +# Rate at which packets can be received, in bytes/second +recv_rate = 5120000 + +# Comma separated list of seed nodes to connect to +seeds = "" # Change me: update with gnoland-1 seed addresses after the hard fork + +# Rate at which packets can be sent, in bytes/second +send_rate = 5120000 + +##### rpc server configuration options ##### +[rpc] + +# A list of non simple headers the client is allowed to use with cross-domain requests +cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time"] + +# A list of methods the client is allowed to use with cross-domain requests +cors_allowed_methods = ["HEAD", "GET", "POST", "OPTIONS"] + +# A list of origins a cross-domain request can be executed from +# Default value '[]' disables cors support +# Use '["*"]' to allow any origin +cors_allowed_origins = ["*"] + +# TCP or UNIX socket address for the gRPC server to listen on +# NOTE: This server only supports /broadcast_tx_commit +grpc_laddr = "" + +# Maximum number of simultaneous connections. +# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +grpc_max_open_connections = 900 +home = "" + +# TCP or UNIX socket address for the RPC server to listen on +laddr = "tcp://0.0.0.0:26657" # Please use a reverse proxy! + +# Maximum size of request body, in bytes +max_body_bytes = 1000000 + +# Maximum size of request header, in bytes +max_header_bytes = 1048576 + +# Maximum number of simultaneous connections (including WebSocket). +# Does not include gRPC connections. See grpc_max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +max_open_connections = 900 + +# How long to wait for a tx to be committed during /broadcast_tx_commit. +# WARNING: Using a value larger than 10s will result in increasing the +# global HTTP write timeout, which applies to all connections and endpoints. +# See https://github.com/tendermint/tendermint/issues/3435 +timeout_broadcast_tx_commit = "10s" + +# The path to a file containing certificate that is used to create the HTTPS server. +# Might be either absolute path or path related to tendermint's config directory. +# If the certificate is signed by a certificate authority, +# the certFile should be the concatenation of the server's certificate, any intermediates, +# and the CA's certificate. +# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. +tls_cert_file = "" + +# The path to a file containing matching private key that is used to create the HTTPS server. +# Might be either absolute path or path related to tendermint's config directory. +# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. +tls_key_file = "" + +# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool +unsafe = false + +##### node telemetry ##### +[telemetry] +# the endpoint to export metrics to, like a local OpenTelemetry collector +exporter_endpoint = "" # Change me to the OTEL endpoint! +meter_name = "gnoland-1" +metrics_enabled = false # Advised to be `true` + +# the ID helps to distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled service), in Prometheus this is transformed into the label 'exported_instance +service_instance_id = "gno-node-1" # Change me! + +# in Prometheus this is transformed into the label 'exported_job' +service_name = "gno.land" +traces_enabled = false + +##### event store ##### +[tx_event_store] + +# Type of event store +event_store_type = "none" + +# Event store parameters +[tx_event_store.event_store_params] diff --git a/misc/deployments/gnoland-1/govdao-scripts/add-validator-from-valopers.sh b/misc/deployments/gnoland-1/govdao-scripts/add-validator-from-valopers.sh new file mode 100755 index 00000000000..31928940ece --- /dev/null +++ b/misc/deployments/gnoland-1/govdao-scripts/add-validator-from-valopers.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# Add a validator from the r/gnops/valopers registry via govDAO proposal. +# +# Uses r/gnops/valopers/proposal.NewValidatorProposalRequest to look up the +# valoper profile on-chain and create a governance proposal, then votes YES +# and executes it immediately. +# +# Usage: +# ./add-validator-from-valopers.sh
+# +# Environment: +# GNOKEY_NAME - gnokey key name (default: moul) +# CHAIN_ID - chain ID (default: gnoland-1) +# REMOTE - RPC endpoint (default: https://rpc.betanet.testnets.gno.land:443) +# GAS_WANTED - gas limit (default: 50000000) +# GAS_FEE - gas fee (default: 1000000ugnot) +set -eo pipefail + +GNOKEY_NAME="${GNOKEY_NAME:-moul}" +CHAIN_ID="${CHAIN_ID:-gnoland-1}" +REMOTE="${REMOTE:-https://rpc.betanet.testnets.gno.land:443}" +GAS_WANTED="${GAS_WANTED:-50000000}" +GAS_FEE="${GAS_FEE:-1000000ugnot}" + +if [ $# -lt 1 ]; then + echo "Usage: $0
" + echo "" + echo "Looks up the valoper profile from r/gnops/valopers and creates a" + echo "govDAO proposal to add them to the validator set, votes YES, and" + echo "executes it." + echo "" + echo "The valoper must have registered at r/gnops/valopers first." + echo "" + echo "Example:" + echo " $0 g1abc...xyz" + exit 1 +fi + +ADDR="$1" + +TMPDIR=$(mktemp -d) +trap 'rm -rf "$TMPDIR"' EXIT + +cat >"$TMPDIR/add_from_valopers.gno" < [voting_power] +# +# Environment: +# GNOKEY_NAME - gnokey key name (default: moul) +# CHAIN_ID - chain ID (default: gnoland-1) +# REMOTE - RPC endpoint (default: https://rpc.betanet.testnets.gno.land:443) +# GAS_WANTED - gas limit (default: 50000000) +# GAS_FEE - gas fee (default: 1000000ugnot) +set -eo pipefail + +GNOKEY_NAME="${GNOKEY_NAME:-moul}" +CHAIN_ID="${CHAIN_ID:-gnoland-1}" +REMOTE="${REMOTE:-https://rpc.betanet.testnets.gno.land:443}" +GAS_WANTED="${GAS_WANTED:-50000000}" +GAS_FEE="${GAS_FEE:-1000000ugnot}" + +if [ $# -lt 2 ]; then + echo "Usage: $0
[voting_power]" + echo "" + echo "Example:" + echo " $0 g1abc...xyz gpub1pggj7... 1" + exit 1 +fi + +ADDR="$1" +PUB_KEY="$2" +POWER="${3:-1}" + +TMPDIR=$(mktemp -d) +trap 'rm -rf "$TMPDIR"' EXIT + +cat >"$TMPDIR/add_validator.gno" < +# +# Environment: +# GNOKEY_NAME - gnokey key name (default: moul) +# CHAIN_ID - chain ID (default: gnoland-1) +# REMOTE - RPC endpoint (default: https://rpc.betanet.testnets.gno.land:443) +# GAS_WANTED - gas limit (default: 50000000) +# GAS_FEE - gas fee (default: 1000000ugnot) +set -eo pipefail + +GNOKEY_NAME="${GNOKEY_NAME:-moul}" +CHAIN_ID="${CHAIN_ID:-gnoland-1}" +REMOTE="${REMOTE:-https://rpc.betanet.testnets.gno.land:443}" +GAS_WANTED="${GAS_WANTED:-50000000}" +GAS_FEE="${GAS_FEE:-1000000ugnot}" + +if [ $# -lt 1 ]; then + echo "Usage: $0
" + echo "" + echo "Example:" + echo " $0 g1abc...xyz" + exit 1 +fi + +ADDR="$1" + +TMPDIR=$(mktemp -d) +trap 'rm -rf "$TMPDIR"' EXIT + +cat >"$TMPDIR/rm_validator.gno" <&2 + exit 1 +fi + +GNOKEY_NAME="${GNOKEY_NAME:-moul}" +CHAIN_ID="${CHAIN_ID:-gnoland-1}" +REMOTE="${REMOTE:-https://rpc.betanet.testnets.gno.land:443}" +GAS_WANTED="${GAS_WANTED:-50000000}" +GAS_FEE="${GAS_FEE:-1000000ugnot}" + +# Build address list for the Gno code. +ADDR_ARGS="" +for addr in "$@"; do + ADDR_ARGS="${ADDR_ARGS} address(\"${addr}\"), +" +done + +TMPDIR=$(mktemp -d) +trap 'rm -rf "$TMPDIR"' EXIT + +cat >"$TMPDIR/unrestrict.gno" < +# app_state.txs: full tx array with metadata preserved +# - Height AND timestamp are preserved (Jae's correctness requirement). +# - Validators independently run this script and compare genesis SHA-256 +# before restarting. +# +# Usage: +# ./migrate-from-gnoland1.sh --data-dir [--halt-height N] +# +# The script writes genesis.json (gnoland-1) to the current directory. +# +# Prerequisites: +# - gnoland1 must be fully halted at the governance-approved halt height +# - tx-archive (with genesis-assemble subcommand) must be installed +# See: https://github.com/gnolang/tx-archive +# - The new gnoland binary (>= gnoland-1) must be in PATH +# +# Dependencies (PRs that must be merged in the new binary): +# - #5334: halt_height config field (MERGED) +# - #5293: namereg GovDAO whitelist (MERGED) +# - #5375: new govdao-scripts (MERGED) +# - #5368: GovDAO-based halt height via r/sys/params (awaiting merge) +# - #5411: genesis replay with OriginalChainID (awaiting merge) +# - #5390: GnoTxMetadata block_height + chain_id extension (awaiting merge) +set -eo pipefail + +# ============================================================================= +# TODO: IMPLEMENT THIS MIGRATION SCRIPT +# +# This is the critical piece that makes the gnoland1 → gnoland-1 hard fork +# possible. Until it is written AND dry-run on test12, the hard fork CANNOT happen. +# +# The decisions below have been made (as of 2026-04-09): +# ✅ Scenario A chosen: genesis tx-replay with InitialHeight preservation +# ✅ Scenario B (height reset) deprioritized +# ✅ Chain ID: gnoland1 → gnoland-1 (one-time rename, agreed) +# ✅ Height + timestamp preservation required (Jae's correctness requirement) +# ✅ #5334, #5293, #5375 merged +# ⏳ #5368 (GovDAO halt) awaiting reviews +# ⏳ #5411 (genesis replay), #5390 (tx metadata) awaiting merge +# ⏳ #5377 (--migrate flag) may be superseded by #5411 approach +# +# Implementation steps: +# +# 1. HALT VERIFICATION +# Check the data dir to confirm gnoland1 stopped at the expected height. +# Read the committed block height from the blockstore and compare against +# the halt_height that was voted on via GovDAO (#5368). +# +# 2. TX EXPORT +# Run tx-archive backup against the halted gnoland1 data dir to produce +# a JSONL file with all successful txs, each including: +# - timestamp: Unix seconds of the block that included the tx +# - block_height: block number the tx ran at (#5390) +# - chain_id: "gnoland1" (#5390) +# Command (once tx-archive supports --data-dir mode): +# tx-archive backup \ +# --data-dir "$DATA_DIR" \ +# --output txs.jsonl +# +# 3. GENESIS ASSEMBLY +# Run tx-archive genesis-assemble to produce genesis.json: +# tx-archive genesis-assemble \ +# --input txs.jsonl \ +# --chain-id gnoland-1 \ +# --original-chain-id gnoland1 \ +# --initial-height $((HALT_HEIGHT + 1)) \ +# --output genesis.json +# The genesis will have: +# chain_id: "gnoland-1" +# initial_height: halt_height + 1 (Jae's InitialHeight tm2 port required) +# app_state.txs: full tx array with metadata +# app_state.original_chain_id: "gnoland1" (for sig verification) +# +# 4. VERIFICATION +# All validators independently run this script and compare: +# sha256sum genesis.json +# Hashes MUST match before anyone restarts. +# Optionally run gnoupgrade statediff for before/after comparison. +# +# 5. RESTART COORDINATION +# Validators restart with the new binary and the new genesis.json. +# The new binary must be >= chain/gnoland-1 tag. +# +# BLOCKERS (must be resolved before implementing): +# [ ] tx-archive genesis-assemble command (companion to #5411) +# [ ] tx-archive --data-dir mode for offline export from block store +# [ ] Jae's tm2 GenesisDoc.InitialHeight field (hard blocker for #5411) +# [ ] test12 dry-run: validate full halt → export → genesis-assemble → restart +# +# RELATED: +# Issue #5374: chain upgrade strategy meta-issue +# PR #5411: genesis replay mechanism (main hardfork PR) +# PR #5390: GnoTxMetadata block_height + chain_id extension +# PR #5368: GovDAO-based halt height via r/sys/params +# PR #5377: in-place block-replay --migrate flag (may complement #5411) +# PR #5369: gnoupgrade toolkit (replay/statediff/healthcheck) +# ============================================================================= + +echo "ERROR: migrate-from-gnoland1.sh is not yet implemented." +echo "" +echo "Blockers:" +echo " - tx-archive genesis-assemble command (companion to gnolang/gno#5411)" +echo " - Jae's tm2 GenesisDoc.InitialHeight field" +echo " - test12 dry-run of the full halt → export → genesis-assemble → restart flow" +echo "" +echo "Track progress at: https://github.com/gnolang/gno/issues/5374" +exit 1