Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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