From 648906290dce7ae7527cb562447e0532e0452a5d Mon Sep 17 00:00:00 2001 From: satyakwok <119509589+satyakwok@users.noreply.github.com> Date: Mon, 11 May 2026 00:30:13 +0200 Subject: [PATCH 1/2] fix(rpc): self-describe reads chain name from genesis (not hardcoded) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the deferred TODO from PR #560 (genesis [chain].name + METAMASK doc alignment). The / RPC root handler hardcoded "name": "Sentrix" on every network — testnet binaries pretended to be mainnet for any caller probing the self-describe endpoint. Now Blockchain holds chain_name (sourced from genesis.chain.name in new_with_genesis) and the route reads it. Mainnet returns "Sentrix Chain", testnet returns "Sentrix Testnet" — matches the canonical chainlist registry submission. The chain_name field carries a serde default ("Sentrix Chain") to keep pre-this-commit state-blob deserialisations working; real boot always overwrites via new_with_genesis. Field impact is purely cosmetic — wallets / chainid registry use chain_id (eth_chainId) for identity, not the / endpoint. But honest self-describe is the right thing for any future tooling that probes it (block-explorer auto-config, dApp-ops dashboards, status pages). --- crates/sentrix-core/src/blockchain.rs | 16 ++++++++++++++++ crates/sentrix-rpc/src/routes/ops.rs | 8 +++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/sentrix-core/src/blockchain.rs b/crates/sentrix-core/src/blockchain.rs index 6d6eaa20..e3c47a06 100644 --- a/crates/sentrix-core/src/blockchain.rs +++ b/crates/sentrix-core/src/blockchain.rs @@ -458,6 +458,14 @@ pub struct Blockchain { pub mempool_sender_count: std::collections::HashMap, pub total_minted: u64, pub chain_id: u64, // kept pub — read-only constant used by external clients + /// Display name of this network (eg "Sentrix Chain", "Sentrix Testnet"). + /// Sourced from the loaded genesis `[chain].name` so testnet binaries + /// don't lie about being mainnet on the `/` self-describe endpoint. + /// Default exists only because pre-genesis ctors (tests) skip the + /// genesis path; real boot always overwrites this in + /// `new_with_genesis`. + #[serde(default = "Blockchain::default_chain_name")] + pub chain_name: String, /// Binary Sparse Merkle Tree for account state. /// None until init_trie() is called; not persisted in MDBX state blob. #[serde(skip)] @@ -624,6 +632,13 @@ fn default_block_source() -> crate::block_executor::BlockSource { } impl Blockchain { + /// Default for the `chain_name` serde-skip field — only matters for + /// pre-genesis state-blob deserialisations that predate the field. + /// Real boot always overwrites via `new_with_genesis`. + fn default_chain_name() -> String { + "Sentrix Chain".to_string() + } + /// Construct a blockchain initialised from the embedded canonical mainnet /// genesis. Thin wrapper over [`Blockchain::new_with_genesis`]. /// @@ -658,6 +673,7 @@ impl Blockchain { .ok() .and_then(|v| v.parse().ok()) .unwrap_or(genesis.chain.chain_id), + chain_name: genesis.chain.name.clone(), state_trie: None, mdbx_storage: None, stake_registry: sentrix_staking::staking::StakeRegistry::new(), diff --git a/crates/sentrix-rpc/src/routes/ops.rs b/crates/sentrix-rpc/src/routes/ops.rs index 4da00073..d20d9190 100644 --- a/crates/sentrix-rpc/src/routes/ops.rs +++ b/crates/sentrix-rpc/src/routes/ops.rs @@ -29,10 +29,16 @@ pub(super) async fn root(State(state): State) -> Json Date: Mon, 11 May 2026 00:38:05 +0200 Subject: [PATCH 2/2] fix(rpc): chain_name fix-up on load (upgrade-path bug) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original commit relied on new_with_genesis to set chain_name, but that path only runs on a fresh init. Existing chain.dbs (mainnet + testnet today) come up via load_blockchain, which deserialises an old blob without the chain_name field — serde defaults silently fired and testnet would still self-describe as "Sentrix Chain". Override from the canonical chain_id mapping right after the blob deserialises. First save_blockchain after this fix-up persists the corrected name so subsequent boots find it already right. Custom chain_ids (third-party deployments) fall through to whatever genesis set; we only normalise the two we ship. --- crates/sentrix-core/src/storage.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crates/sentrix-core/src/storage.rs b/crates/sentrix-core/src/storage.rs index 84f5933e..d1186dd1 100644 --- a/crates/sentrix-core/src/storage.rs +++ b/crates/sentrix-core/src/storage.rs @@ -57,6 +57,29 @@ impl Storage { } }; + // Upgrade-path fix-up for chain_name. The field gets a serde + // default of "Sentrix Chain" so old state blobs deserialise + // cleanly, but on testnet that means the loaded value silently + // takes mainnet's name. Override from the canonical chain_id + // mapping so the self-describe endpoint reflects the network + // this binary is actually running. The very first save_blockchain + // after this fix-up persists the corrected name so subsequent + // boots find it already right. + let canonical = match bc.chain_id { + 7119 => Some("Sentrix Chain"), + 7120 => Some("Sentrix Testnet"), + _ => None, + }; + if let Some(name) = canonical + && bc.chain_name != name + { + tracing::info!( + "chain_name fix-up on load: chain_id={} blob={:?} → {:?}", + bc.chain_id, bc.chain_name, name, + ); + bc.chain_name = name.to_string(); + } + // Load only the sliding window (last CHAIN_WINDOW_SIZE blocks) into RAM. let height = self .chain