From d2347cc9fe7de0ec48f2687e848be2a4b24f2896 Mon Sep 17 00:00:00 2001 From: valued mammal Date: Sat, 25 Oct 2025 17:42:05 -0400 Subject: [PATCH 1/5] build: Clean up "proxy" feature Before, the `client` module was gated on the "proxy" feature, which caused unnecessary coupling since proxy is only required for the Socks5 client type. This change removes the client module's dependency on the "proxy" feature in favor of more precise feature gating of the Socks5 client type and related functions calling into the `socks` module. Note that `Client` still requires a TLS backend to be enabled by one of "use-openssl", "use-rustls" or "use-rustls-ring". --- src/client.rs | 20 ++++++++++++++++---- src/lib.rs | 20 ++++++++++---------- src/raw_client.rs | 15 +++++++++------ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/client.rs b/src/client.rs index 1ed336b..ff2636e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -17,13 +17,14 @@ use std::convert::TryFrom; /// [`RawClient`](client/struct.RawClient.html) and provides a more user-friendly /// constructor that can choose the right backend based on the url prefix. /// -/// **This is available only with the `default` features, or if `proxy` and one ssl implementation are enabled** +/// **Note the `Socks5` client type requires the "proxy" feature to be enabled.** pub enum ClientType { #[allow(missing_docs)] TCP(RawClient), #[allow(missing_docs)] SSL(RawClient), #[allow(missing_docs)] + #[cfg(feature = "proxy")] Socks5(RawClient), } @@ -44,6 +45,7 @@ macro_rules! impl_inner_call { let res = match &*read_client { ClientType::TCP(inner) => inner.$name( $($args, )* ), ClientType::SSL(inner) => inner.$name( $($args, )* ), + #[cfg(feature = "proxy")] ClientType::Socks5(inner) => inner.$name( $($args, )* ), }; drop(read_client); @@ -110,6 +112,7 @@ impl ClientType { pub fn from_config(url: &str, config: &Config) -> Result { if url.starts_with("ssl://") { let url = url.replacen("ssl://", "", 1); + #[cfg(feature = "proxy")] let client = match config.socks5() { Some(socks5) => RawClient::new_proxy_ssl( url.as_str(), @@ -121,19 +124,28 @@ impl ClientType { RawClient::new_ssl(url.as_str(), config.validate_domain(), config.timeout())? } }; + #[cfg(not(feature = "proxy"))] + let client = + RawClient::new_ssl(url.as_str(), config.validate_domain(), config.timeout())?; Ok(ClientType::SSL(client)) } else { let url = url.replacen("tcp://", "", 1); - Ok(match config.socks5().as_ref() { - None => ClientType::TCP(RawClient::new(url.as_str(), config.timeout())?), + #[cfg(feature = "proxy")] + let client = match config.socks5() { Some(socks5) => ClientType::Socks5(RawClient::new_proxy( url.as_str(), socks5, config.timeout(), )?), - }) + None => ClientType::TCP(RawClient::new(url.as_str(), config.timeout())?), + }; + + #[cfg(not(feature = "proxy"))] + let client = ClientType::TCP(RawClient::new(url.as_str(), config.timeout())?); + + Ok(client) } } } diff --git a/src/lib.rs b/src/lib.rs index 491665a..1440db3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,24 +43,24 @@ extern crate serde_json; ))] extern crate webpki_roots; -#[cfg(any(feature = "default", feature = "proxy"))] +#[cfg(feature = "proxy")] extern crate byteorder; -#[cfg(all(unix, any(feature = "default", feature = "proxy")))] +#[cfg(all(unix, feature = "proxy"))] extern crate libc; -#[cfg(all(windows, any(feature = "default", feature = "proxy")))] +#[cfg(all(windows, feature = "proxy"))] extern crate winapi; -#[cfg(any(feature = "default", feature = "proxy"))] +#[cfg(feature = "proxy")] pub mod socks; mod api; mod batch; #[cfg(any( - all(feature = "proxy", feature = "use-openssl"), - all(feature = "proxy", feature = "use-rustls"), - all(feature = "proxy", feature = "use-rustls-ring") + feature = "use-openssl", + feature = "use-rustls", + feature = "use-rustls-ring", ))] pub mod client; @@ -74,9 +74,9 @@ pub mod utils; pub use api::ElectrumApi; pub use batch::Batch; #[cfg(any( - all(feature = "proxy", feature = "use-openssl"), - all(feature = "proxy", feature = "use-rustls"), - all(feature = "proxy", feature = "use-rustls-ring") + feature = "use-openssl", + feature = "use-rustls", + feature = "use-rustls-ring", ))] pub use client::*; pub use config::{Config, ConfigBuilder, Socks5Config}; diff --git a/src/raw_client.rs b/src/raw_client.rs index 5d67467..6c8b3bf 100644 --- a/src/raw_client.rs +++ b/src/raw_client.rs @@ -470,10 +470,10 @@ impl RawClient { } } -#[cfg(any(feature = "default", feature = "proxy"))] +#[cfg(feature = "proxy")] /// Transport type used to establish a connection to a server through a socks proxy pub type ElectrumProxyStream = Socks5Stream; -#[cfg(any(feature = "default", feature = "proxy"))] +#[cfg(feature = "proxy")] impl RawClient { /// Creates a new socks client and tries to connect to `target_addr` using `proxy_addr` as a /// socks proxy server. The DNS resolution of `target_addr`, if required, is done @@ -499,10 +499,13 @@ impl RawClient { Ok(stream.into()) } - #[cfg(any( - feature = "use-openssl", - feature = "use-rustls", - feature = "use-rustls-ring" + #[cfg(all( + any( + feature = "use-openssl", + feature = "use-rustls", + feature = "use-rustls-ring", + ), + feature = "proxy", ))] /// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy /// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This From b4fac803b5e08120ddc8a80efa9d969a936553be Mon Sep 17 00:00:00 2001 From: valued mammal Date: Fri, 31 Oct 2025 16:51:07 -0400 Subject: [PATCH 2/5] build: remove "default" feature gating The "default" feature argument is redundant and unclear, as it requires the developer to know which aspects of the default features apply to a particular cfg attribute. This change simplifies feature gating logic by only requiring the features necessary to build with a given feature set. --- src/lib.rs | 15 ++------------- src/raw_client.rs | 36 ++++++++---------------------------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1440db3..202365a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,23 +24,12 @@ extern crate core; extern crate log; #[cfg(feature = "use-openssl")] extern crate openssl; -#[cfg(all( - any( - feature = "default", - feature = "use-rustls", - feature = "use-rustls-ring" - ), - not(feature = "use-openssl") -))] +#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] extern crate rustls; extern crate serde; extern crate serde_json; -#[cfg(any( - feature = "default", - feature = "use-rustls", - feature = "use-rustls-ring" -))] +#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] extern crate webpki_roots; #[cfg(feature = "proxy")] diff --git a/src/raw_client.rs b/src/raw_client.rs index 6c8b3bf..23d1d75 100644 --- a/src/raw_client.rs +++ b/src/raw_client.rs @@ -22,21 +22,15 @@ use bitcoin::{Script, Txid}; #[cfg(feature = "use-openssl")] use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode}; -#[cfg(all( - any( - feature = "default", - feature = "use-rustls", - feature = "use-rustls-ring" - ), - not(feature = "use-openssl") -))] +#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] +#[allow(unused_imports)] use rustls::{ pki_types::ServerName, pki_types::{Der, TrustAnchor}, ClientConfig, ClientConnection, RootCertStore, StreamOwned, }; -#[cfg(any(feature = "default", feature = "proxy"))] +#[cfg(feature = "proxy")] use crate::socks::{Socks5Stream, TargetAddr, ToTargetAddr}; use crate::stream::ClonableStream; @@ -93,7 +87,7 @@ impl ToSocketAddrsDomain for (&str, u16) { } } -#[cfg(any(feature = "default", feature = "proxy"))] +#[cfg(feature = "proxy")] impl ToSocketAddrsDomain for TargetAddr { fn domain(&self) -> Option<&str> { match self { @@ -289,14 +283,8 @@ impl RawClient { } } -#[cfg(all( - any( - feature = "default", - feature = "use-rustls", - feature = "use-rustls-ring" - ), - not(feature = "use-openssl") -))] +#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] +#[allow(unused)] mod danger { use crate::raw_client::ServerName; use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified}; @@ -350,21 +338,13 @@ mod danger { } #[cfg(all( - any( - feature = "default", - feature = "use-rustls", - feature = "use-rustls-ring" - ), + any(feature = "use-rustls", feature = "use-rustls-ring"), not(feature = "use-openssl") ))] /// Transport type used to establish a Rustls TLS encrypted/authenticated connection with the server pub type ElectrumSslStream = StreamOwned; #[cfg(all( - any( - feature = "default", - feature = "use-rustls", - feature = "use-rustls-ring" - ), + any(feature = "use-rustls", feature = "use-rustls-ring"), not(feature = "use-openssl") ))] impl RawClient { From 64b20d1bdb1115d24693a62243cdbbb2317b4a59 Mon Sep 17 00:00:00 2001 From: valued mammal Date: Fri, 31 Oct 2025 17:17:23 -0400 Subject: [PATCH 3/5] build: move away from "use-" feature naming Introduce simpler feature names "openssl", "rustls", and "rustls-ring". The original "use-" style names are still available for backwards compatibility. --- Cargo.toml | 11 ++++++++--- src/lib.rs | 18 +++++------------- src/raw_client.rs | 32 ++++++++++++++------------------ src/types.rs | 14 +++++++------- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cb9f189..b604a94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,10 +38,15 @@ libc = { version = "0.2", optional = true } winapi = { version="0.3.9", features=["winsock2"], optional = true } [features] -default = ["proxy", "use-rustls"] +default = ["proxy", "rustls"] minimal = [] debug-calls = [] proxy = ["byteorder", "winapi", "libc"] -use-rustls = ["webpki-roots", "rustls/default"] -use-rustls-ring = ["webpki-roots", "rustls/ring", "rustls/logging", "rustls/std", "rustls/tls12"] +rustls = ["webpki-roots", "dep:rustls", "rustls/default"] +rustls-ring = ["webpki-roots", "dep:rustls", "rustls/ring", "rustls/logging", "rustls/std", "rustls/tls12"] +openssl = ["dep:openssl"] + +# Old feature names +use-rustls = ["rustls"] +use-rustls-ring = ["rustls-ring"] use-openssl = ["openssl"] diff --git a/src/lib.rs b/src/lib.rs index 202365a..2e71e20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,14 +22,14 @@ pub extern crate bitcoin; extern crate core; extern crate log; -#[cfg(feature = "use-openssl")] +#[cfg(feature = "openssl")] extern crate openssl; -#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] +#[cfg(any(feature = "rustls", feature = "rustls-ring"))] extern crate rustls; extern crate serde; extern crate serde_json; -#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] +#[cfg(any(feature = "rustls", feature = "rustls-ring"))] extern crate webpki_roots; #[cfg(feature = "proxy")] @@ -46,11 +46,7 @@ pub mod socks; mod api; mod batch; -#[cfg(any( - feature = "use-openssl", - feature = "use-rustls", - feature = "use-rustls-ring", -))] +#[cfg(any(feature = "openssl", feature = "rustls", feature = "rustls-ring"))] pub mod client; mod config; @@ -62,11 +58,7 @@ pub mod utils; pub use api::ElectrumApi; pub use batch::Batch; -#[cfg(any( - feature = "use-openssl", - feature = "use-rustls", - feature = "use-rustls-ring", -))] +#[cfg(any(feature = "openssl", feature = "rustls", feature = "rustls-ring"))] pub use client::*; pub use config::{Config, ConfigBuilder, Socks5Config}; pub use types::*; diff --git a/src/raw_client.rs b/src/raw_client.rs index 23d1d75..8904979 100644 --- a/src/raw_client.rs +++ b/src/raw_client.rs @@ -19,10 +19,10 @@ use bitcoin::consensus::encode::deserialize; use bitcoin::hex::{DisplayHex, FromHex}; use bitcoin::{Script, Txid}; -#[cfg(feature = "use-openssl")] +#[cfg(feature = "openssl")] use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode}; -#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] +#[cfg(any(feature = "rustls", feature = "rustls-ring"))] #[allow(unused_imports)] use rustls::{ pki_types::ServerName, @@ -222,10 +222,10 @@ fn connect_with_total_timeout( Err(Error::AllAttemptsErrored(errors)) } -#[cfg(feature = "use-openssl")] +#[cfg(feature = "openssl")] /// Transport type used to establish an OpenSSL TLS encrypted/authenticated connection with the server pub type ElectrumSslStream = SslStream; -#[cfg(feature = "use-openssl")] +#[cfg(feature = "openssl")] impl RawClient { /// Creates a new SSL client and tries to connect to `socket_addr`. Optionally, if /// `validate_domain` is `true`, validate the server's certificate. @@ -283,7 +283,7 @@ impl RawClient { } } -#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] +#[cfg(any(feature = "rustls", feature = "rustls-ring"))] #[allow(unused)] mod danger { use crate::raw_client::ServerName; @@ -338,14 +338,14 @@ mod danger { } #[cfg(all( - any(feature = "use-rustls", feature = "use-rustls-ring"), - not(feature = "use-openssl") + any(feature = "rustls", feature = "rustls-ring"), + not(feature = "openssl") ))] /// Transport type used to establish a Rustls TLS encrypted/authenticated connection with the server pub type ElectrumSslStream = StreamOwned; #[cfg(all( - any(feature = "use-rustls", feature = "use-rustls-ring"), - not(feature = "use-openssl") + any(feature = "rustls", feature = "rustls-ring"), + not(feature = "openssl") ))] impl RawClient { /// Creates a new SSL client and tries to connect to `socket_addr`. Optionally, if @@ -388,7 +388,7 @@ impl RawClient { if rustls::crypto::CryptoProvider::get_default().is_none() { // We install a crypto provider depending on the set feature. - #[cfg(all(feature = "use-rustls", not(feature = "use-rustls-ring")))] + #[cfg(all(feature = "rustls", not(feature = "rustls-ring")))] rustls::crypto::CryptoProvider::install_default( rustls::crypto::aws_lc_rs::default_provider(), ) @@ -398,7 +398,7 @@ impl RawClient { )) })?; - #[cfg(feature = "use-rustls-ring")] + #[cfg(feature = "rustls-ring")] rustls::crypto::CryptoProvider::install_default( rustls::crypto::ring::default_provider(), ) @@ -429,9 +429,9 @@ impl RawClient { builder .dangerous() .with_custom_certificate_verifier(std::sync::Arc::new( - #[cfg(all(feature = "use-rustls", not(feature = "use-rustls-ring")))] + #[cfg(all(feature = "rustls", not(feature = "rustls-ring")))] danger::NoCertificateVerification::new(rustls::crypto::aws_lc_rs::default_provider()), - #[cfg(feature = "use-rustls-ring")] + #[cfg(feature = "rustls-ring")] danger::NoCertificateVerification::new(rustls::crypto::ring::default_provider()), )) .with_no_client_auth() @@ -480,11 +480,7 @@ impl RawClient { } #[cfg(all( - any( - feature = "use-openssl", - feature = "use-rustls", - feature = "use-rustls-ring", - ), + any(feature = "openssl", feature = "rustls", feature = "rustls-ring",), feature = "proxy", ))] /// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy diff --git a/src/types.rs b/src/types.rs index ce3ef9f..9277be1 100644 --- a/src/types.rs +++ b/src/types.rs @@ -326,14 +326,14 @@ pub enum Error { CouldntLockReader, /// Broken IPC communication channel: the other thread probably has exited Mpsc, - #[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))] + #[cfg(any(feature = "rustls", feature = "rustls-ring"))] /// Could not create a rustls client connection CouldNotCreateConnection(rustls::Error), - #[cfg(feature = "use-openssl")] + #[cfg(feature = "openssl")] /// Invalid OpenSSL method used InvalidSslMethod(openssl::error::ErrorStack), - #[cfg(feature = "use-openssl")] + #[cfg(feature = "openssl")] /// SSL Handshake failed with the server SslHandshakeError(openssl::ssl::HandshakeError), } @@ -346,13 +346,13 @@ impl Display for Error { Error::Hex(e) => Display::fmt(e, f), Error::Bitcoin(e) => Display::fmt(e, f), Error::SharedIOError(e) => Display::fmt(e, f), - #[cfg(feature = "use-openssl")] + #[cfg(feature = "openssl")] Error::SslHandshakeError(e) => Display::fmt(e, f), - #[cfg(feature = "use-openssl")] + #[cfg(feature = "openssl")] Error::InvalidSslMethod(e) => Display::fmt(e, f), #[cfg(any( - feature = "use-rustls", - feature = "use-rustls-ring", + feature = "rustls", + feature = "rustls-ring", ))] Error::CouldNotCreateConnection(e) => Display::fmt(e, f), From ce7a0eb0a04beca67ee5d65e05074d30058345c2 Mon Sep 17 00:00:00 2001 From: valued mammal Date: Mon, 3 Nov 2025 10:25:25 -0500 Subject: [PATCH 4/5] build: Remove unused "minimal" feature --- .github/workflows/cont_integration.yml | 3 +-- Cargo.toml | 1 - src/lib.rs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cont_integration.yml b/.github/workflows/cont_integration.yml index 01a95f3..85a8725 100644 --- a/.github/workflows/cont_integration.yml +++ b/.github/workflows/cont_integration.yml @@ -36,8 +36,7 @@ jobs: run: cargo test -- --ignored test_local_timeout - run: cargo check --verbose --features=use-openssl - run: cargo check --verbose --no-default-features --features=proxy - - run: cargo check --verbose --no-default-features --features=minimal - - run: cargo check --verbose --no-default-features --features=minimal,debug-calls + - run: cargo check --verbose --no-default-features --features=debug-calls - run: cargo check --verbose --no-default-features --features=proxy,use-openssl - run: cargo check --verbose --no-default-features --features=proxy,use-rustls - run: cargo check --verbose --no-default-features --features=proxy,use-rustls-ring diff --git a/Cargo.toml b/Cargo.toml index b604a94..8a8b07f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,6 @@ winapi = { version="0.3.9", features=["winsock2"], optional = true } [features] default = ["proxy", "rustls"] -minimal = [] debug-calls = [] proxy = ["byteorder", "winapi", "libc"] rustls = ["webpki-roots", "dep:rustls", "rustls/default"] diff --git a/src/lib.rs b/src/lib.rs index 2e71e20..384156a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! plaintext connections over a socks proxy, useful for Onion servers. Using different features, //! the SSL implementation can be removed or replaced with [`openssl`](https://docs.rs/openssl). //! -//! A `minimal` configuration is also provided, which only includes the plaintext TCP client. +//! For a minimal configuration the library can be built with `--no-default-features`, which only includes the plaintext TCP client. //! //! # Example //! From 51cfd778c2711403fa08706345ff55def588edf5 Mon Sep 17 00:00:00 2001 From: valued mammal Date: Tue, 4 Nov 2025 21:45:17 -0500 Subject: [PATCH 5/5] build!: Always implement `calls_made` Removes conditional compilation of `ElectrumApi::calls_made`. As a result the `debug-calls` feature flag is also removed. --- .github/workflows/cont_integration.yml | 1 - Cargo.toml | 1 - src/api.rs | 3 --- src/client.rs | 1 - src/raw_client.rs | 8 -------- 5 files changed, 14 deletions(-) diff --git a/.github/workflows/cont_integration.yml b/.github/workflows/cont_integration.yml index 85a8725..dc56e42 100644 --- a/.github/workflows/cont_integration.yml +++ b/.github/workflows/cont_integration.yml @@ -36,7 +36,6 @@ jobs: run: cargo test -- --ignored test_local_timeout - run: cargo check --verbose --features=use-openssl - run: cargo check --verbose --no-default-features --features=proxy - - run: cargo check --verbose --no-default-features --features=debug-calls - run: cargo check --verbose --no-default-features --features=proxy,use-openssl - run: cargo check --verbose --no-default-features --features=proxy,use-rustls - run: cargo check --verbose --no-default-features --features=proxy,use-rustls-ring diff --git a/Cargo.toml b/Cargo.toml index 8a8b07f..ba66fe2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,6 @@ winapi = { version="0.3.9", features=["winsock2"], optional = true } [features] default = ["proxy", "rustls"] -debug-calls = [] proxy = ["byteorder", "winapi", "libc"] rustls = ["webpki-roots", "dep:rustls", "rustls/default"] rustls-ring = ["webpki-roots", "dep:rustls", "rustls/ring", "rustls/logging", "rustls/std", "rustls/tls12"] diff --git a/src/api.rs b/src/api.rs index 26cd769..bcea1d4 100644 --- a/src/api.rs +++ b/src/api.rs @@ -176,7 +176,6 @@ where (**self).ping() } - #[cfg(feature = "debug-calls")] fn calls_made(&self) -> Result { (**self).calls_made() } @@ -402,7 +401,6 @@ pub trait ElectrumApi { /// of incoming block header or script notifications. fn ping(&self) -> Result<(), Error>; - #[cfg(feature = "debug-calls")] /// Returns the number of network calls made since the creation of the client. fn calls_made(&self) -> Result; } @@ -611,7 +609,6 @@ mod test { unreachable!() } - #[cfg(feature = "debug-calls")] fn calls_made(&self) -> Result { unreachable!() } diff --git a/src/client.rs b/src/client.rs index ff2636e..15c78f1 100644 --- a/src/client.rs +++ b/src/client.rs @@ -380,7 +380,6 @@ impl ElectrumApi for Client { } #[inline] - #[cfg(feature = "debug-calls")] fn calls_made(&self) -> Result { impl_inner_call!(self, calls_made) } diff --git a/src/raw_client.rs b/src/raw_client.rs index 8904979..3a80da8 100644 --- a/src/raw_client.rs +++ b/src/raw_client.rs @@ -136,7 +136,6 @@ where headers: Mutex>, script_notifications: Mutex>>, - #[cfg(feature = "debug-calls")] calls: AtomicUsize, } @@ -157,7 +156,6 @@ where headers: Mutex::new(VecDeque::new()), script_notifications: Mutex::new(HashMap::new()), - #[cfg(feature = "debug-calls")] calls: AtomicUsize::new(0), } } @@ -741,14 +739,9 @@ impl RawClient { } #[inline] - #[cfg(feature = "debug-calls")] fn increment_calls(&self) { self.calls.fetch_add(1, Ordering::SeqCst); } - - #[inline] - #[cfg(not(feature = "debug-calls"))] - fn increment_calls(&self) {} } impl ElectrumApi for RawClient { @@ -1169,7 +1162,6 @@ impl ElectrumApi for RawClient { Ok(()) } - #[cfg(feature = "debug-calls")] fn calls_made(&self) -> Result { Ok(self.calls.load(Ordering::SeqCst)) }