Skip to content

Commit

Permalink
RPC-456 adding tests and measurements for different algos
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitriy-helius committed Sep 13, 2024
1 parent 919d723 commit 29ff945
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 26 deletions.
14 changes: 8 additions & 6 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ yellowstone-grpc-geyser = { git = "https://github.com/helius-labs/yellowstone-gr
rand = "0.8.5"
futures = "0.3.24"
figment = { version = "0.10.6", features = ["env", "test"] }
tower = { version = "0.4.13", features = ["full"] }
tower = { version = "0.4.13", features = ["full"] }
thiserror = "1.0.63"
anyhow = "1.0.86"
112 changes: 93 additions & 19 deletions src/priority_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,11 @@ impl GrpcConsumer for PriorityFeeTracker {
&mut compute_budget,
);

let writable_accounts = vec!(
let writable_accounts = vec![
construct_writable_accounts(accounts, &header),
writable_accounts
).concat();
writable_accounts,
]
.concat();

statsd_count!(
"priority_fee_tracker.accounts_processed",
Expand Down Expand Up @@ -538,9 +539,16 @@ impl PriorityFeeTracker {
self.calculation2(&accounts, include_vote, &lookback_period)
};

let version = if calculation1 { "v1" } else { "v2" };
statsd_gauge!(
"get_priority_fee_estimates_time",
start.elapsed().as_nanos() as u64
start.elapsed().as_nanos() as u64,
"version" => &version
);
statsd_count!(
"get_priority_fee_calculation_version",
1,
"version" => &version
);
if let Err(e) = self.sampling_sender.try_send((
accounts.to_owned(),
Expand Down Expand Up @@ -745,11 +753,14 @@ fn percentile(values: &mut Vec<f64>, percentile: Percentile) -> f64 {

#[cfg(test)]
mod tests {
use std::collections::HashSet;
use super::*;
use anyhow::Context;
use cadence::{NopMetricSink, StatsdClient};
use cadence_macros::set_global_default;

use super::*;
use solana_sdk::compute_budget::ComputeBudgetInstruction::{
RequestHeapFrame, SetComputeUnitLimit, SetComputeUnitPrice, SetLoadedAccountsDataSizeLimit,
};
use std::collections::HashSet;

fn init_metrics() {
let noop = NopMetricSink {};
Expand Down Expand Up @@ -831,12 +842,7 @@ mod tests {

// Simulate adding the fixed fees as both account-specific and transaction fees
for (i, fee) in fees.clone().into_iter().enumerate() {
tracker.push_priority_fee_for_txn(
i as Slot,
accounts.clone(),
fee as u64,
false,
);
tracker.push_priority_fee_for_txn(i as Slot, accounts.clone(), fee as u64, false);
}

// Now test the fee estimates for a known priority level, let's say medium (50th percentile)
Expand Down Expand Up @@ -891,12 +897,7 @@ mod tests {

// Simulate adding the fixed fees as both account-specific and transaction fees
for (i, fee) in fees.clone().into_iter().enumerate() {
tracker.push_priority_fee_for_txn(
i as Slot,
accounts.clone(),
fee as u64,
false,
);
tracker.push_priority_fee_for_txn(i as Slot, accounts.clone(), fee as u64, false);
}

// Now test the fee estimates for a known priority level, let's say medium (50th percentile)
Expand Down Expand Up @@ -1156,6 +1157,79 @@ mod tests {
}
}

const MICRO_LAMPORTS_PER_LAMPORT: u128 = 1_000_000;
#[test]
fn test_budget_calculation() -> Result<(), anyhow::Error> {
// Ok(PrioritizationFeeDetails { fee: 4923, priority: 39066 })
let account_keys = [
"89oWV7LXUtEgh4sYQS7gBGPVvsznCzgf9ip5h7SHWDSr", // random account
"GitvMpoCygGyDGUK4SMZdHpEqCqwif2cnuLAhmca96zw", // random account
"731dL3MmiEKaAT711BWxizxKyHcwLxqWQ2pLroPmbMye", // random account
"ComputeBudget111111111111111111111111111111", // budget program system account
"11111111111111111111111111111111", // budget program for accounts account
];

let comp1 = SetComputeUnitLimit(100_000)
.pack()
.context("Could not pack compute unit limit")?;
let comp2 = SetComputeUnitPrice(200_000)
.pack()
.context("Could not pack compute unit price")?;
let comp3 = SetLoadedAccountsDataSizeLimit(300_000)
.pack()
.context("Could not pack loaded account data size limit")?;
let comp4 = RequestHeapFrame(64 * 1024)
.pack()
.context("Could not pack request for heap frame")?;

let random_account = "some app -- ignore".as_bytes().to_vec();
let instructions = [
(2u8, random_account, vec![]),
(3u8, comp1.clone(), Vec::with_capacity(0)),
(3u8, comp2.clone(), Vec::with_capacity(0)),
(3u8, comp3.clone(), Vec::with_capacity(0)),
(3u8, comp4.clone(), Vec::with_capacity(0)),
(4u8, comp1, vec![0u8, 1u8].to_vec()),
];

let fee = calculate_priority_fee_details(
&construct_accounts(&account_keys[..])?,
&construct_instructions(instructions.to_vec())?,
&mut ComputeBudget::default(),
)?;
assert_eq!(
fee.get_fee() as u128,
(200_000 * 100_000 + MICRO_LAMPORTS_PER_LAMPORT - 1)
/ MICRO_LAMPORTS_PER_LAMPORT as u128
);
assert_eq!(fee.get_priority(), 200_000);

Ok::<(), anyhow::Error>(())
}

fn construct_instructions(
instructions: Vec<(u8, Vec<u8>, Vec<u8>)>,
) -> Result<Vec<CompiledInstruction>, anyhow::Error> {
let res: Result<Vec<CompiledInstruction>, _> = instructions
.into_iter()
.map(|data| {
let (prog_id, operations, accounts) = data;
Ok::<CompiledInstruction, anyhow::Error>(CompiledInstruction::new_from_raw_parts(
prog_id, operations, accounts,
))
})
.collect();

res.with_context(|| "Failed to parse account keys")
}

fn construct_accounts(account_keys: &[&str]) -> Result<Vec<Pubkey>, anyhow::Error> {
let res: Result<Vec<Pubkey>, _> =
account_keys.iter().map(|&s| Pubkey::try_from(s)).collect();

res.with_context(|| "Failed to parse account keys")
}

fn generate_data() -> Vec<(Vec<Pubkey>, Option<MessageHeader>, Vec<Pubkey>)> {
let p1 = Pubkey::new_unique();
let p2 = Pubkey::new_unique();
Expand Down

0 comments on commit 29ff945

Please sign in to comment.