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
16 changes: 16 additions & 0 deletions crates/sentrix-core/src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,14 @@ pub struct Blockchain {
pub mempool_sender_count: std::collections::HashMap<String, u32>,
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)]
Expand Down Expand Up @@ -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`].
///
Expand Down Expand Up @@ -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(),
Expand Down
23 changes: 23 additions & 0 deletions crates/sentrix-core/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion crates/sentrix-rpc/src/routes/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,16 @@ pub(super) async fn root(State(state): State<SharedState>) -> Json<serde_json::V
// explorers, wallets) need accurate consensus mode.
let bc = state.read().await;
let chain_id = bc.chain_id;
// Read the loaded genesis name so testnet binaries return
// "Sentrix Testnet" instead of pretending to be mainnet. Pre-fix
// the literal "Sentrix" string here was the same on every network
// — wallets that probe `/` for self-describe couldn't tell which
// rail they were on without checking chain_id.
let chain_name = bc.chain_name.clone();
let consensus = if bc.voyager_activated { "DPoS+BFT" } else { "PoA" };
drop(bc);
Json(serde_json::json!({
"name": "Sentrix",
"name": chain_name,
"version": env!("CARGO_PKG_VERSION"),
"chain_id": chain_id,
"consensus": consensus,
Expand Down
Loading