Skip to content

Commit 7da3183

Browse files
authored
chore: rust ci rules (#21)
* fix rust-analyzer failing to load i got this error: Caused by: Dependency 'rblib' has different source paths depending on the build target. Each dependency must have a single canonical source path irrespective of build target. * fix compilation issues * fix clippy issues * more clippy fixes * apply cargo fmt * vibe code rust ci stuff * edit the vibes
1 parent f96e198 commit 7da3183

File tree

12 files changed

+272
-73
lines changed

12 files changed

+272
-73
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
name: "[unichain-builder] Checks"
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
merge_group:
7+
push:
8+
branches:
9+
- main
10+
11+
env:
12+
CARGO_TERM_COLOR: always
13+
RUST_BACKTRACE: 1
14+
15+
jobs:
16+
check:
17+
name: Cargo Check
18+
runs-on: warp-ubuntu-latest-x64-32x
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Install Rust toolchain
23+
uses: dtolnay/rust-toolchain@stable
24+
25+
- name: Cache cargo registry
26+
uses: actions/cache@v4
27+
with:
28+
path: ~/.cargo/registry
29+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
30+
31+
- name: Cache cargo index
32+
uses: actions/cache@v4
33+
with:
34+
path: ~/.cargo/git
35+
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
36+
37+
- name: Cache cargo build
38+
uses: actions/cache@v4
39+
with:
40+
path: target
41+
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
42+
43+
- name: Install system dependencies
44+
run: |
45+
sudo apt-get update
46+
sudo apt-get install -y libclang-dev libssl-dev pkg-config protobuf-compiler
47+
48+
- name: Run cargo check
49+
run: make check
50+
51+
clippy:
52+
name: Clippy
53+
runs-on: warp-ubuntu-latest-x64-32x
54+
steps:
55+
- uses: actions/checkout@v4
56+
57+
- name: Install Rust toolchain
58+
uses: dtolnay/rust-toolchain@stable
59+
with:
60+
components: clippy
61+
62+
- name: Cache cargo registry
63+
uses: actions/cache@v4
64+
with:
65+
path: ~/.cargo/registry
66+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
67+
68+
- name: Cache cargo index
69+
uses: actions/cache@v4
70+
with:
71+
path: ~/.cargo/git
72+
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
73+
74+
- name: Cache cargo build
75+
uses: actions/cache@v4
76+
with:
77+
path: target
78+
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
79+
80+
- name: Install system dependencies
81+
run: |
82+
sudo apt-get update
83+
sudo apt-get install -y libclang-dev libssl-dev pkg-config protobuf-compiler
84+
85+
- name: Run clippy
86+
run: make clippy
87+
88+
fmt:
89+
name: Rustfmt
90+
runs-on: warp-ubuntu-latest-x64-32x
91+
steps:
92+
- uses: actions/checkout@v4
93+
94+
- name: Install Rust nightly toolchain
95+
uses: dtolnay/rust-toolchain@nightly
96+
with:
97+
components: rustfmt
98+
99+
- name: Run cargo fmt
100+
run: make fmt-check
101+
102+
test:
103+
name: Tests
104+
runs-on: warp-ubuntu-latest-x64-32x
105+
steps:
106+
- uses: actions/checkout@v4
107+
108+
- name: Install Rust toolchain
109+
uses: dtolnay/rust-toolchain@stable
110+
111+
- name: Cache cargo registry
112+
uses: actions/cache@v4
113+
with:
114+
path: ~/.cargo/registry
115+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
116+
117+
- name: Cache cargo index
118+
uses: actions/cache@v4
119+
with:
120+
path: ~/.cargo/git
121+
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
122+
123+
- name: Cache cargo build
124+
uses: actions/cache@v4
125+
with:
126+
path: target
127+
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
128+
129+
- name: Install system dependencies
130+
run: |
131+
sudo apt-get update
132+
sudo apt-get install -y libclang-dev libssl-dev pkg-config protobuf-compiler
133+
134+
- name: Run tests
135+
run: make test

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ reth-provider = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
7474
console-subscriber = { version = "0.4", optional = true }
7575

7676
[dev-dependencies]
77-
rblib = { git = "https://github.com/flashbots/rblib", rev = "9e9b93a601a4cb1a1dd5ddd3952b09ab145d3e93", features = [
77+
rblib = { git = "https://github.com/flashbots/rblib", rev = "5dea87ce8e9ea61692d5d3e05545b62d01671e1e", features = [
7878
"test-utils",
7979
] }
8080

Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
.PHONY: help check clippy fmt fmt-check test clean all
2+
3+
help:
4+
@echo "Available targets:"
5+
@echo " make check - Run cargo check on all workspace members"
6+
@echo " make clippy - Run clippy with project-specific lints"
7+
@echo " make fmt - Format code using rustfmt"
8+
@echo " make fmt-check - Check formatting without modifying files"
9+
@echo " make test - Run all tests"
10+
@echo " make all - Run check, clippy, fmt-check, and test"
11+
@echo " make clean - Clean build artifacts"
12+
13+
check:
14+
cargo check --workspace --all-targets --all-features
15+
16+
clippy:
17+
cargo clippy --workspace --all-targets --all-features -- -D warnings
18+
19+
fmt:
20+
cargo +nightly fmt --all
21+
22+
fmt-check:
23+
cargo +nightly fmt --all -- --check
24+
25+
test:
26+
cargo test --workspace --all-features
27+
28+
clean:
29+
cargo clean
30+
31+
all: check clippy fmt-check test

src/args.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ pub struct FlashblocksArgs {
8888
enabled: Option<SocketAddr>,
8989

9090
/// Should we calculate the state root for each flashblock
91-
#[arg(
92-
long = "flashblocks.calculate-state-root",
93-
default_value = "false",
94-
env = "FLASHBLOCKS_CALCULATE_STATE_ROOT"
95-
)]
96-
pub calculate_state_root: bool,
91+
#[arg(
92+
long = "flashblocks.calculate-state-root",
93+
default_value = "false",
94+
env = "FLASHBLOCKS_CALCULATE_STATE_ROOT"
95+
)]
96+
pub calculate_state_root: bool,
9797
}
9898

9999
impl Default for BuilderArgs {
@@ -249,7 +249,7 @@ impl FlashblocksArgs {
249249
interval: Duration::from_millis(250),
250250
leeway_time: Duration::from_millis(75),
251251
enabled: Some(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, port).into()),
252-
calculate_state_root: true,
252+
calculate_state_root: true,
253253
}
254254
}
255255

src/limits.rs

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44
//! individual flashblocks. This is essentially where we define the block /
55
//! flashblock partitioning logic.
66
7-
use std::sync::{Arc, Mutex};
8-
use std::sync::atomic::{AtomicU64, Ordering};
97
use {
108
crate::Flashblocks,
119
core::time::Duration,
1210
rblib::{alloy::consensus::BlockHeader, prelude::*},
13-
std::ops::{Div, Rem},
11+
std::{
12+
ops::{Div, Rem},
13+
sync::{
14+
Arc,
15+
Mutex,
16+
atomic::{AtomicU64, Ordering},
17+
},
18+
},
1419
};
1520

1621
/// Specifies the limits for individual flashblocks.
@@ -35,25 +40,29 @@ pub struct FlashblockState {
3540
/// None - uninitialized state, happens only on first block building job
3641
current_block: Option<u64>,
3742
/// Current flashblock being built, number based
38-
/// 0 - uninitialized state, use progress_state to initialize it
43+
/// 0 - uninitialized state, use `progress_state` to initialize it
3944
current_flashblock: u64,
4045
/// Interval of the first flashblock, it absorbs leeway time and network lag
4146
first_flashblock_interval: Duration,
4247
/// Gas for flashblock used for current block
4348
gas_per_flashblock: u64,
44-
/// Used to communicate maximum number of flashblocks on every blocks for other steps
45-
// TODO: once we remove max_flashblocks from publish step we could change it to u64
49+
/// Used to communicate maximum number of flashblocks on every blocks for
50+
/// other steps
51+
// TODO: once we remove max_flashblocks from publish step we could change it
52+
// to u64
4653
max_flashblocks: Arc<AtomicU64>,
4754
}
4855

4956
impl FlashblockState {
5057
fn current_gas_limit(&self) -> u64 {
51-
self.gas_per_flashblock.saturating_mul(self.current_flashblock)
58+
self
59+
.gas_per_flashblock
60+
.saturating_mul(self.current_flashblock)
5261
}
5362
}
5463
impl FlashblockLimits {
5564
pub fn new(interval: Duration, max_flashblocks: Arc<AtomicU64>) -> Self {
56-
let state = FlashblockState{
65+
let state = FlashblockState {
5766
max_flashblocks,
5867
..Default::default()
5968
};
@@ -63,11 +72,13 @@ impl FlashblockLimits {
6372
}
6473
}
6574

66-
/// Checks if we have started building new block, if so we need to reset the state
67-
/// This will produce empty state, progress state before using it
68-
pub fn update_state(&self,
75+
/// Checks if we have started building new block, if so we need to reset the
76+
/// state This will produce empty state, progress state before using it
77+
pub fn update_state(
78+
&self,
6979
payload: &Checkpoint<Flashblocks>,
70-
enclosing: &Limits) {
80+
enclosing: &Limits,
81+
) {
7182
let mut state = self.state.lock().expect("mutex is not poisoned");
7283

7384
if state.current_block != Some(payload.block().number()) {
@@ -77,12 +88,15 @@ impl FlashblockLimits {
7788
let remaining_time =
7889
payload_deadline.saturating_sub(payload.building_since().elapsed());
7990

80-
let (target_flashblock, first_flashblock_interval) = self.calculate_flashblocks(payload, remaining_time);
91+
let (target_flashblock, first_flashblock_interval) =
92+
self.calculate_flashblocks(payload, remaining_time);
8193
state.gas_per_flashblock = enclosing.gas_limit / target_flashblock;
8294
state.current_block = Some(payload.block().number());
8395
state.current_flashblock = 0;
8496
state.first_flashblock_interval = first_flashblock_interval;
85-
state.max_flashblocks.store(target_flashblock, Ordering::Relaxed);
97+
state
98+
.max_flashblocks
99+
.store(target_flashblock, Ordering::Relaxed);
86100
}
87101
}
88102

@@ -96,20 +110,20 @@ impl FlashblockLimits {
96110
pub fn get_limits(&self, enclosing: &Limits) -> Limits {
97111
let state = self.state.lock().expect("mutex is not poisoned");
98112
// Check that state was progressed at least once
99-
assert_ne!(state.current_flashblock, 0, "Get limits on uninitialized state");
113+
assert_ne!(
114+
state.current_flashblock, 0,
115+
"Get limits on uninitialized state"
116+
);
100117
// If we don't need to create new flashblocks - exit with immediate deadline
101-
if state.current_flashblock > state.max_flashblocks.load(Ordering::Relaxed) {
118+
if state.current_flashblock > state.max_flashblocks.load(Ordering::Relaxed)
119+
{
102120
enclosing.with_deadline(Duration::from_millis(1))
103121
} else {
104122
// If self.current_flashblock == 1, we are building first flashblock
105123
let enclosing = if state.current_flashblock == 1 {
106-
enclosing
107-
.with_deadline(state.first_flashblock_interval)
108-
124+
enclosing.with_deadline(state.first_flashblock_interval)
109125
} else {
110-
enclosing
111-
.with_deadline(self.interval)
112-
126+
enclosing.with_deadline(self.interval)
113127
};
114128
enclosing.with_gas_limit(state.current_gas_limit())
115129
}
@@ -130,10 +144,11 @@ impl FlashblockLimits {
130144
.timestamp()
131145
.saturating_sub(payload.block().parent().header().timestamp()),
132146
);
133-
let remaining_time = remaining_time
134-
.min(block_time);
135-
let interval_millis = self.interval.as_millis() as u64;
136-
let remaining_time_millis = remaining_time.as_millis() as u64;
147+
let remaining_time = remaining_time.min(block_time);
148+
let interval_millis = u64::try_from(self.interval.as_millis())
149+
.expect("interval_millis should never be greater than u64::MAX");
150+
let remaining_time_millis = u64::try_from(remaining_time.as_millis())
151+
.expect("remaining_time_millis should never be greater than u64::MAX");
137152
let first_flashblock_offset = remaining_time_millis.rem(interval_millis);
138153

139154
if first_flashblock_offset == 0 {
@@ -165,13 +180,14 @@ impl ScopedLimits<Flashblocks> for FlashblockLimits {
165180
let limits = self.get_limits(enclosing);
166181

167182
let state = self.state.lock().expect("mutex is not poisoned");
168-
if state.current_flashblock <= state.max_flashblocks.load(Ordering::Relaxed) {
183+
if state.current_flashblock <= state.max_flashblocks.load(Ordering::Relaxed)
184+
{
169185
let gas_used = payload.cumulative_gas_used();
170186
let remaining_gas = enclosing.gas_limit.saturating_sub(gas_used);
171187
tracing::warn!(
172188
">---> flashblocks: {}/{}, payload txs: {}, gas used: {} ({}%), \
173-
gas_remaining: {} ({}%), next_block_gas_limit: {} ({}%), gas per block: {} ({}%), \
174-
remaining_time: {}ms, gas_limit: {}",
189+
gas_remaining: {} ({}%), next_block_gas_limit: {} ({}%), gas per \
190+
block: {} ({}%), remaining_time: {}ms, gas_limit: {}",
175191
state.current_flashblock,
176192
state.max_flashblocks.load(Ordering::Relaxed),
177193
payload.history().transactions().count(),
@@ -188,7 +204,5 @@ impl ScopedLimits<Flashblocks> for FlashblockLimits {
188204
);
189205
}
190206
limits
191-
192207
}
193208
}
194-

0 commit comments

Comments
 (0)