Hansie Odendaal b3d54125ea
chore: merge dev into master (#29)
* Add node config overrides (#14)

* chore: merge master into dev and update configs after merge (#17)

* Sdp config structs from logos blockchain (#15)

* Update configs after main repo merge

---------

Co-authored-by: gusto <bacv@users.noreply.github.com>

* Local deployer allows to stop and restart nodes (#16)

* Unify local node control and restart support

* Add local stop-node support

* Use node names for restart/stop control

* merge

---------

Co-authored-by: hansieodendaal <hansie.odendaal@gmail.com>

* Add orphan manual cluster test utilities

* Update node rev and align consensus/wallet config

* Update node rev and align wallet/KMS configs

* Update main repo ref (#23)

* Fix genesis utxos and scale leader stake

* Document leader stake constants

* feat: add custom persistent dir option for working files (#26)

* chore: config and naming updates (#27)

* Update config and crate naming

- Updated configs to the lates main repo configs.
- Updated all main repo crate namings to be same as the main repo.
- Added `create_dir_all` to `pub(crate) fn create_tempdir(custom_work_dir: Option<PathBuf>) -> std::io::Result<TempDir> {`.
- Wired in optional `persist_dir` when using the local deployer.
- Update `time` vulnerability

**Note:** Unsure about the `service_params` mapping in `pub(crate) fn cryptarchia_deployment(config: &GeneralConfig) -> CryptarchiaDeploymentSettings {`

* fix ntp server config

---------

Co-authored-by: Andrus Salumets <andrus@status.im>
Co-authored-by: gusto <bacv@users.noreply.github.com>
Co-authored-by: andrussal <salumets.andrus@gmail.com>
2026-02-09 14:12:26 +02:00

76 lines
2.3 KiB
Rust

use std::{sync::Arc, time::Duration};
use lb_core::{
block::Block,
mantle::{
AuthenticatedMantleTx as _, SignedMantleTx, Transaction as MantleTx,
ops::{Op, channel::MsgId},
},
};
use rand::{seq::SliceRandom as _, thread_rng};
use testing_framework_core::scenario::{DynError, RunContext};
use tracing::debug;
const SUBMIT_RETRIES: usize = 5;
const SUBMIT_RETRY_DELAY: Duration = Duration::from_millis(500);
/// Scans a block and invokes the matcher for every operation until it returns
/// `Some(...)`. Returns `None` when no matching operation is found.
pub fn find_channel_op<F>(block: &Block<SignedMantleTx>, matcher: &mut F) -> Option<MsgId>
where
F: FnMut(&Op) -> Option<MsgId>,
{
debug!(
txs = block.transactions().len(),
"scanning block for channel op"
);
for tx in block.transactions() {
for op in &tx.mantle_tx().ops {
if let Some(msg_id) = matcher(op) {
return Some(msg_id);
}
}
}
None
}
/// Submits a transaction to the cluster, fanning out across clients until one
/// succeeds.
pub async fn submit_transaction_via_cluster(
ctx: &RunContext,
tx: Arc<SignedMantleTx>,
) -> Result<(), DynError> {
let tx_hash = tx.hash();
debug!(?tx_hash, "submitting transaction via cluster (nodes first)");
let node_clients = ctx.node_clients();
let mut clients = node_clients.node_clients();
clients.shuffle(&mut thread_rng());
let mut last_err = None;
for attempt in 0..SUBMIT_RETRIES {
clients.shuffle(&mut thread_rng());
for client in &clients {
let url = client.base_url().clone();
debug!(?tx_hash, %url, attempt, "submitting transaction to client");
match client
.submit_transaction(&tx)
.await
.map_err(|err| -> DynError { err.into() })
{
Ok(()) => return Ok(()),
Err(err) => {
debug!(?tx_hash, %url, attempt, "transaction submission failed");
last_err = Some(err);
}
}
}
tokio::time::sleep(SUBMIT_RETRY_DELAY).await;
}
Err(last_err.unwrap_or_else(|| "cluster client exhausted all nodes".into()))
}