Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add dynamic priority fees to forester #1481

Merged
merged 8 commits into from
Jan 17, 2025
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
36 changes: 29 additions & 7 deletions .github/workflows/forester-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,40 @@ concurrency:
cancel-in-progress: true

env:
RUST_BACKTRACE: "1"
RUSTFLAGS: "--cfg tokio_unstable -D warnings"

jobs:
test:
strategy:
matrix:
test-name: [
{name: "address-batched", command: "test_address_batched", timeout: 60, needs-test-program: true},
{name: "state-batched", command: "test_state_batched", timeout: 60, needs-test-program: false},
{name: "2-foresters", command: "test_epoch_monitor_with_2_foresters", timeout: 60, needs-test-program: false},
{name: "double-registration", command: "test_epoch_double_registration", timeout: 60, needs-test-program: false}
]
test-name:
[
{
name: "address-batched",
command: "test_address_batched",
timeout: 60,
needs-test-program: true,
},
{
name: "state-batched",
command: "test_state_batched",
timeout: 60,
needs-test-program: false,
},
{
name: "2-foresters",
command: "test_epoch_monitor_with_2_foresters",
timeout: 60,
needs-test-program: false,
},
{
name: "double-registration",
command: "test_epoch_double_registration",
timeout: 60,
needs-test-program: false,
},
]
name: test-${{ matrix.test-name.name }}
runs-on: ubuntu-latest
timeout-minutes: ${{ matrix.test-name.timeout }}
Expand Down Expand Up @@ -63,4 +85,4 @@ jobs:
- name: Run ${{ matrix.test-name.name }} tests
run: |
source ./scripts/devenv.sh
cargo test --package forester ${{ matrix.test-name.command }} -- --nocapture
cargo test --package forester ${{ matrix.test-name.command }} -- --nocapture
58 changes: 58 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ solana-cli-output = "=1.18.22"
solana-transaction-status = "=1.18.22"
solana-account-decoder = "=1.18.22"
solana-rpc = "=1.18.22"
solana-rpc-client-api = "=1.18.22"
spl-token = "=4.0.0"
spl-token-2022 = {version="3.0.5", no-default-features = true, features = ["no-entrypoint"]}

Expand Down
7 changes: 7 additions & 0 deletions forester/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ light-client = { workspace = true }
light-merkle-tree-metadata = { workspace = true }
light-sdk = { workspace = true }
light-program-test = { workspace = true}
solana-transaction-status = { workspace = true }
bincode = "1.3"
url = "2.2"
tokio-tungstenite = "0.16"
bb8 = { workspace = true }

serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
Expand All @@ -48,3 +54,4 @@ serial_test = "3.2.0"
light-prover-client = { workspace = true }
light-test-utils = { workspace = true }
light-program-test = { workspace = true, features = ["devenv"] }
dotenvy = "0.15"
23 changes: 11 additions & 12 deletions forester/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,35 @@ It subscribes to the nullifier queue and nullifies merkle tree leaves.
## Configuration

Forester requires a configuration file, `forester.toml`, specifying necessary keys:

- `STATE_MERKLE_TREE_PUBKEY`: Address of the State Merkle tree.
- `NULLIFIER_QUEUE_PUBKEY`: Address of the State Nullifier queue.
- `ADDRESS_MERKLE_TREE_PUBKEY`: Address of the Address Merkle tree.
- `ADDRESS_MERKLE_TREE_QUEUE_PUBKEY`: Address of the Address queue.
- `REGISTRY_PUBKEY`: Address of the Registry program.

To setup your environment properly, copy `.env.example` to `.env`
and update the `FORESTER_PAYER` field with your appropriate key.

To setup your environment properly, copy `.env.example` to `.env`
and update the `FORESTER_PAYER` field with your appropriate key.

Alternatively, if you prefer to use a terminal profile file,
add the key to your `~/.zshrc` (zsh) or `~/.bashrc` (bash)
Alternatively, if you prefer to use a terminal profile file,
add the key to your `~/.zshrc` (zsh) or `~/.bashrc` (bash)
by including this line: `export FORESTER_PAYER=your_value_here`.
Substitute `your_value_here` with your actual key.
Substitute `your_value_here` with your actual key.

Remember to restart your terminal or source your terminal profile for the changes to take effect.

## Usage

1. Run the service:
To subscribe to nullify the state merkle tree, use the following command:
`cargo run -- subscribe`
To subscribe to nullify the state merkle tree, use the following command:
`cargo run -- subscribe`
2. To manually nullify state merkle tree leaves, use the following command:
`cargo run -- nullify-state`
`cargo run -- nullify-state`
3. To manually nullify address merkle tree leaves, use the following command:
`cargo run -- nullify-addresses`
4. To manually nullify state *and* address merkle tree leaves, use the following command:
`cargo run -- nullify-addresses`
4. To manually nullify state _and_ address merkle tree leaves, use the following command:
`cargo run -- nullify`


## TODO

1. Add indexer URL to the configuration file.
Expand Down
17 changes: 13 additions & 4 deletions forester/src/epoch_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ impl<R: RpcConnection, I: Indexer<R> + IndexerType<R>> EpochManager<R, I> {
)
.await?;

// light slot length in s
let light_slot_timeout = {
let slot_length_u32 = u32::try_from(epoch_pda.protocol_config.slot_length)
.map_err(|_| ConfigurationError::SlotLengthOverflow {
Expand Down Expand Up @@ -907,14 +908,21 @@ impl<R: RpcConnection, I: Indexer<R> + IndexerType<R>> EpochManager<R, I> {
}
}
} else {
// TODO: measure accuracy
// Optional replace with shutdown signal for all child processes
// TODO: measure accuracy Optional replace with shutdown
// signal for all child processes
//
// Note: as of now, this executes all batches sequentially:
// a single batch must fully complete before the next batch
// is sent. We can either limit num_batches to 1 and
// increase batch_size (quick fix) and require another
// rate-limiting mechanism (with more control). Or rework
// the send logic to not await confirmations.
let batched_tx_config = SendBatchedTransactionsConfig {
num_batches: 10,
build_transaction_batch_config: BuildTransactionBatchConfig {
batch_size: 50, // TODO: make batch size configurable and or dynamic based on queue usage
compute_unit_price: None, // Make dynamic based on queue usage
compute_unit_limit: Some(1_000_000),
compute_unit_price: Some(10_000), // Is dynamic. Sets max.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
compute_unit_price: Some(10_000), // Is dynamic. Sets max.
max_compute_unit_price: Some(10_000), // Is dynamic. Sets max.

compute_unit_limit: Some(180_000),
},
queue_config: self.config.queue_config,
retry_config: RetryConfig {
Expand All @@ -932,6 +940,7 @@ impl<R: RpcConnection, I: Indexer<R> + IndexerType<R>> EpochManager<R, I> {
};

debug!("Sending transactions...");
// sequential
let start_time = Instant::now();
let batch_tx_future = send_batched_transactions(
&self.config.payer_keypair,
Expand Down
74 changes: 74 additions & 0 deletions forester/src/helius_priority_fee_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// adapted from https://github.com/helius-labs/helius-rust-sdk/blob/dev/src/types/types.rs
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub enum PriorityLevel {
Min,
Low,
Medium,
High,
VeryHigh,
UnsafeMax,
Default,
}

#[derive(Serialize, Deserialize, Debug)]
pub enum UiTransactionEncoding {
Binary,
Base64,
Base58,
Json,
JsonParsed,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct RpcRequest<T> {
pub jsonrpc: String,
pub id: String,
pub method: String,
#[serde(rename = "params")]
pub parameters: T,
}

impl<T> RpcRequest<T> {
pub fn new(method: String, parameters: T) -> Self {
Self {
jsonrpc: "2.0".to_string(),
id: "1".to_string(),
method,
parameters,
}
}
}

#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct RpcResponse<T> {
pub jsonrpc: String,
pub id: String,
pub result: T,
}

#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetPriorityFeeEstimateOptions {
pub priority_level: Option<PriorityLevel>,
pub include_all_priority_fee_levels: Option<bool>,
pub transaction_encoding: Option<UiTransactionEncoding>,
pub lookback_slots: Option<u8>,
pub recommended: Option<bool>,
pub include_vote: Option<bool>,
}

#[derive(Serialize, Deserialize, Debug, Default)]
pub struct GetPriorityFeeEstimateRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction: Option<String>,
#[serde(rename = "accountKeys", skip_serializing_if = "Option::is_none")]
pub account_keys: Option<Vec<String>>,
pub options: Option<GetPriorityFeeEstimateOptions>,
}

#[derive(Serialize, Deserialize, Debug, Default)]
pub struct GetPriorityFeeEstimateResponse {
#[serde(rename = "priorityFeeEstimate")]
pub priority_fee_estimate: Option<f64>,
}
2 changes: 2 additions & 0 deletions forester/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod config;
pub mod epoch_manager;
pub mod errors;
pub mod forester_status;
pub mod helius_priority_fee_types;
mod indexer_type;
pub mod metrics;
pub mod pagerduty;
Expand All @@ -15,6 +16,7 @@ pub mod queue_helpers;
pub mod rollover;
pub mod send_transaction;
mod slot_tracker;
pub mod smart_transaction;
pub mod telemetry;
pub mod tree_data_sync;
pub mod tree_finder;
Expand Down
Loading
Loading