Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/forester-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
test:
name: Forester e2e test
runs-on: warp-ubuntu-latest-x64-4x
timeout-minutes: 30
timeout-minutes: 45

services:
redis:
Expand Down
2 changes: 1 addition & 1 deletion forester/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "GPL-3.0",
"scripts": {
"build": "cargo build",
"test": "source .env && RUST_LOG=forester=debug,forester_utils=debug cargo test --package forester test_e2e_v2 -- --nocapture",
"test": "source .env && RUST_LOG=forester=debug,forester_utils=debug cargo test --package forester e2e_test -- --nocapture",
"docker:build": "docker build --tag forester -f Dockerfile .."
},
"devDependencies": {
Expand Down
87 changes: 86 additions & 1 deletion forester/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use clap::{Parser, Subcommand};
use clap::{Parser, Subcommand, ValueEnum};

#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
Expand Down Expand Up @@ -173,6 +173,14 @@ pub struct StartArgs {

#[arg(long, env = "FORESTER_SEND_TRANSACTION_RATE_LIMIT")]
pub send_tx_rate_limit: Option<u32>,

#[arg(
long,
env = "FORESTER_PROCESSOR_MODE",
default_value_t = ProcessorMode::All,
help = "Processor mode: v1 (process only v1 trees), v2 (process only v2 trees), all (process all trees)"
)]
pub processor_mode: ProcessorMode,
}

#[derive(Parser, Clone, Debug)]
Expand Down Expand Up @@ -204,3 +212,80 @@ impl StatusArgs {
self.push_gateway_url.is_some()
}
}

#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum ProcessorMode {
#[clap(name = "v1")]
V1,
#[clap(name = "v2")]
V2,
#[clap(name = "all")]
#[default]
All,
}

impl std::fmt::Display for ProcessorMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ProcessorMode::V1 => write!(f, "v1"),
ProcessorMode::V2 => write!(f, "v2"),
ProcessorMode::All => write!(f, "all"),
}
}
}

#[cfg(test)]
mod tests {
use clap::Parser;

use super::*;

#[test]
fn test_processor_mode_parsing() {
// Test v1-only
let args = StartArgs::try_parse_from([
"forester",
"--processor-mode", "v1",
"--rpc-url", "http://test.com",
"--payer", "[1,2,3]",
"--derivation", "[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]"
]).unwrap();
assert_eq!(args.processor_mode, ProcessorMode::V1);

// Test v2-only
let args = StartArgs::try_parse_from([
"forester",
"--processor-mode", "v2",
"--rpc-url", "http://test.com",
"--payer", "[1,2,3]",
"--derivation", "[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]"
]).unwrap();
assert_eq!(args.processor_mode, ProcessorMode::V2);

// Test all (default)
let args = StartArgs::try_parse_from([
"forester",
"--rpc-url", "http://test.com",
"--payer", "[1,2,3]",
"--derivation", "[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]"
]).unwrap();
assert_eq!(args.processor_mode, ProcessorMode::All);

// Test invalid mode should fail
let result = StartArgs::try_parse_from([
"forester",
"--processor-mode", "invalid-mode",
"--rpc-url", "http://test.com",
"--payer", "[1,2,3]",
"--derivation", "[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]"
]);
assert!(result.is_err());
}

#[test]
fn test_processor_mode_display() {
assert_eq!(ProcessorMode::V1.to_string(), "v1");
assert_eq!(ProcessorMode::V2.to_string(), "v2");
assert_eq!(ProcessorMode::All.to_string(), "all");
}
}
10 changes: 5 additions & 5 deletions forester/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use light_registry::{EpochPda, ForesterEpochPda};
use solana_sdk::{pubkey::Pubkey, signature::Keypair};

use crate::{
cli::{StartArgs, StatusArgs},
cli::{ProcessorMode, StartArgs, StatusArgs},
errors::ConfigError,
Result,
};
Expand Down Expand Up @@ -245,10 +245,10 @@ impl ForesterConfig {
slot_update_interval_seconds: args.slot_update_interval_seconds,
tree_discovery_interval_seconds: args.tree_discovery_interval_seconds,
enable_metrics: args.enable_metrics(),
skip_v1_state_trees: false,
skip_v2_state_trees: false,
skip_v1_address_trees: false,
skip_v2_address_trees: false,
skip_v1_state_trees: args.processor_mode == ProcessorMode::V2,
skip_v2_state_trees: args.processor_mode == ProcessorMode::V1,
skip_v1_address_trees: args.processor_mode == ProcessorMode::V2,
skip_v2_address_trees: args.processor_mode == ProcessorMode::V1,
},
rpc_pool_config: RpcPoolConfig {
max_size: args.rpc_pool_size,
Expand Down
13 changes: 13 additions & 0 deletions forester/src/epoch_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,19 @@ pub async fn run_service<R: Rpc>(
) -> Result<()> {
info_span!("run_service", forester = %config.payer_keypair.pubkey())
.in_scope(|| async {
let processor_mode_str = match (
config.general_config.skip_v1_state_trees
&& config.general_config.skip_v1_address_trees,
config.general_config.skip_v2_state_trees
&& config.general_config.skip_v2_address_trees,
) {
(true, false) => "v2",
(false, true) => "v1",
(false, false) => "all",
_ => "unknown",
};
info!("Starting forester in {} mode", processor_mode_str);

const INITIAL_RETRY_DELAY: Duration = Duration::from_secs(1);
const MAX_RETRY_DELAY: Duration = Duration::from_secs(30);

Expand Down
3 changes: 2 additions & 1 deletion forester/tests/priority_fee_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use forester::{
cli::StartArgs,
cli::{ProcessorMode, StartArgs},
processor::v1::{
config::CapConfig,
helpers::{get_capped_priority_fee, request_priority_fee_estimate},
Expand Down Expand Up @@ -75,6 +75,7 @@ async fn test_priority_fee_request() {
rpc_rate_limit: None,
photon_rate_limit: None,
send_tx_rate_limit: None,
processor_mode: ProcessorMode::All,
};

let config = ForesterConfig::new_for_start(&args).expect("Failed to create config");
Expand Down
1 change: 0 additions & 1 deletion sdk-libs/client/src/rpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ impl LightClient {
self.retry_config.max_retries,
e
);
tokio::task::yield_now().await;
sleep(self.retry_config.retry_delay).await;
} else {
return Err(e);
Expand Down