Port instructions sysvar and secp256k1 program activation to FeatureSet
This commit is contained in:
@ -19,9 +19,16 @@ impl Default for FeeCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FeeConfig {
|
||||
pub is_secp256k1_enabled: bool,
|
||||
pub secp256k1_program_enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for FeeConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
secp256k1_program_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FeeCalculator {
|
||||
@ -31,27 +38,27 @@ impl FeeCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
// extra_config: None == everything enabled
|
||||
pub fn calculate_fee(&self, message: &Message, extra_config: Option<FeeConfig>) -> u64 {
|
||||
let is_secp256k1_enabled = match extra_config {
|
||||
Some(config) => config.is_secp256k1_enabled,
|
||||
None => true,
|
||||
};
|
||||
let mut num_secp_signatures: u64 = 0;
|
||||
if is_secp256k1_enabled {
|
||||
pub fn calculate_fee(&self, message: &Message) -> u64 {
|
||||
self.calculate_fee_with_config(message, &FeeConfig::default())
|
||||
}
|
||||
|
||||
pub fn calculate_fee_with_config(&self, message: &Message, fee_config: &FeeConfig) -> u64 {
|
||||
let mut num_secp256k1_signatures: u64 = 0;
|
||||
if fee_config.secp256k1_program_enabled {
|
||||
for instruction in &message.instructions {
|
||||
let program_index = instruction.program_id_index as usize;
|
||||
// Transaction may not be sanitized here
|
||||
if program_index < message.account_keys.len() {
|
||||
let id = message.account_keys[program_index];
|
||||
if secp256k1_program::check_id(&id) && !instruction.data.is_empty() {
|
||||
num_secp_signatures += instruction.data[0] as u64;
|
||||
num_secp256k1_signatures += instruction.data[0] as u64;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.lamports_per_signature
|
||||
* (u64::from(message.header.num_required_signatures) + num_secp_signatures)
|
||||
* (u64::from(message.header.num_required_signatures) + num_secp256k1_signatures)
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,9 +189,7 @@ impl FeeRateGovernor {
|
||||
|
||||
/// create a FeeCalculator based on current cluster signature throughput
|
||||
pub fn create_fee_calculator(&self) -> FeeCalculator {
|
||||
FeeCalculator {
|
||||
lamports_per_signature: self.lamports_per_signature,
|
||||
}
|
||||
FeeCalculator::new(self.lamports_per_signature)
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,34 +212,25 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_fee_calculator_calculate_fee() {
|
||||
let fee_config = Some(FeeConfig {
|
||||
is_secp256k1_enabled: true,
|
||||
});
|
||||
// Default: no fee.
|
||||
let message = Message::default();
|
||||
assert_eq!(
|
||||
FeeCalculator::default().calculate_fee(&message, fee_config.clone()),
|
||||
0
|
||||
);
|
||||
assert_eq!(FeeCalculator::default().calculate_fee(&message), 0);
|
||||
|
||||
// No signature, no fee.
|
||||
assert_eq!(FeeCalculator::new(1).calculate_fee(&message, fee_config), 0);
|
||||
assert_eq!(FeeCalculator::new(1).calculate_fee(&message), 0);
|
||||
|
||||
let fee_config = Some(FeeConfig {
|
||||
is_secp256k1_enabled: false,
|
||||
});
|
||||
// One signature, a fee.
|
||||
let pubkey0 = Pubkey::new(&[0; 32]);
|
||||
let pubkey1 = Pubkey::new(&[1; 32]);
|
||||
let ix0 = system_instruction::transfer(&pubkey0, &pubkey1, 1);
|
||||
let message = Message::new(&[ix0], Some(&pubkey0));
|
||||
assert_eq!(FeeCalculator::new(2).calculate_fee(&message, fee_config), 2);
|
||||
assert_eq!(FeeCalculator::new(2).calculate_fee(&message), 2);
|
||||
|
||||
// Two signatures, double the fee.
|
||||
let ix0 = system_instruction::transfer(&pubkey0, &pubkey1, 1);
|
||||
let ix1 = system_instruction::transfer(&pubkey1, &pubkey0, 1);
|
||||
let message = Message::new(&[ix0, ix1], Some(&pubkey0));
|
||||
assert_eq!(FeeCalculator::new(2).calculate_fee(&message, None), 4);
|
||||
assert_eq!(FeeCalculator::new(2).calculate_fee(&message), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -262,21 +258,21 @@ mod tests {
|
||||
],
|
||||
Some(&pubkey0),
|
||||
);
|
||||
let fee_config = Some(FeeConfig {
|
||||
is_secp256k1_enabled: true,
|
||||
});
|
||||
assert_eq!(FeeCalculator::new(1).calculate_fee(&message), 2);
|
||||
assert_eq!(
|
||||
FeeCalculator::new(1).calculate_fee(&message, fee_config.clone()),
|
||||
2
|
||||
FeeCalculator::new(1).calculate_fee_with_config(
|
||||
&message,
|
||||
&FeeConfig {
|
||||
secp256k1_program_enabled: false
|
||||
}
|
||||
),
|
||||
1
|
||||
);
|
||||
|
||||
secp_instruction.data = vec![0];
|
||||
secp_instruction2.data = vec![10];
|
||||
let message = Message::new(&[ix0, secp_instruction, secp_instruction2], Some(&pubkey0));
|
||||
assert_eq!(
|
||||
FeeCalculator::new(1).calculate_fee(&message, fee_config),
|
||||
11
|
||||
);
|
||||
assert_eq!(FeeCalculator::new(1).calculate_fee(&message), 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,28 +1,6 @@
|
||||
use crate::clock::{Epoch, GENESIS_EPOCH};
|
||||
use crate::fee_calculator::FeeConfig;
|
||||
use crate::genesis_config::ClusterType;
|
||||
use digest::Digest;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
pub fn get_fee_config(cluster_type: ClusterType, epoch: Epoch) -> Option<FeeConfig> {
|
||||
Some(FeeConfig {
|
||||
is_secp256k1_enabled: is_enabled(cluster_type, epoch),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_enabled_epoch(cluster_type: ClusterType) -> Epoch {
|
||||
match cluster_type {
|
||||
ClusterType::Development => GENESIS_EPOCH,
|
||||
ClusterType::Testnet => u64::MAX,
|
||||
ClusterType::MainnetBeta => u64::MAX,
|
||||
ClusterType::Devnet => u64::MAX,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_enabled(cluster_type: ClusterType, epoch: Epoch) -> bool {
|
||||
epoch >= is_enabled_epoch(cluster_type)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Secp256k1Error {
|
||||
InvalidSignature,
|
||||
|
@ -11,16 +11,6 @@ crate::declare_sysvar_id!("Sysvar1nstructions1111111111111111111111111", Instruc
|
||||
|
||||
impl Sysvar for Instructions {}
|
||||
|
||||
#[cfg(not(feature = "program"))]
|
||||
use crate::clock::Epoch;
|
||||
#[cfg(not(feature = "program"))]
|
||||
use crate::genesis_config::ClusterType;
|
||||
|
||||
#[cfg(not(feature = "program"))]
|
||||
pub fn is_enabled(_epoch: Epoch, cluster_type: ClusterType) -> bool {
|
||||
cluster_type == ClusterType::Development
|
||||
}
|
||||
|
||||
pub fn load_current_index(data: &[u8]) -> u16 {
|
||||
let mut instr_fixed_data = [0u8; 2];
|
||||
let len = data.len();
|
||||
|
Reference in New Issue
Block a user