2022-05-15 21:06:33 -07:00
|
|
|
/// There are 10^6 micro-lamports in one lamport
|
|
|
|
const MICRO_LAMPORTS_PER_LAMPORT: u64 = 1_000_000;
|
|
|
|
|
|
|
|
type MicroLamports = u128;
|
|
|
|
|
|
|
|
pub enum PrioritizationFeeType {
|
|
|
|
ComputeUnitPrice(u64),
|
2022-09-09 15:24:21 -07:00
|
|
|
// TODO: remove 'Deprecated' after feature remove_deprecated_request_unit_ix::id() is activated
|
2022-05-15 21:06:33 -07:00
|
|
|
Deprecated(u64),
|
|
|
|
}
|
|
|
|
|
2022-05-22 18:00:42 -07:00
|
|
|
#[derive(Default, Debug, PartialEq, Eq)]
|
2022-05-15 21:06:33 -07:00
|
|
|
pub struct PrioritizationFeeDetails {
|
|
|
|
fee: u64,
|
|
|
|
priority: u64,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PrioritizationFeeDetails {
|
2022-05-17 22:14:31 -07:00
|
|
|
pub fn new(fee_type: PrioritizationFeeType, compute_unit_limit: u64) -> Self {
|
2022-05-15 21:06:33 -07:00
|
|
|
match fee_type {
|
2022-09-09 15:24:21 -07:00
|
|
|
// TODO: remove support of 'Deprecated' after feature remove_deprecated_request_unit_ix::id() is activated
|
2022-05-15 21:06:33 -07:00
|
|
|
PrioritizationFeeType::Deprecated(fee) => {
|
2022-05-17 22:14:31 -07:00
|
|
|
let priority = if compute_unit_limit == 0 {
|
2022-05-15 21:06:33 -07:00
|
|
|
0
|
|
|
|
} else {
|
|
|
|
let micro_lamport_fee: MicroLamports =
|
|
|
|
(fee as u128).saturating_mul(MICRO_LAMPORTS_PER_LAMPORT as u128);
|
2022-05-17 22:14:31 -07:00
|
|
|
let priority = micro_lamport_fee.saturating_div(compute_unit_limit as u128);
|
2022-05-15 21:06:33 -07:00
|
|
|
u64::try_from(priority).unwrap_or(u64::MAX)
|
|
|
|
};
|
|
|
|
|
|
|
|
Self { fee, priority }
|
|
|
|
}
|
|
|
|
PrioritizationFeeType::ComputeUnitPrice(cu_price) => {
|
|
|
|
let fee = {
|
|
|
|
let micro_lamport_fee: MicroLamports =
|
2022-05-17 22:14:31 -07:00
|
|
|
(cu_price as u128).saturating_mul(compute_unit_limit as u128);
|
2022-05-15 21:06:33 -07:00
|
|
|
let fee = micro_lamport_fee
|
|
|
|
.saturating_add(MICRO_LAMPORTS_PER_LAMPORT.saturating_sub(1) as u128)
|
|
|
|
.saturating_div(MICRO_LAMPORTS_PER_LAMPORT as u128);
|
|
|
|
u64::try_from(fee).unwrap_or(u64::MAX)
|
|
|
|
};
|
|
|
|
|
|
|
|
Self {
|
|
|
|
fee,
|
|
|
|
priority: cu_price,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_fee(&self) -> u64 {
|
|
|
|
self.fee
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_priority(&self) -> u64 {
|
|
|
|
self.priority
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::{PrioritizationFeeDetails as FeeDetails, PrioritizationFeeType as FeeType, *};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_new_with_no_fee() {
|
|
|
|
for compute_units in [0, 1, MICRO_LAMPORTS_PER_LAMPORT, u64::MAX] {
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::ComputeUnitPrice(0), compute_units),
|
|
|
|
FeeDetails::default(),
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(0), compute_units),
|
|
|
|
FeeDetails::default(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_new_with_compute_unit_price() {
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::ComputeUnitPrice(MICRO_LAMPORTS_PER_LAMPORT - 1), 1),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 1,
|
|
|
|
priority: MICRO_LAMPORTS_PER_LAMPORT - 1,
|
|
|
|
},
|
|
|
|
"should round up (<1.0) lamport fee to 1 lamport"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::ComputeUnitPrice(MICRO_LAMPORTS_PER_LAMPORT), 1),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 1,
|
|
|
|
priority: MICRO_LAMPORTS_PER_LAMPORT,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::ComputeUnitPrice(MICRO_LAMPORTS_PER_LAMPORT + 1), 1),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 2,
|
|
|
|
priority: MICRO_LAMPORTS_PER_LAMPORT + 1,
|
|
|
|
},
|
|
|
|
"should round up (>1.0) lamport fee to 2 lamports"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::ComputeUnitPrice(200), 100_000),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 20,
|
|
|
|
priority: 200,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(
|
|
|
|
FeeType::ComputeUnitPrice(MICRO_LAMPORTS_PER_LAMPORT),
|
|
|
|
u64::MAX
|
|
|
|
),
|
|
|
|
FeeDetails {
|
|
|
|
fee: u64::MAX,
|
|
|
|
priority: MICRO_LAMPORTS_PER_LAMPORT,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::ComputeUnitPrice(u64::MAX), u64::MAX),
|
|
|
|
FeeDetails {
|
|
|
|
fee: u64::MAX,
|
|
|
|
priority: u64::MAX,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_new_with_deprecated_fee() {
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(1), MICRO_LAMPORTS_PER_LAMPORT / 2 - 1),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 1,
|
|
|
|
priority: 2,
|
|
|
|
},
|
|
|
|
"should round down fee rate of (>2.0) to priority value 1"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(1), MICRO_LAMPORTS_PER_LAMPORT / 2),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 1,
|
|
|
|
priority: 2,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(1), MICRO_LAMPORTS_PER_LAMPORT / 2 + 1),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 1,
|
|
|
|
priority: 1,
|
|
|
|
},
|
|
|
|
"should round down fee rate of (<2.0) to priority value 1"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(1), MICRO_LAMPORTS_PER_LAMPORT),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 1,
|
|
|
|
priority: 1,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(42), 42 * MICRO_LAMPORTS_PER_LAMPORT),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 42,
|
|
|
|
priority: 1,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(420), 42 * MICRO_LAMPORTS_PER_LAMPORT),
|
|
|
|
FeeDetails {
|
|
|
|
fee: 420,
|
|
|
|
priority: 10,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(
|
|
|
|
FeeType::Deprecated(u64::MAX),
|
|
|
|
2 * MICRO_LAMPORTS_PER_LAMPORT
|
|
|
|
),
|
|
|
|
FeeDetails {
|
|
|
|
fee: u64::MAX,
|
|
|
|
priority: u64::MAX / 2,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
FeeDetails::new(FeeType::Deprecated(u64::MAX), u64::MAX),
|
|
|
|
FeeDetails {
|
|
|
|
fee: u64::MAX,
|
|
|
|
priority: MICRO_LAMPORTS_PER_LAMPORT,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|