use WyRand instead of Xoshiro
This commit is contained in:
parent
a8f0c1f6f4
commit
c771479d94
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -4485,15 +4485,6 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_xoshiro"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rate-counter"
|
name = "rate-counter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -6090,14 +6081,6 @@ dependencies = [
|
|||||||
"syn 2.0.18",
|
"syn 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thread-fast-rng"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"rand",
|
|
||||||
"rand_xoshiro",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thread-id"
|
name = "thread-id"
|
||||||
version = "4.1.0"
|
version = "4.1.0"
|
||||||
@ -7062,6 +7045,7 @@ dependencies = [
|
|||||||
"migration",
|
"migration",
|
||||||
"mimalloc",
|
"mimalloc",
|
||||||
"moka",
|
"moka",
|
||||||
|
"nanorand",
|
||||||
"num",
|
"num",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -7083,7 +7067,6 @@ dependencies = [
|
|||||||
"serde_prometheus",
|
"serde_prometheus",
|
||||||
"siwe",
|
"siwe",
|
||||||
"strum",
|
"strum",
|
||||||
"thread-fast-rng",
|
|
||||||
"time 0.3.22",
|
"time 0.3.22",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-console",
|
"tokio-console",
|
||||||
|
@ -7,7 +7,6 @@ members = [
|
|||||||
"payment-contracts",
|
"payment-contracts",
|
||||||
"rate-counter",
|
"rate-counter",
|
||||||
"redis-rate-limiter",
|
"redis-rate-limiter",
|
||||||
"thread-fast-rng",
|
|
||||||
"web3_proxy",
|
"web3_proxy",
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "thread-fast-rng"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rand = "0.8.5"
|
|
||||||
rand_xoshiro = "0.6.0"
|
|
@ -1,87 +0,0 @@
|
|||||||
//! works just like rand::thread_rng but with a rng that is **not** cryptographically secure
|
|
||||||
//!
|
|
||||||
//! TODO: currently uses Xoshiro256Plus. do some benchmarks
|
|
||||||
pub use rand;
|
|
||||||
|
|
||||||
use rand::{Error, Rng, RngCore, SeedableRng};
|
|
||||||
use rand_xoshiro::Xoshiro256Plus;
|
|
||||||
use std::{cell::UnsafeCell, rc::Rc};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ThreadFastRng {
|
|
||||||
// Rc is explicitly !Send and !Sync
|
|
||||||
rng: Rc<UnsafeCell<Xoshiro256Plus>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local! {
|
|
||||||
pub static THREAD_FAST_RNG: Rc<UnsafeCell<Xoshiro256Plus>> = {
|
|
||||||
// use a cryptographically secure rng for the seed
|
|
||||||
let mut crypto_rng = rand::thread_rng();
|
|
||||||
let seed = crypto_rng.gen();
|
|
||||||
// use a fast rng for things that aren't cryptography
|
|
||||||
let rng = Xoshiro256Plus::seed_from_u64(seed);
|
|
||||||
Rc::new(UnsafeCell::new(rng))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn thread_fast_rng() -> ThreadFastRng {
|
|
||||||
let rng = THREAD_FAST_RNG.with(|t| t.clone());
|
|
||||||
ThreadFastRng { rng }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ThreadFastRng {
|
|
||||||
fn default() -> Self {
|
|
||||||
thread_fast_rng()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RngCore for ThreadFastRng {
|
|
||||||
#[inline(always)]
|
|
||||||
fn next_u32(&mut self) -> u32 {
|
|
||||||
// SAFETY: We must make sure to stop using `rng` before anyone else
|
|
||||||
// creates another mutable reference
|
|
||||||
let rng = unsafe { &mut *self.rng.get() };
|
|
||||||
rng.next_u32()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn next_u64(&mut self) -> u64 {
|
|
||||||
// SAFETY: We must make sure to stop using `rng` before anyone else
|
|
||||||
// creates another mutable reference
|
|
||||||
let rng = unsafe { &mut *self.rng.get() };
|
|
||||||
rng.next_u64()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
|
||||||
// SAFETY: We must make sure to stop using `rng` before anyone else
|
|
||||||
// creates another mutable reference
|
|
||||||
let rng = unsafe { &mut *self.rng.get() };
|
|
||||||
rng.fill_bytes(dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
|
|
||||||
// SAFETY: We must make sure to stop using `rng` before anyone else
|
|
||||||
// creates another mutable reference
|
|
||||||
let rng = unsafe { &mut *self.rng.get() };
|
|
||||||
rng.try_fill_bytes(dest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_thread_fast_rng() {
|
|
||||||
let mut r = thread_fast_rng();
|
|
||||||
r.gen::<i32>();
|
|
||||||
assert_eq!(r.gen_range(0..1), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_thread_fast_rng_struct() {
|
|
||||||
let mut r = ThreadFastRng::default();
|
|
||||||
r.gen::<i32>();
|
|
||||||
assert_eq!(r.gen_range(0..1), 0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,6 @@ latency = { path = "../latency" }
|
|||||||
migration = { path = "../migration" }
|
migration = { path = "../migration" }
|
||||||
payment-contracts = { path = "../payment-contracts" }
|
payment-contracts = { path = "../payment-contracts" }
|
||||||
redis-rate-limiter = { path = "../redis-rate-limiter" }
|
redis-rate-limiter = { path = "../redis-rate-limiter" }
|
||||||
thread-fast-rng = { path = "../thread-fast-rng" }
|
|
||||||
|
|
||||||
influxdb2 = { git = "https://github.com/llamanodes/influxdb2", features = ["rustls"] }
|
influxdb2 = { git = "https://github.com/llamanodes/influxdb2", features = ["rustls"] }
|
||||||
influxdb2-structmap = { git = "https://github.com/llamanodes/influxdb2/"}
|
influxdb2-structmap = { git = "https://github.com/llamanodes/influxdb2/"}
|
||||||
@ -43,6 +42,7 @@ async-trait = "0.1.68"
|
|||||||
axum = { version = "0.6.18", features = ["headers", "ws"] }
|
axum = { version = "0.6.18", features = ["headers", "ws"] }
|
||||||
axum-client-ip = "0.4.1"
|
axum-client-ip = "0.4.1"
|
||||||
axum-macros = "0.3.7"
|
axum-macros = "0.3.7"
|
||||||
|
base64 = "0.21.2"
|
||||||
check-if-email-exists = "0.9.0"
|
check-if-email-exists = "0.9.0"
|
||||||
chrono = "0.4.26"
|
chrono = "0.4.26"
|
||||||
console-subscriber = { version = "0.1.9", optional = true }
|
console-subscriber = { version = "0.1.9", optional = true }
|
||||||
@ -60,6 +60,7 @@ gethostname = "0.4.3"
|
|||||||
glob = "0.3.1"
|
glob = "0.3.1"
|
||||||
handlebars = "4.3.7"
|
handlebars = "4.3.7"
|
||||||
hashbrown = { version = "0.14.0", features = ["serde"] }
|
hashbrown = { version = "0.14.0", features = ["serde"] }
|
||||||
|
hdrhistogram = "7.5.2"
|
||||||
hostname = "0.3.1"
|
hostname = "0.3.1"
|
||||||
http = "0.2.9"
|
http = "0.2.9"
|
||||||
hyper = { version = "0.14.26", features = ["full", "nightly"] }
|
hyper = { version = "0.14.26", features = ["full", "nightly"] }
|
||||||
@ -69,6 +70,7 @@ listenfd = "1.0.1"
|
|||||||
log = "0.4.19"
|
log = "0.4.19"
|
||||||
mimalloc = { version = "0.1.37", optional = true}
|
mimalloc = { version = "0.1.37", optional = true}
|
||||||
moka = { version = "0.11.2", features = ["future"] }
|
moka = { version = "0.11.2", features = ["future"] }
|
||||||
|
nanorand = { version = "0.7.0", default-features = false, features = ["alloc", "std", "tls", "wyrand"] }
|
||||||
num = "0.4.0"
|
num = "0.4.0"
|
||||||
num-traits = "0.2.15"
|
num-traits = "0.2.15"
|
||||||
once_cell = { version = "1.18.0" }
|
once_cell = { version = "1.18.0" }
|
||||||
@ -101,8 +103,6 @@ tracing-subscriber = "0.3"
|
|||||||
ulid = { version = "1.0.0", features = ["rand", "uuid", "serde"] }
|
ulid = { version = "1.0.0", features = ["rand", "uuid", "serde"] }
|
||||||
url = "2.4.0"
|
url = "2.4.0"
|
||||||
uuid = { version = "1.3.3", default-features = false, features = ["fast-rng", "serde", "v4", "zerocopy"] }
|
uuid = { version = "1.3.3", default-features = false, features = ["fast-rng", "serde", "v4", "zerocopy"] }
|
||||||
hdrhistogram = "7.5.2"
|
|
||||||
base64 = "0.21.2"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1.28.2", features = ["full", "test-util"] }
|
tokio = { version = "1.28.2", features = ["full", "test-util"] }
|
||||||
|
@ -101,8 +101,8 @@ pub struct AuthorizationChecks {
|
|||||||
pub tracking_level: TrackingLevel,
|
pub tracking_level: TrackingLevel,
|
||||||
/// Chance to save reverting eth_call, eth_estimateGas, and eth_sendRawTransaction to the database.
|
/// Chance to save reverting eth_call, eth_estimateGas, and eth_sendRawTransaction to the database.
|
||||||
/// depending on the caller, errors might be expected. this keeps us from bloating our database
|
/// depending on the caller, errors might be expected. this keeps us from bloating our database
|
||||||
/// TODO: f32 would be fine
|
/// u16::MAX == 100%
|
||||||
pub log_revert_chance: f64,
|
pub log_revert_chance: u16,
|
||||||
/// if true, transactions are broadcast only to private mempools.
|
/// if true, transactions are broadcast only to private mempools.
|
||||||
/// IMPORTANT! Once confirmed by a miner, they will be public on the blockchain!
|
/// IMPORTANT! Once confirmed by a miner, they will be public on the blockchain!
|
||||||
pub private_txs: bool,
|
pub private_txs: bool,
|
||||||
|
@ -644,7 +644,7 @@ impl Authorization {
|
|||||||
pub fn internal(db_conn: Option<DatabaseConnection>) -> Web3ProxyResult<Self> {
|
pub fn internal(db_conn: Option<DatabaseConnection>) -> Web3ProxyResult<Self> {
|
||||||
let authorization_checks = AuthorizationChecks {
|
let authorization_checks = AuthorizationChecks {
|
||||||
// any error logs on a local (internal) query are likely problems. log them all
|
// any error logs on a local (internal) query are likely problems. log them all
|
||||||
log_revert_chance: 1.0,
|
log_revert_chance: 100,
|
||||||
tracking_level: TrackingLevel::Detailed,
|
tracking_level: TrackingLevel::Detailed,
|
||||||
// default for everything else should be fine. we don't have a user_id or ip to give
|
// default for everything else should be fine. we don't have a user_id or ip to give
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -1288,7 +1288,8 @@ impl Web3ProxyApp {
|
|||||||
allowed_referers,
|
allowed_referers,
|
||||||
allowed_user_agents,
|
allowed_user_agents,
|
||||||
tracking_level: rpc_key_model.log_level,
|
tracking_level: rpc_key_model.log_level,
|
||||||
log_revert_chance: rpc_key_model.log_revert_chance,
|
// TODO: is floating point math going to scale this correctly
|
||||||
|
log_revert_chance: (rpc_key_model.log_revert_chance * u16::MAX as f64) as u16,
|
||||||
max_concurrent_requests: user_tier_model.max_concurrent_requests,
|
max_concurrent_requests: user_tier_model.max_concurrent_requests,
|
||||||
max_requests_per_period: user_tier_model.max_requests_per_period,
|
max_requests_per_period: user_tier_model.max_requests_per_period,
|
||||||
private_txs: rpc_key_model.private_txs,
|
private_txs: rpc_key_model.private_txs,
|
||||||
|
@ -17,6 +17,7 @@ use futures::StreamExt;
|
|||||||
use latency::{EwmaLatency, PeakEwmaLatency};
|
use latency::{EwmaLatency, PeakEwmaLatency};
|
||||||
use log::{debug, info, trace, warn, Level};
|
use log::{debug, info, trace, warn, Level};
|
||||||
use migration::sea_orm::DatabaseConnection;
|
use migration::sea_orm::DatabaseConnection;
|
||||||
|
use nanorand::Rng;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use redis_rate_limiter::{RedisPool, RedisRateLimitResult, RedisRateLimiter};
|
use redis_rate_limiter::{RedisPool, RedisRateLimitResult, RedisRateLimiter};
|
||||||
@ -28,7 +29,6 @@ use std::fmt;
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::sync::atomic::{self, AtomicU64, AtomicU8, AtomicUsize};
|
use std::sync::atomic::{self, AtomicU64, AtomicU8, AtomicUsize};
|
||||||
use std::{cmp::Ordering, sync::Arc};
|
use std::{cmp::Ordering, sync::Arc};
|
||||||
use thread_fast_rng::rand::Rng;
|
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
use tokio::sync::watch;
|
use tokio::sync::watch;
|
||||||
use tokio::time::{sleep, sleep_until, timeout, Duration, Instant};
|
use tokio::time::{sleep, sleep_until, timeout, Duration, Instant};
|
||||||
@ -270,9 +270,9 @@ impl Web3Rpc {
|
|||||||
) -> ((bool, u8, Reverse<U64>), u32) {
|
) -> ((bool, u8, Reverse<U64>), u32) {
|
||||||
let sort_on = self.sort_on(max_block);
|
let sort_on = self.sort_on(max_block);
|
||||||
|
|
||||||
let mut rng = thread_fast_rng::thread_fast_rng();
|
let mut rng = nanorand::tls_rng();
|
||||||
|
|
||||||
let r = rng.gen::<u32>();
|
let r = rng.generate::<u32>();
|
||||||
|
|
||||||
(sort_on, r)
|
(sort_on, r)
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@ use ethers::providers::ProviderError;
|
|||||||
use ethers::types::{Address, Bytes};
|
use ethers::types::{Address, Bytes};
|
||||||
use log::{debug, error, trace, warn, Level};
|
use log::{debug, error, trace, warn, Level};
|
||||||
use migration::sea_orm::{self, ActiveEnum, ActiveModelTrait};
|
use migration::sea_orm::{self, ActiveEnum, ActiveModelTrait};
|
||||||
|
use nanorand::Rng;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use thread_fast_rng::rand::Rng;
|
|
||||||
use tokio::time::{Duration, Instant};
|
use tokio::time::{Duration, Instant};
|
||||||
|
|
||||||
#[derive(Debug, From)]
|
#[derive(Debug, From)]
|
||||||
@ -225,15 +225,13 @@ impl OpenRequestHandle {
|
|||||||
} else if self.authorization.db_conn.is_some() {
|
} else if self.authorization.db_conn.is_some() {
|
||||||
let log_revert_chance = self.authorization.checks.log_revert_chance;
|
let log_revert_chance = self.authorization.checks.log_revert_chance;
|
||||||
|
|
||||||
if log_revert_chance == 0.0 {
|
if log_revert_chance == 0 {
|
||||||
// trace!(%method, "no chance. skipping save on revert");
|
// trace!(%method, "no chance. skipping save on revert");
|
||||||
RequestErrorHandler::TraceLevel
|
RequestErrorHandler::TraceLevel
|
||||||
} else if log_revert_chance == 1.0 {
|
} else if log_revert_chance == u16::MAX {
|
||||||
// trace!(%method, "gaurenteed chance. SAVING on revert");
|
// trace!(%method, "gaurenteed chance. SAVING on revert");
|
||||||
self.error_handler
|
self.error_handler
|
||||||
} else if thread_fast_rng::thread_fast_rng().gen_range(0.0f64..=1.0)
|
} else if nanorand::tls_rng().generate_range(0u16..u16::MAX) < log_revert_chance {
|
||||||
< log_revert_chance
|
|
||||||
{
|
|
||||||
// trace!(%method, "missed chance. skipping save on revert");
|
// trace!(%method, "missed chance. skipping save on revert");
|
||||||
RequestErrorHandler::TraceLevel
|
RequestErrorHandler::TraceLevel
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user