Skip to content
Open
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.14.8 (TBD)

- Fixed a startup race in the network transaction builder that could panic the chain MMR when a block committed between subscribing to the mempool and fetching the chain tip from the store ([#1953](https://github.com/0xMiden/node/pull/1953)).

## v0.14.7 (2026-04-15)

- [BREAKING] Aligned proto `TransactionHeader` with domain type and exposed erased notes in `SyncTransactions` ([#1941](https://github.com/0xMiden/node/pull/1941)).
Expand Down
36 changes: 18 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ license = "MIT"
readme = "README.md"
repository = "https://github.com/0xMiden/node"
rust-version = "1.93"
version = "0.14.7"
version = "0.14.8"

# Optimize the cryptography for faster tests involving account creation.
[profile.test.package.miden-crypto]
Expand Down
13 changes: 13 additions & 0 deletions crates/ntx-builder/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,19 @@ impl NetworkTransactionBuilder {
async fn update_chain_tip(&mut self, tip: BlockHeader) {
let mut chain_state = self.chain_state.write().await;

// Skip blocks already reflected in the chain state. A `BlockCommitted` event may arrive
// for a block whose state was already loaded from the store during startup: the mempool
// subscription is established first and then the chain tip is fetched, so any block
// committed in that window produces an event for state we have already ingested.
if tip.block_num() <= chain_state.chain_tip_header.block_num() {
tracing::debug!(
event_block = %tip.block_num(),
current_tip = %chain_state.chain_tip_header.block_num(),
"skipping BlockCommitted event for block already in chain state",
);
return;
}

// Update MMR which lags by one block.
let mmr_tip = chain_state.chain_tip_header.clone();
Arc::make_mut(&mut chain_state.chain_mmr).add_block(&mmr_tip, true);
Expand Down
Loading