From 5bcf071891c55062164cfe11f2295dcdb593ca3b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 3 Nov 2025 18:40:48 +0100 Subject: [PATCH 01/25] memorized lately received transactions to avoid requesting them again in ChainSync: lately_received_transactions. --- crates/ethcore/sync/src/chain/handler.rs | 9 +++++---- crates/ethcore/sync/src/chain/mod.rs | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/ethcore/sync/src/chain/handler.rs b/crates/ethcore/sync/src/chain/handler.rs index a4a74f0ba..0c4e92ea5 100644 --- a/crates/ethcore/sync/src/chain/handler.rs +++ b/crates/ethcore/sync/src/chain/handler.rs @@ -884,10 +884,11 @@ impl SyncHandler { return Ok(()); } - if io - .chain() - .transaction_if_readable(&hash, &deadline.time_left()) - .is_none() + if !sync.lately_received_transactions.contains(&hash) + && io + .chain() + .transaction_if_readable(&hash, &deadline.time_left()) + .is_none() { sync.peers .get_mut(&peer_id) diff --git a/crates/ethcore/sync/src/chain/mod.rs b/crates/ethcore/sync/src/chain/mod.rs index 3a204b3c1..8494e8a7c 100644 --- a/crates/ethcore/sync/src/chain/mod.rs +++ b/crates/ethcore/sync/src/chain/mod.rs @@ -758,6 +758,8 @@ pub struct ChainSync { statistics: SyncPropagatorStatistics, /// memorizing currently pooled transaction to reduce the number of pooled transaction requests. asking_pooled_transaction_overview: PooledTransactionOverview, + /// memorized lately received transactions to avoid requesting them again. + lately_received_transactions: H256FastSet, } #[derive(Debug, Default)] @@ -849,6 +851,7 @@ impl ChainSync { new_transactions_stats_period: config.new_transactions_stats_period, statistics: SyncPropagatorStatistics::new(), asking_pooled_transaction_overview: PooledTransactionOverview::new(), + lately_received_transactions: H256FastSet::default(), }; sync.update_targets(chain); sync @@ -952,6 +955,9 @@ impl ChainSync { trace!(target: "sync", "Received {:?}", txs.iter().map(|t| t.hash).map(|t| t.0).collect::>()); } + self.lately_received_transactions + .extend(txs.iter().map(|tx| tx.hash())); + // Remove imported txs from all request queues let imported = txs.iter().map(|tx| tx.hash()).collect::(); for (pid, peer_info) in &mut self.peers { @@ -1024,6 +1030,7 @@ impl ChainSync { // Reactivate peers only if some progress has been made // since the last sync round of if starting fresh. self.active_peers = self.peers.keys().cloned().collect(); + self.lately_received_transactions.clear(); debug!(target: "sync", "resetting sync state to {:?}", self.state); } @@ -1267,6 +1274,7 @@ impl ChainSync { debug!(target: "sync", "sync_peer: {} force {} state: {:?}", peer_id, force, self.state ); + if !self.active_peers.contains(&peer_id) { trace!(target: "sync", "Skipping deactivated peer {}", peer_id); return; @@ -1441,6 +1449,9 @@ impl ChainSync { if let Some(peer) = self.peers.get_mut(&peer_id) { // info: this check should do nothing, if everything is tracked correctly, + peer.unfetched_pooled_transactions + .retain(|h| !self.lately_received_transactions.contains(h)); + if peer.asking_pooled_transactions.is_empty() { // todo: we might just request the same transactions from multiple peers here, at the same time. // we should keep track of how many replicas of a transaction we had requested. From 2c145457e64ca2ab38a5ee3b41ead2c151498292 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 3 Nov 2025 19:30:57 +0100 Subject: [PATCH 02/25] error handling for malicious keys --- .../engines/hbbft/contracts/keygen_history.rs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/contracts/keygen_history.rs b/crates/ethcore/src/engines/hbbft/contracts/keygen_history.rs index ee41a17ef..a4d5abd73 100644 --- a/crates/ethcore/src/engines/hbbft/contracts/keygen_history.rs +++ b/crates/ethcore/src/engines/hbbft/contracts/keygen_history.rs @@ -156,12 +156,25 @@ pub fn acks_of_address( if serialized_ack.is_empty() { return Err(CallError::ReturnValueInvalid); } - let deserialized_ack: Ack = bincode::deserialize(&serialized_ack).unwrap(); - let outcome = skg - .handle_ack(vmap.get(&address).unwrap(), deserialized_ack) - .unwrap(); + let deserialized_ack: Ack = match bincode::deserialize(&serialized_ack) { + Ok(ack) => ack, + Err(e) => { + error!(target: "engine", "Failed to deserialize Ack #{} for address {}: {:?}", n, address, e); + return Err(CallError::ReturnValueInvalid); + } + }; + + let outcome = match skg.handle_ack(vmap.get(&address).unwrap(), deserialized_ack) { + Ok(s) => s, + Err(e) => { + error!(target: "engine", "Failed to handle Ack #{} for address {}: {:?}", n, address, e); + return Err(CallError::ReturnValueInvalid); + } + }; + if let AckOutcome::Invalid(fault) = outcome { - panic!("Expected Ack Outcome to be valid. {:?}", fault); + error!(target: "engine", "Invalid Ack Outcome for #{} for address {}: {:?}", n, address, fault); + return Err(CallError::ReturnValueInvalid); } } From de99d16031dcf2cc2dd04a0e2b5edefddc4e97c0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 4 Nov 2025 11:19:45 +0100 Subject: [PATCH 03/25] improved cleanup of unfetched_pooled_transactions, depending witch collection is larger, we choose the appropriate method. --- crates/ethcore/sync/src/chain/mod.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/ethcore/sync/src/chain/mod.rs b/crates/ethcore/sync/src/chain/mod.rs index 8494e8a7c..2053653fe 100644 --- a/crates/ethcore/sync/src/chain/mod.rs +++ b/crates/ethcore/sync/src/chain/mod.rs @@ -1447,10 +1447,20 @@ impl ChainSync { // and if we have nothing else to do, get the peer to give us at least some of announced but unfetched transactions let mut to_send = H256FastSet::default(); if let Some(peer) = self.peers.get_mut(&peer_id) { - // info: this check should do nothing, if everything is tracked correctly, - - peer.unfetched_pooled_transactions - .retain(|h| !self.lately_received_transactions.contains(h)); + // remove lately received transactions from unfetched list + // depending witch collection is larger, we choose the appropriate method. + if self.lately_received_transactions.len() > 0 { + if peer.unfetched_pooled_transactions.len() + > self.lately_received_transactions.len() + { + self.lately_received_transactions.iter().for_each(|h| { + peer.unfetched_pooled_transactions.remove(h); + }); + } else { + peer.unfetched_pooled_transactions + .retain(|h| !self.lately_received_transactions.contains(h)); + } + } if peer.asking_pooled_transactions.is_empty() { // todo: we might just request the same transactions from multiple peers here, at the same time. From 14129bf1261baa38714455646556940d44bc9b11 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Nov 2025 15:40:53 +0100 Subject: [PATCH 04/25] increased gracefull client shutdown from 5 second to 15 seconds. https://github.com/DMDcoin/diamond-node/issues/321 --- bin/oe/run.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/oe/run.rs b/bin/oe/run.rs index 92dc4feb5..c58504c86 100644 --- a/bin/oe/run.rs +++ b/bin/oe/run.rs @@ -723,7 +723,7 @@ impl RunningClient { .name("diamond-node-force-quit".to_string()) .spawn(move || { - let duration_soft = 5; + let duration_soft = 15; // we make a force quit if after 90 seconds, if this shutdown routine std::thread::sleep(Duration::from_secs(duration_soft)); warn!(target: "shutdown", "shutdown not happened within {duration_soft} seconds, starting force exiting the process."); From f93430af7a727a33d89b026d21741d6c866b08ea Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 29 Nov 2025 13:59:08 +0100 Subject: [PATCH 05/25] Node shutdown, if a validator becomes a regular node: https://github.com/DMDcoin/diamond-node/issues/322 --- .../ethcore/src/engines/hbbft/hbbft_state.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_state.rs b/crates/ethcore/src/engines/hbbft/hbbft_state.rs index 725e5b75f..0cd959817 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_state.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_state.rs @@ -222,10 +222,26 @@ impl HbbftState { } if sks.is_none() { - info!(target: "engine", "We are not part of the HoneyBadger validator set - running as regular node."); + info!(target: "engine", "We are not part of the HoneyBadger validator set - Running as regular node."); peers_service .send_message(HbbftConnectToPeersMessage::DisconnectAllValidators) .ok()?; + + if self.is_validator() { + if client + .as_full_client() + .expect("full client") + .is_major_syncing() + { + debug!(target: "engine", "Node was a validator, and became regular node, but we are syncing, not shutting down Node as defined inhttps://github.com/DMDcoin/diamond-node/issues/322."); + } else { + info!(target: "engine", "Node was a validator, and became regular node. shutting down Node as defined in https://github.com/DMDcoin/diamond-node/issues/322."); + // for unit tests no problem, demand shutddown wont to anything if its a unit test. + // e2e tests needs adaption. + // this gracefully shuts down a node, if it was a validator before, but now it is not anymore. + client.demand_shutdown(); + } + } return Some(()); } From a27cba25934e317633cac67d6af845d0e2e8260b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 1 Dec 2025 17:41:23 +0100 Subject: [PATCH 06/25] Error handling for autoshutdown of ex validators https://github.com/DMDcoin/diamond-node/issues/322 + typo fixes --- .../ethcore/src/engines/hbbft/hbbft_state.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_state.rs b/crates/ethcore/src/engines/hbbft/hbbft_state.rs index 0cd959817..fe94ec2bd 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_state.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_state.rs @@ -228,16 +228,19 @@ impl HbbftState { .ok()?; if self.is_validator() { - if client - .as_full_client() - .expect("full client") - .is_major_syncing() - { - debug!(target: "engine", "Node was a validator, and became regular node, but we are syncing, not shutting down Node as defined inhttps://github.com/DMDcoin/diamond-node/issues/322."); + let is_syncing = if let Some(full) = client.as_full_client() { + full.is_major_syncing() + } else { + info!(target: "engine", "Node was a validator: cannot be determinated, because client is not a full client. (https://github.com/DMDcoin/diamond-node/issues/322.)"); + return Some(()); + }; + + if is_syncing { + debug!(target: "engine", "Node was a validator, and became regular node, but we are syncing, not shutting down Node as defined in https://github.com/DMDcoin/diamond-node/issues/322."); } else { info!(target: "engine", "Node was a validator, and became regular node. shutting down Node as defined in https://github.com/DMDcoin/diamond-node/issues/322."); - // for unit tests no problem, demand shutddown wont to anything if its a unit test. - // e2e tests needs adaption. + // for unit tests no problem, demand shutddown won't to anything if its a unit test. + // e2e tests needs adaptation. // this gracefully shuts down a node, if it was a validator before, but now it is not anymore. client.demand_shutdown(); } From b1170084b3e1e26cbce27a43bc17add7525d2c16 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 1 Dec 2025 18:33:08 +0100 Subject: [PATCH 07/25] 4.0.2-rc1: release notes and version update --- CHANGELOG.md | 14 +++++++++++++- Cargo.lock | 4 ++-- Cargo.toml | 2 +- crates/util/version/Cargo.toml | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dc8e0ede..e56002baf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ +## Diamond Node Software 4.0.2 + +OPTIONAL Update + +New behavior for validator nodes as main feature +- [Autoshutdown if a Node becomes a regular Node](https://github.com/DMDcoin/diamond-node/issues/322) + +Further stability improvements +- [FIXED: received transactions are getting pooled, if announced by another peer](https://github.com/DMDcoin/diamond-node/issues/304) +- [FIXED: dropped transactions are getting pooled](https://github.com/DMDcoin/diamond-node/issues/303) +- [FIXED: key generation can panic if faulty validators write malicious parts](https://github.com/DMDcoin/diamond-node/issues/100) + ## Diamond Node Software 4.0.1 -First hotfix +OPTIONAL: First hotfix Mitigates the transaction spam caused by flaws in the transaction management of report disconnectivity transactions. - [Reduce Intervals for connectivity checks](https://github.com/DMDcoin/diamond-node/issues/313) diff --git a/Cargo.lock b/Cargo.lock index f41aa956e..d6d86f352 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -850,7 +850,7 @@ dependencies = [ [[package]] name = "diamond-node" -version = "4.0.1" +version = "4.0.2-rc1" dependencies = [ "ansi_term 0.10.2", "atty", @@ -3579,7 +3579,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "4.0.1" +version = "4.0.2-rc1" dependencies = [ "parity-bytes", "rlp", diff --git a/Cargo.toml b/Cargo.toml index edeb127ca..963b350a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Diamond Node" name = "diamond-node" # NOTE Make sure to update util/version/Cargo.toml as well -version = "4.0.1" +version = "4.0.2-rc1" license = "GPL-3.0" authors = [ "bit.diamonds developers", diff --git a/crates/util/version/Cargo.toml b/crates/util/version/Cargo.toml index be1b4000e..45eee360f 100644 --- a/crates/util/version/Cargo.toml +++ b/crates/util/version/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-version" # NOTE: this value is used for OpenEthereum version string (via env CARGO_PKG_VERSION) -version = "4.0.1" +version = "4.0.2-rc1" authors = [ "bit.diamonds developers", "OpenEthereum developers", From 3e7bc8f2ab8df3572468303aec81c98f0c024b05 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Dec 2025 09:08:46 +0100 Subject: [PATCH 08/25] removed empty blocks during key gen phase: https://github.com/DMDcoin/diamond-node/issues/327 --- .../ethcore/src/engines/hbbft/hbbft_engine.rs | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs index c3eca3362..4f4ad3b88 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs @@ -329,8 +329,6 @@ impl TransitionHandler { // If the minimum block time has passed we are ready to trigger new blocks. if timer_duration == Duration::from_secs(0) { - // Always create blocks if we are in the keygen phase. - self.engine.start_hbbft_epoch_if_next_phase(); // If the maximum block time has been reached we trigger a new block in any case. if self.max_block_time_remaining(client.clone()) == Duration::from_secs(0) { @@ -1104,27 +1102,6 @@ impl HoneyBadgerBFT { self.client.read().as_ref().and_then(Weak::upgrade) } - fn start_hbbft_epoch_if_next_phase(&self) { - // experimental deactivation of empty blocks. - // see: https://github.com/DMDcoin/diamond-node/issues/160 - - match self.client_arc() { - None => return, - Some(client) => { - // Get the next phase start time - let genesis_transition_time = match start_time_of_next_phase_transition(&*client) { - Ok(time) => time, - Err(_) => return, - }; - - // If current time larger than phase start time, start a new block. - if genesis_transition_time.as_u64() < unix_now_secs() { - self.start_hbbft_epoch(client); - } - } - } - } - fn replay_cached_messages(&self) -> Option<()> { let client = self.client_arc()?; From 02cb0a8ab7c0b44ba308211540cebfbf90157617 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Dec 2025 09:10:37 +0100 Subject: [PATCH 09/25] Remove empty blocks during key gen phases behaviour --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e56002baf..9fbf87220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ OPTIONAL Update -New behavior for validator nodes as main feature +New behavior for validator nodes - [Autoshutdown if a Node becomes a regular Node](https://github.com/DMDcoin/diamond-node/issues/322) +- [Remove empty blocks during key gen phases behaviour](https://github.com/DMDcoin/diamond-node/issues/327) Further stability improvements - [FIXED: received transactions are getting pooled, if announced by another peer](https://github.com/DMDcoin/diamond-node/issues/304) From 6e30091cb1930a2a603e1fe7a340434e81f7bb27 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Dec 2025 18:30:59 +0100 Subject: [PATCH 10/25] reduced log level of early-epoch-end: HbbftEarlyEpochEndManager created. --- .../ethcore/src/engines/hbbft/hbbft_early_epoch_end_manager.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_early_epoch_end_manager.rs b/crates/ethcore/src/engines/hbbft/hbbft_early_epoch_end_manager.rs index 398246ab4..3134d2fcb 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_early_epoch_end_manager.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_early_epoch_end_manager.rs @@ -112,7 +112,7 @@ impl HbbftEarlyEpochEndManager { signing_address: signing_address.clone(), }; - info!(target: "engine", "early-epoch-end: HbbftEarlyEpochEndManager created. start_time {now:?}, start_block: {epoch_start_block}"); + trace!(target: "engine", "early-epoch-end: HbbftEarlyEpochEndManager created. start_time {now:?}, start_block: {epoch_start_block}"); return Some(result); } From f76a089a9755461f28281d000ab993b1e27ce6d5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Dec 2025 20:00:26 +0100 Subject: [PATCH 11/25] fixed unused import --- crates/ethcore/src/engines/hbbft/hbbft_engine.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs index 4f4ad3b88..7774d19f7 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs @@ -51,7 +51,6 @@ use super::{ NodeId, contracts::{ keygen_history::{all_parts_acks_available, initialize_synckeygen}, - staking::start_time_of_next_phase_transition, validator_set::{ValidatorType, get_pending_validators, is_pending_validator}, }, contribution::{unix_now_millis, unix_now_secs}, From 593bcfc62583bef9813edfa94d3e53f2b801d56c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Dec 2025 20:03:02 +0100 Subject: [PATCH 12/25] implememtation of gc. https://github.com/DMDcoin/diamond-node/issues/172 todo: dont gc same block twice --- crates/concensus/miner/src/pool/queue.rs | 13 ++++++++ crates/ethcore/service/src/service.rs | 4 ++- crates/ethcore/src/client/client.rs | 35 +++++++++++++++++++++ crates/ethcore/src/miner/miner.rs | 11 +++++++ crates/transaction-pool/Cargo.toml | 1 - crates/transaction-pool/src/pool.rs | 40 +++++++++++++++++++++++- 6 files changed, 101 insertions(+), 3 deletions(-) diff --git a/crates/concensus/miner/src/pool/queue.rs b/crates/concensus/miner/src/pool/queue.rs index 3034123d4..fcf9659cb 100644 --- a/crates/concensus/miner/src/pool/queue.rs +++ b/crates/concensus/miner/src/pool/queue.rs @@ -41,6 +41,8 @@ use crate::pool::{ verifier, PendingOrdering, PendingSettings, PrioritizationStrategy, }; +use super::VerifiedTransaction; + type Listener = ( LocalTransactionsList, (listener::Notifier, listener::Logger), @@ -413,6 +415,17 @@ impl TransactionQueue { .collect() } + /// Performs garbage collection of the pool of this transactionqueue for free service transactions. + /// Removes transaction that are not valid anymore. + /// The process executes listener calls. + pub fn garbage_collect bool>( + &self, + service_transaction_check: F, + ) { + let mut pool = self.pool.write(); + pool.garbage_collect(service_transaction_check); + } + /// Computes unordered set of pending hashes. /// /// Since strict nonce-checking is not required, you may get some false positive future transactions as well. diff --git a/crates/ethcore/service/src/service.rs b/crates/ethcore/service/src/service.rs index 9885ea874..67319b6f6 100644 --- a/crates/ethcore/service/src/service.rs +++ b/crates/ethcore/service/src/service.rs @@ -233,7 +233,9 @@ impl IoHandler for ClientIoHandler { ClientIoMessage::Execute(ref exec) => { (*exec.0)(&self.client); } - _ => {} // ignore other messages + ClientIoMessage::NewChainHead => { + self.client.garbage_collect_in_queue(); + } } } } diff --git a/crates/ethcore/src/client/client.rs b/crates/ethcore/src/client/client.rs index e4cc85d3f..65fc37c7f 100644 --- a/crates/ethcore/src/client/client.rs +++ b/crates/ethcore/src/client/client.rs @@ -842,6 +842,13 @@ impl Importer { warn!("Failed to prune ancient state data: {}", e); } + client.schedule_garbage_collect_in_queue(); + + //self.on_block_commit_finalized(); + + //client.miner().g + //client.check_garbage();.garbage_collect(Duration::from_secs(1)); + route } @@ -1540,6 +1547,34 @@ impl Client { } } + /// Schedule garbage collection of invalid service transactions from the transaction queue based on the given block hash. + pub fn schedule_garbage_collect_in_queue(&self) { + let m = ClientIoMessage::execute(|c| c.garbage_collect_in_queue()); + if let Err(e) = self.io_channel.read().send(m) { + error!(target: "client", "Failed to schedule garbage collection in transaction queue for block {:?}", e); + } + } + + /// Garbage collect invalid servive transactions from the transaction queue based on the given block header. + pub fn garbage_collect_in_queue(&self) { + let machine = self.engine().machine(); + + //todo!("do not gc for blocks that are already gc or old."); + match &self.block_header_decoded(BlockId::Latest) { + Some(block_header) => { + self.importer.miner.collect_garbage(|tx| + match machine.verify_transaction(tx.signed(), block_header, self) { + Ok(_) => true, + Err(e) => { + info!(target: "client", "collected garbage transaction from {:?}: {:?} reason: {:?}", tx.signed().sender(), tx.signed().hash, e); + false + }, + }); + } + None => {} + } + } + fn check_garbage(&self) { self.chain.read().collect_garbage(); self.importer.block_queue.collect_garbage(); diff --git a/crates/ethcore/src/miner/miner.rs b/crates/ethcore/src/miner/miner.rs index ee2135764..bc2a08bb8 100644 --- a/crates/ethcore/src/miner/miner.rs +++ b/crates/ethcore/src/miner/miner.rs @@ -420,6 +420,17 @@ impl Miner { self.service_transaction_checker.clone() } + /// Performs garbage collection of the pool for free service transactions. + /// Removes transaction that are not valid anymore. + /// The process executes listener calls. + pub fn collect_garbage bool>( + &self, + service_transaction_filter: F, + ) { + self.transaction_queue + .garbage_collect(service_transaction_filter); + } + /// Retrieves an existing pending block iff it's not older than given block number. /// /// NOTE: This will not prepare a new pending block if it's not existing. diff --git a/crates/transaction-pool/Cargo.toml b/crates/transaction-pool/Cargo.toml index db2478e95..a04fb955a 100644 --- a/crates/transaction-pool/Cargo.toml +++ b/crates/transaction-pool/Cargo.toml @@ -8,7 +8,6 @@ authors = ["Dragan Rakita . -use log::{trace, warn}; +use log::{info, trace, warn}; use std::{ collections::{hash_map, BTreeSet, HashMap}, slice, @@ -236,6 +236,44 @@ where } } + /// Performs garbage collection of the pool for free service transactions. + /// Removes transaction that are not valid anymore. + /// The process executes listener calls. + pub fn garbage_collect bool>(&mut self, service_transaction_check: F) { + if self.best_transactions.is_empty() { + return; + } + + let mut txs_to_remove = Vec::::new(); + + for sender in self.transactions.iter() { + for tx in sender.1.iter_transactions() { + if tx.transaction.has_zero_gas_price() { + if service_transaction_check(&tx.transaction) { + txs_to_remove.push(tx.hash().clone()); + } + } else { + // if the next transaction has not zero gas price, + // we are not continuing. + break; + }; + } + } + + if txs_to_remove.is_empty() { + return; + } + + info!( + "Garbage collection: removing invalid {} service transactions from pool.", + txs_to_remove.len() + ); + + for tx in txs_to_remove.iter() { + self.remove(tx, true); + } + } + /// Updates state of the pool statistics if the transaction was added to a set. fn finalize_insert(&mut self, new: &Transaction, old: Option<&Transaction>) { self.mem_usage += new.mem_usage(); From ec3ed175da0373a6fd350ac10910c8a8092ba09d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 13:28:37 +0100 Subject: [PATCH 13/25] removed unused fragment for https://github.com/DMDcoin/diamond-node/issues/327 --- crates/ethcore/src/engines/hbbft/contracts/staking.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/contracts/staking.rs b/crates/ethcore/src/engines/hbbft/contracts/staking.rs index 84094ccc5..58b0ee653 100644 --- a/crates/ethcore/src/engines/hbbft/contracts/staking.rs +++ b/crates/ethcore/src/engines/hbbft/contracts/staking.rs @@ -35,11 +35,6 @@ pub fn get_posdao_epoch_start( call_const_staking!(c, staking_epoch_start_block) } -pub fn start_time_of_next_phase_transition(client: &dyn EngineClient) -> Result { - let c = BoundContract::bind(client, BlockId::Latest, *STAKING_CONTRACT_ADDRESS); - call_const_staking!(c, start_time_of_next_phase_transition) -} - pub fn candidate_min_stake(client: &dyn EngineClient) -> Result { let c = BoundContract::bind(client, BlockId::Latest, *STAKING_CONTRACT_ADDRESS); call_const_staking!(c, candidate_min_stake) From 9af27de66b4b8d9ca232dcbec7c326778e57a425 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 14:08:28 +0100 Subject: [PATCH 14/25] fixed test for https://github.com/DMDcoin/diamond-node/issues/327 (remove empty blocks during key gen phases behaviour) --- crates/ethcore/src/engines/hbbft/hbbft_engine.rs | 1 - crates/ethcore/src/engines/hbbft/test/mod.rs | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs index 7774d19f7..b0fc2e614 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs @@ -328,7 +328,6 @@ impl TransitionHandler { // If the minimum block time has passed we are ready to trigger new blocks. if timer_duration == Duration::from_secs(0) { - // If the maximum block time has been reached we trigger a new block in any case. if self.max_block_time_remaining(client.clone()) == Duration::from_secs(0) { self.engine.start_hbbft_epoch(client); diff --git a/crates/ethcore/src/engines/hbbft/test/mod.rs b/crates/ethcore/src/engines/hbbft/test/mod.rs index 4c935ff7a..e95a4c576 100644 --- a/crates/ethcore/src/engines/hbbft/test/mod.rs +++ b/crates/ethcore/src/engines/hbbft/test/mod.rs @@ -1,12 +1,11 @@ use super::{ contracts::{ staking::{ - get_posdao_epoch, start_time_of_next_phase_transition, + get_posdao_epoch, tests::{create_staker, is_pool_active}, }, validator_set::{is_pending_validator, mining_by_staking_address}, }, - contribution::unix_now_secs, test::hbbft_test_client::{HbbftTestClient, create_hbbft_client, create_hbbft_clients}, }; use crate::{client::traits::BlockInfo, types::ids::BlockId}; @@ -129,12 +128,6 @@ fn test_epoch_transition() { // To avoid performing external transactions with the MoC we create and fund a random address. let transactor: KeyPair = Random.generate(); - let genesis_transition_time = start_time_of_next_phase_transition(moc.client.as_ref()) - .expect("start_time_of_next_phase_transition call must succeed"); - - // Genesis block is at time 0, current unix time must be much larger. - assert!(genesis_transition_time.as_u64() < unix_now_secs()); - // We should not be in the pending validator set at the genesis block. assert!( !is_pending_validator(moc.client.as_ref(), &moc.address()) From 8e84bdb65fa7c3e14284ef45c107d33b16e8a46c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 14:34:55 +0100 Subject: [PATCH 15/25] rpc gas price: always use latest gas price: https://github.com/DMDcoin/diamond-node/issues/159 --- crates/ethcore/src/engines/hbbft/hbbft_state.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_state.rs b/crates/ethcore/src/engines/hbbft/hbbft_state.rs index fe94ec2bd..3bdb78c20 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_state.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_state.rs @@ -209,10 +209,7 @@ impl HbbftState { // apply DAO updates here. // update the current minimum gas price. - match get_minimum_gas_from_permission_contract( - client.as_ref(), - BlockId::Number(self.current_posdao_epoch_start_block), - ) { + match get_minimum_gas_from_permission_contract(client.as_ref(), BlockId::Latest) { Ok(min_gas) => { *current_minimum_gas_price.lock() = Some(min_gas); } From 55b5f659c1a73d429fc1e859a004220bcdb74399 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 15:15:56 +0100 Subject: [PATCH 16/25] avoid GC of service transactions twice within the same block. --- crates/ethcore/src/client/client.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/ethcore/src/client/client.rs b/crates/ethcore/src/client/client.rs index 65fc37c7f..9410070b3 100644 --- a/crates/ethcore/src/client/client.rs +++ b/crates/ethcore/src/client/client.rs @@ -306,6 +306,10 @@ pub struct Client { shutdown: Arc, + /// block number and block has of latest gc. + /// this information is used to avoid double garbage collection. + garbage_collect_latest_block: Mutex<(u64, H256)>, + statistics: ClientStatistics, } @@ -1114,6 +1118,7 @@ impl Client { importer, config, shutdown, + garbage_collect_latest_block: Mutex::new((0, H256::zero())), statistics, }); @@ -1555,13 +1560,31 @@ impl Client { } } - /// Garbage collect invalid servive transactions from the transaction queue based on the given block header. + /// Garbage collect invalid servive transactions from the transaction queue based on the given block header. pub fn garbage_collect_in_queue(&self) { let machine = self.engine().machine(); - //todo!("do not gc for blocks that are already gc or old."); match &self.block_header_decoded(BlockId::Latest) { Some(block_header) => { + { + // scope for mutex. + let mut last_gc = self.garbage_collect_latest_block.lock(); + + if block_header.number() == last_gc.0 && block_header.hash() == last_gc.1 { + // already gced for this block, or gc is ongoing. + // we can return here. + return; + } + + // we treat ongoing gc as DONE, to avoid blocking of the message channel + last_gc.0 = block_header.number(); + last_gc.1 = block_header.hash(); + } + + // here hides an accepted race condition. + // latest block could change during loing ongoing GCs. + // this could be avoided developing a more complex GC logic. + // but the GC blocks the tx queue, so it has to be placing fast. self.importer.miner.collect_garbage(|tx| match machine.verify_transaction(tx.signed(), block_header, self) { Ok(_) => true, From 9aa3a2525512c88a73000421d5f80d52e8640081 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 15:30:49 +0100 Subject: [PATCH 17/25] updated release notes for 4.0.2 --- CHANGELOG.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fbf87220..623cba754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,21 @@ ## Diamond Node Software 4.0.2 -OPTIONAL Update -New behavior for validator nodes +### New behavior for validator nodes - [Autoshutdown if a Node becomes a regular Node](https://github.com/DMDcoin/diamond-node/issues/322) - [Remove empty blocks during key gen phases behaviour](https://github.com/DMDcoin/diamond-node/issues/327) +- [Service Transaction cleanup (garbage collect)](https://github.com/DMDcoin/diamond-node/issues/172) -Further stability improvements +### RPC +- [Gas price from contracts](https://github.com/DMDcoin/diamond-node/issues/159) + +### Further stability improvements - [FIXED: received transactions are getting pooled, if announced by another peer](https://github.com/DMDcoin/diamond-node/issues/304) - [FIXED: dropped transactions are getting pooled](https://github.com/DMDcoin/diamond-node/issues/303) - [FIXED: key generation can panic if faulty validators write malicious parts](https://github.com/DMDcoin/diamond-node/issues/100) +- [FIXED: already included transactions are refretched from peers](https://github.com/DMDcoin/diamond-node/issues/196) +- [Gracefull Node Shutdown: increase to 15 seconds](https://github.com/DMDcoin/diamond-node/issues/321) + ## Diamond Node Software 4.0.1 From d95481f8373f65f98a99ceda6c7a15ea7b90391e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 19:18:57 +0100 Subject: [PATCH 18/25] fixes for garbage collect of inactive service transactions + log level adjustments --- crates/ethcore/src/client/client.rs | 2 +- crates/transaction-pool/src/pool.rs | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/crates/ethcore/src/client/client.rs b/crates/ethcore/src/client/client.rs index 9410070b3..ba9f0f767 100644 --- a/crates/ethcore/src/client/client.rs +++ b/crates/ethcore/src/client/client.rs @@ -1560,7 +1560,7 @@ impl Client { } } - /// Garbage collect invalid servive transactions from the transaction queue based on the given block header. + /// Garbage collect invalid service transactions from the transaction queue based on the given block header. pub fn garbage_collect_in_queue(&self) { let machine = self.engine().machine(); diff --git a/crates/transaction-pool/src/pool.rs b/crates/transaction-pool/src/pool.rs index abea527ba..caa4d9c43 100644 --- a/crates/transaction-pool/src/pool.rs +++ b/crates/transaction-pool/src/pool.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use log::{info, trace, warn}; +use log::{debug, trace, warn}; use std::{ collections::{hash_map, BTreeSet, HashMap}, slice, @@ -236,11 +236,12 @@ where } } - /// Performs garbage collection of the pool for free service transactions. - /// Removes transaction that are not valid anymore. - /// The process executes listener calls. - pub fn garbage_collect bool>(&mut self, service_transaction_check: F) { - if self.best_transactions.is_empty() { + /// Performs garbage collection of the pool for free service transactions (zero gas transactions). + /// Only checks lowest nonce. + /// inject "should_keep_function" to decide. + /// The process executes listener calls for invalid transactions. + pub fn garbage_collect bool>(&mut self, should_keep_function: F) { + if self.transactions.is_empty() { return; } @@ -249,7 +250,7 @@ where for sender in self.transactions.iter() { for tx in sender.1.iter_transactions() { if tx.transaction.has_zero_gas_price() { - if service_transaction_check(&tx.transaction) { + if !should_keep_function(&tx.transaction) { txs_to_remove.push(tx.hash().clone()); } } else { @@ -264,7 +265,7 @@ where return; } - info!( + debug!( "Garbage collection: removing invalid {} service transactions from pool.", txs_to_remove.len() ); From 9b10f1c3141858e03f8279aea7b469c070ea0148 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 19:19:16 +0100 Subject: [PATCH 19/25] log level for collect garbage --- crates/ethcore/src/client/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ethcore/src/client/client.rs b/crates/ethcore/src/client/client.rs index ba9f0f767..43e52b75e 100644 --- a/crates/ethcore/src/client/client.rs +++ b/crates/ethcore/src/client/client.rs @@ -1589,7 +1589,7 @@ impl Client { match machine.verify_transaction(tx.signed(), block_header, self) { Ok(_) => true, Err(e) => { - info!(target: "client", "collected garbage transaction from {:?}: {:?} reason: {:?}", tx.signed().sender(), tx.signed().hash, e); + trace!(target: "client", "collected garbage transaction from {:?}: {:?} reason: {:?}", tx.signed().sender(), tx.signed().hash, e); false }, }); From 80fbdf83ca0de41e3d062ba4d0eb72a89f21d071 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 19:41:46 +0100 Subject: [PATCH 20/25] FIXED not staked nodes write log entries about service transactions. https://github.com/DMDcoin/diamond-node/issues/323 --- crates/ethcore/src/engines/hbbft/hbbft_engine.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs index b0fc2e614..60bb942fc 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs @@ -1211,12 +1211,10 @@ impl HoneyBadgerBFT { return Ok(()); } - self.hbbft_peers_service - .channel() - .send(HbbftConnectToPeersMessage::AnnounceAvailability)?; - - self.hbbft_peers_service - .send_message(HbbftConnectToPeersMessage::AnnounceOwnInternetAddress)?; + if self.is_staked() { + self.hbbft_peers_service.send_message(HbbftConnectToPeersMessage::AnnounceAvailability)?; + self.hbbft_peers_service.send_message(HbbftConnectToPeersMessage::AnnounceOwnInternetAddress)?; + } if self.should_connect_to_validator_set() { // we just keep those variables here, because we need them in the early_epoch_end_manager. From a3cc2b9670320b3a6c3354da3b958c07c278404c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 19:43:41 +0100 Subject: [PATCH 21/25] version update and changelog --- CHANGELOG.md | 3 ++- Cargo.lock | 4 ++-- Cargo.toml | 2 +- crates/util/version/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 623cba754..4676d01ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,12 @@ ### RPC - [Gas price from contracts](https://github.com/DMDcoin/diamond-node/issues/159) -### Further stability improvements +### Further improvements - [FIXED: received transactions are getting pooled, if announced by another peer](https://github.com/DMDcoin/diamond-node/issues/304) - [FIXED: dropped transactions are getting pooled](https://github.com/DMDcoin/diamond-node/issues/303) - [FIXED: key generation can panic if faulty validators write malicious parts](https://github.com/DMDcoin/diamond-node/issues/100) - [FIXED: already included transactions are refretched from peers](https://github.com/DMDcoin/diamond-node/issues/196) +- [FIXED:not staked nodes write log entries about service transactions](https://github.com/DMDcoin/diamond-node/issues/323) - [Gracefull Node Shutdown: increase to 15 seconds](https://github.com/DMDcoin/diamond-node/issues/321) diff --git a/Cargo.lock b/Cargo.lock index d6d86f352..3fa0b15ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -850,7 +850,7 @@ dependencies = [ [[package]] name = "diamond-node" -version = "4.0.2-rc1" +version = "4.0.2-rc3" dependencies = [ "ansi_term 0.10.2", "atty", @@ -3579,7 +3579,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "4.0.2-rc1" +version = "4.0.2-rc3" dependencies = [ "parity-bytes", "rlp", diff --git a/Cargo.toml b/Cargo.toml index 963b350a2..c283c8c90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Diamond Node" name = "diamond-node" # NOTE Make sure to update util/version/Cargo.toml as well -version = "4.0.2-rc1" +version = "4.0.2-rc3" license = "GPL-3.0" authors = [ "bit.diamonds developers", diff --git a/crates/util/version/Cargo.toml b/crates/util/version/Cargo.toml index 45eee360f..12b6250c6 100644 --- a/crates/util/version/Cargo.toml +++ b/crates/util/version/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-version" # NOTE: this value is used for OpenEthereum version string (via env CARGO_PKG_VERSION) -version = "4.0.2-rc1" +version = "4.0.2-rc3" authors = [ "bit.diamonds developers", "OpenEthereum developers", From 7cde9bdf0687d20de6332798d2b560f7eb5c1210 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 10 Dec 2025 19:48:34 +0100 Subject: [PATCH 22/25] cargo fmt --all -- --config imports_granularity=Crate --- crates/ethcore/src/engines/hbbft/hbbft_engine.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs index 60bb942fc..2d93b169b 100644 --- a/crates/ethcore/src/engines/hbbft/hbbft_engine.rs +++ b/crates/ethcore/src/engines/hbbft/hbbft_engine.rs @@ -1212,8 +1212,10 @@ impl HoneyBadgerBFT { } if self.is_staked() { - self.hbbft_peers_service.send_message(HbbftConnectToPeersMessage::AnnounceAvailability)?; - self.hbbft_peers_service.send_message(HbbftConnectToPeersMessage::AnnounceOwnInternetAddress)?; + self.hbbft_peers_service + .send_message(HbbftConnectToPeersMessage::AnnounceAvailability)?; + self.hbbft_peers_service + .send_message(HbbftConnectToPeersMessage::AnnounceOwnInternetAddress)?; } if self.should_connect_to_validator_set() { From 236d549043941c5b4eda983ee2f9e80d4a4deadc Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 12 Dec 2025 17:54:34 +0100 Subject: [PATCH 23/25] cleanup of comments --- crates/ethcore/src/client/client.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/ethcore/src/client/client.rs b/crates/ethcore/src/client/client.rs index 43e52b75e..8643abb5a 100644 --- a/crates/ethcore/src/client/client.rs +++ b/crates/ethcore/src/client/client.rs @@ -848,11 +848,6 @@ impl Importer { client.schedule_garbage_collect_in_queue(); - //self.on_block_commit_finalized(); - - //client.miner().g - //client.check_garbage();.garbage_collect(Duration::from_secs(1)); - route } From 58dfe2b6900d90d6068dad8997bbb0a72bfddccd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 12 Dec 2025 17:58:49 +0100 Subject: [PATCH 24/25] fixed typos in comments --- crates/concensus/miner/src/pool/queue.rs | 4 ++-- crates/ethcore/src/client/client.rs | 6 +++--- crates/ethcore/src/miner/miner.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/concensus/miner/src/pool/queue.rs b/crates/concensus/miner/src/pool/queue.rs index fcf9659cb..dc9fd9e6f 100644 --- a/crates/concensus/miner/src/pool/queue.rs +++ b/crates/concensus/miner/src/pool/queue.rs @@ -415,8 +415,8 @@ impl TransactionQueue { .collect() } - /// Performs garbage collection of the pool of this transactionqueue for free service transactions. - /// Removes transaction that are not valid anymore. + /// Performs garbage collection on the pool of this `TransactionQueue` for free service transactions. + /// Removes transactions that are not valid anymore. /// The process executes listener calls. pub fn garbage_collect bool>( &self, diff --git a/crates/ethcore/src/client/client.rs b/crates/ethcore/src/client/client.rs index 8643abb5a..48291d278 100644 --- a/crates/ethcore/src/client/client.rs +++ b/crates/ethcore/src/client/client.rs @@ -306,7 +306,7 @@ pub struct Client { shutdown: Arc, - /// block number and block has of latest gc. + /// block number and block hash of latest gc. /// this information is used to avoid double garbage collection. garbage_collect_latest_block: Mutex<(u64, H256)>, @@ -1577,9 +1577,9 @@ impl Client { } // here hides an accepted race condition. - // latest block could change during loing ongoing GCs. + // latest block could change during long ongoing GCs. // this could be avoided developing a more complex GC logic. - // but the GC blocks the tx queue, so it has to be placing fast. + // but the GC blocks the tx queue, so it has to be blazing fast. self.importer.miner.collect_garbage(|tx| match machine.verify_transaction(tx.signed(), block_header, self) { Ok(_) => true, diff --git a/crates/ethcore/src/miner/miner.rs b/crates/ethcore/src/miner/miner.rs index bc2a08bb8..5df562f2c 100644 --- a/crates/ethcore/src/miner/miner.rs +++ b/crates/ethcore/src/miner/miner.rs @@ -421,7 +421,7 @@ impl Miner { } /// Performs garbage collection of the pool for free service transactions. - /// Removes transaction that are not valid anymore. + /// Removes transactions that are not valid anymore. /// The process executes listener calls. pub fn collect_garbage bool>( &self, From b1eecb93da8351fe128f459e5b5cbfd0aa80d583 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 12 Dec 2025 17:59:47 +0100 Subject: [PATCH 25/25] version Update: 4.0.2-rc3 -> 4.0.2 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- crates/util/version/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fa0b15ac..8cc7e6cb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -850,7 +850,7 @@ dependencies = [ [[package]] name = "diamond-node" -version = "4.0.2-rc3" +version = "4.0.2" dependencies = [ "ansi_term 0.10.2", "atty", @@ -3579,7 +3579,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "4.0.2-rc3" +version = "4.0.2" dependencies = [ "parity-bytes", "rlp", diff --git a/Cargo.toml b/Cargo.toml index c283c8c90..1e225d0df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Diamond Node" name = "diamond-node" # NOTE Make sure to update util/version/Cargo.toml as well -version = "4.0.2-rc3" +version = "4.0.2" license = "GPL-3.0" authors = [ "bit.diamonds developers", diff --git a/crates/util/version/Cargo.toml b/crates/util/version/Cargo.toml index 12b6250c6..8737eca0a 100644 --- a/crates/util/version/Cargo.toml +++ b/crates/util/version/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-version" # NOTE: this value is used for OpenEthereum version string (via env CARGO_PKG_VERSION) -version = "4.0.2-rc3" +version = "4.0.2" authors = [ "bit.diamonds developers", "OpenEthereum developers",