Divorce the runtime from FeeCalculator (#20737)

This commit is contained in:
Jack May
2021-10-22 14:32:40 -07:00
committed by GitHub
parent 613c7b8444
commit bfbbc53dac
24 changed files with 503 additions and 563 deletions

View File

@ -5,8 +5,6 @@ use {
message::{MappedAddresses, MappedMessage, Message, MessageHeader},
pubkey::Pubkey,
sanitize::{Sanitize, SanitizeError},
secp256k1_program,
ed25519_program,
serialize_utils::{append_slice, append_u16, append_u8},
},
bitflags::bitflags,
@ -291,21 +289,6 @@ impl SanitizedMessage {
})
}
/// Calculate the total fees for a transaction given a fee calculator
pub fn calculate_fee(&self, lamports_per_signature: u64) -> u64 {
let mut num_signatures = u64::from(self.header().num_required_signatures);
for (program_id, instruction) in self.program_instructions_iter() {
if secp256k1_program::check_id(program_id) || ed25519_program::check_id(program_id) {
if let Some(num_verifies) = instruction.data.get(0) {
num_signatures =
num_signatures.saturating_add(u64::from(*num_verifies));
}
}
}
lamports_per_signature.saturating_mul(num_signatures)
}
/// Inspect all message keys for the bpf upgradeable loader
pub fn is_upgradeable_loader_present(&self) -> bool {
match self {
@ -321,7 +304,6 @@ mod tests {
use crate::{
instruction::{AccountMeta, Instruction},
message::v0,
secp256k1_program, system_instruction,
};
#[test]
@ -460,25 +442,6 @@ mod tests {
}
}
#[test]
fn test_calculate_fee() {
// Default: no fee.
let message =
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
assert_eq!(message.calculate_fee(0), 0);
// One signature, a fee.
assert_eq!(message.calculate_fee(1), 1);
// Two signatures, double the fee.
let key0 = Pubkey::new_unique();
let key1 = Pubkey::new_unique();
let ix0 = system_instruction::transfer(&key0, &key1, 1);
let ix1 = system_instruction::transfer(&key1, &key0, 1);
let message = SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&key0))).unwrap();
assert_eq!(message.calculate_fee(2), 4);
}
#[test]
fn test_try_compile_instruction() {
let key0 = Pubkey::new_unique();
@ -561,80 +524,4 @@ mod tests {
.is_none());
}
}
#[test]
fn test_calculate_fee_secp256k1() {
let key0 = Pubkey::new_unique();
let key1 = Pubkey::new_unique();
let ix0 = system_instruction::transfer(&key0, &key1, 1);
let mut secp_instruction1 = Instruction {
program_id: secp256k1_program::id(),
accounts: vec![],
data: vec![],
};
let mut secp_instruction2 = Instruction {
program_id: secp256k1_program::id(),
accounts: vec![],
data: vec![1],
};
let message = SanitizedMessage::try_from(Message::new(
&[
ix0.clone(),
secp_instruction1.clone(),
secp_instruction2.clone(),
],
Some(&key0),
))
.unwrap();
assert_eq!(message.calculate_fee(1), 2);
secp_instruction1.data = vec![0];
secp_instruction2.data = vec![10];
let message = SanitizedMessage::try_from(Message::new(
&[ix0, secp_instruction1, secp_instruction2],
Some(&key0),
))
.unwrap();
assert_eq!(message.calculate_fee(1), 11);
}
#[test]
fn test_calculate_fee_ed25519() {
let key0 = Pubkey::new_unique();
let key1 = Pubkey::new_unique();
let ix0 = system_instruction::transfer(&key0, &key1, 1);
let mut instruction1 = Instruction {
program_id: ed25519_program::id(),
accounts: vec![],
data: vec![],
};
let mut instruction2 = Instruction {
program_id: ed25519_program::id(),
accounts: vec![],
data: vec![1],
};
let message = SanitizedMessage::try_from(Message::new(
&[
ix0.clone(),
instruction1.clone(),
instruction2.clone(),
],
Some(&key0),
))
.unwrap();
assert_eq!(message.calculate_fee(1), 2);
instruction1.data = vec![0];
instruction2.data = vec![10];
let message = SanitizedMessage::try_from(Message::new(
&[ix0, instruction1, instruction2],
Some(&key0),
))
.unwrap();
assert_eq!(message.calculate_fee(1), 11);
}
}

View File

@ -9,6 +9,19 @@ pub struct Data {
pub fee_calculator: FeeCalculator,
}
impl Data {
pub fn new(authority: Pubkey, blockhash: Hash, lamports_per_signature: u64) -> Self {
Data {
authority,
blockhash,
fee_calculator: FeeCalculator::new(lamports_per_signature),
}
}
pub fn get_lamports_per_signature(&self) -> u64 {
self.fee_calculator.lamports_per_signature
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub enum State {
Uninitialized,

View File

@ -30,10 +30,10 @@ pub struct Entry {
pub fee_calculator: FeeCalculator,
}
impl Entry {
pub fn new(blockhash: &Hash, fee_calculator: &FeeCalculator) -> Self {
pub fn new(blockhash: &Hash, lamports_per_signature: u64) -> Self {
Self {
blockhash: *blockhash,
fee_calculator: fee_calculator.clone(),
fee_calculator: FeeCalculator::new(lamports_per_signature),
}
}
}
@ -43,7 +43,7 @@ impl Entry {
note = "Please do not use, will no longer be available in the future"
)]
#[derive(Clone, Debug)]
pub struct IterItem<'a>(pub u64, pub &'a Hash, pub &'a FeeCalculator);
pub struct IterItem<'a>(pub u64, pub &'a Hash, pub u64);
impl<'a> Eq for IterItem<'a> {}
@ -149,13 +149,13 @@ pub fn create_test_recent_blockhashes(start: usize) -> RecentBlockhashes {
(
i as u64,
hash(&bincode::serialize(&i).unwrap()),
FeeCalculator::new(i as u64 * 100),
i as u64 * 100,
)
})
.collect();
blocks
.iter()
.map(|(i, hash, fee_calc)| IterItem(*i, hash, fee_calc))
.map(|(i, hash, lamports_per_signature)| IterItem(*i, hash, *lamports_per_signature))
.collect()
}
@ -173,7 +173,7 @@ mod tests {
#[test]
fn test_size_of() {
let entry = Entry::new(&Hash::default(), &FeeCalculator::default());
let entry = Entry::new(&Hash::default(), 0);
assert_eq!(
bincode::serialized_size(&RecentBlockhashes(vec![entry; MAX_ENTRIES])).unwrap()
as usize,