Skip to content

Commit

Permalink
add secp256r1 cost
Browse files Browse the repository at this point in the history
  • Loading branch information
samkim-crypto committed Dec 3, 2024
1 parent f454a53 commit 68e7050
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 1 deletion.
3 changes: 3 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 builtins-default-costs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ lazy_static! {
.cloned()
.collect();
}
// TODO: ask Joe on adding `secp256r1_program::id()` above

lazy_static! {
/// A table of 256 booleans indicates whether the first `u8` of a Pubkey exists in
Expand Down
2 changes: 2 additions & 0 deletions cost-model/src/block_cost_limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub const COMPUTE_UNIT_TO_US_RATIO: u64 = 30;
pub const SIGNATURE_COST: u64 = COMPUTE_UNIT_TO_US_RATIO * 24;
/// Number of compute units for one secp256k1 signature verification.
pub const SECP256K1_VERIFY_COST: u64 = COMPUTE_UNIT_TO_US_RATIO * 223;
/// Number of compute units for one secp256r1 signature verification.
pub const SECP256R1_VERIFY_COST: u64 = COMPUTE_UNIT_TO_US_RATIO * 9999; // TODO: update cost
/// Number of compute units for one ed25519 signature verification.
pub const ED25519_VERIFY_COST: u64 = COMPUTE_UNIT_TO_US_RATIO * 76;
/// Number of compute units for one ed25519 strict signature verification.
Expand Down
5 changes: 5 additions & 0 deletions cost-model/src/cost_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ impl CostModel {
.num_ed25519_instruction_signatures()
.saturating_mul(ed25519_verify_cost),
)
.saturating_add(
signatures_count_detail
.num_secp256r1_instruction_signatures()
.saturating_mul(SECP256R1_VERIFY_COST),
)
}

fn get_writable_accounts(message: &impl SVMMessage) -> impl Iterator<Item = &Pubkey> {
Expand Down
15 changes: 15 additions & 0 deletions cost-model/src/cost_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub struct CostTracker {
/// the tracker, but are still waiting for an update with actual usage or
/// removal if the transaction does not end up getting committed.
in_flight_transaction_count: usize,
secp256r1_instruction_signature_count: u64,
}

impl Default for CostTracker {
Expand All @@ -102,6 +103,7 @@ impl Default for CostTracker {
secp256k1_instruction_signature_count: 0,
ed25519_instruction_signature_count: 0,
in_flight_transaction_count: 0,
secp256r1_instruction_signature_count: 0,
}
}
}
Expand All @@ -127,6 +129,7 @@ impl CostTracker {
self.secp256k1_instruction_signature_count = 0;
self.ed25519_instruction_signature_count = 0;
self.in_flight_transaction_count = 0;
self.secp256r1_instruction_signature_count = 0;
}

/// allows to adjust limits initiated during construction
Expand Down Expand Up @@ -256,6 +259,11 @@ impl CostTracker {
self.in_flight_transaction_count,
i64
),
(
"secp256r1_instruction_signature_count",
self.secp256r1_instruction_signature_count,
i64
),
);
}

Expand Down Expand Up @@ -334,6 +342,10 @@ impl CostTracker {
self.ed25519_instruction_signature_count,
tx_cost.num_ed25519_instruction_signatures()
);
saturating_add_assign!(
self.secp256r1_instruction_signature_count,
tx_cost.num_secp256r1_instruction_signatures()
);
self.add_transaction_execution_cost(tx_cost, tx_cost.sum())
}

Expand All @@ -353,6 +365,9 @@ impl CostTracker {
self.ed25519_instruction_signature_count = self
.ed25519_instruction_signature_count
.saturating_sub(tx_cost.num_ed25519_instruction_signatures());
self.secp256r1_instruction_signature_count = self
.secp256r1_instruction_signature_count
.saturating_sub(tx_cost.num_secp256r1_instruction_signatures());
}

/// Apply additional actual execution units to cost_tracker
Expand Down
12 changes: 11 additions & 1 deletion cost-model/src/transaction_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ impl<'a, Tx: TransactionWithMeta> TransactionCost<'a, Tx> {
.num_ed25519_instruction_signatures(),
}
}

pub fn num_secp256r1_instruction_signatures(&self) -> u64 {
match self {
Self::SimpleVote { .. } => 0,
Self::Transaction(usage_cost) => usage_cost
.transaction
.signature_details()
.num_secp256r1_instruction_signatures(),
}
}
}

// costs are stored in number of 'compute unit's
Expand Down Expand Up @@ -244,7 +254,7 @@ impl solana_runtime_transaction::transaction_meta::StaticMeta for WritableKeysTr

fn signature_details(&self) -> &solana_sdk::message::TransactionSignatureDetails {
const DUMMY: solana_sdk::message::TransactionSignatureDetails =
solana_sdk::message::TransactionSignatureDetails::new(0, 0, 0);
solana_sdk::message::TransactionSignatureDetails::new(0, 0, 0, 0);
&DUMMY
}

Expand Down
3 changes: 3 additions & 0 deletions programs/sbf/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 runtime-transaction/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ solana-builtins-default-costs = { workspace = true }
solana-compute-budget = { workspace = true }
solana-pubkey = { workspace = true }
solana-sdk = { workspace = true }
solana-secp256r1-program = { workspace = true }
solana-svm-transaction = { workspace = true }
thiserror = { workspace = true }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl RuntimeTransaction<SanitizedVersionedTransaction> {
),
precompile_signature_details.num_secp256k1_instruction_signatures,
precompile_signature_details.num_ed25519_instruction_signatures,
precompile_signature_details.num_secp256r1_instruction_signatures,
);
let compute_budget_instruction_details = ComputeBudgetInstructionDetails::try_from(
sanitized_versioned_tx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl<D: TransactionData> RuntimeTransaction<SanitizedTransactionView<D>> {
u64::from(transaction.num_required_signatures()),
precompile_signature_details.num_secp256k1_instruction_signatures,
precompile_signature_details.num_ed25519_instruction_signatures,
precompile_signature_details.num_secp256r1_instruction_signatures,
);
let compute_budget_instruction_details =
ComputeBudgetInstructionDetails::try_from(transaction.program_instructions_iter())?;
Expand Down
17 changes: 17 additions & 0 deletions runtime-transaction/src/signature_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use {
pub struct PrecompileSignatureDetails {
pub num_secp256k1_instruction_signatures: u64,
pub num_ed25519_instruction_signatures: u64,
pub num_secp256r1_instruction_signatures: u64,
}

/// Get transaction signature details.
Expand All @@ -20,6 +21,7 @@ pub fn get_precompile_signature_details<'a>(
// is low enough that the sum of all signatures will not overflow a u64.
let mut num_secp256k1_instruction_signatures: u64 = 0;
let mut num_ed25519_instruction_signatures: u64 = 0;
let mut num_secp256r1_instruction_signatures: u64 = 0;
for (program_id, instruction) in instructions {
let program_id_index = instruction.program_id_index;
match filter.is_signature(program_id_index, program_id) {
Expand All @@ -32,12 +34,17 @@ pub fn get_precompile_signature_details<'a>(
num_ed25519_instruction_signatures = num_ed25519_instruction_signatures
.wrapping_add(get_num_signatures_in_instruction(&instruction));
}
ProgramIdStatus::Secp256r1 => {
num_secp256r1_instruction_signatures = num_secp256r1_instruction_signatures
.wrapping_add(get_num_signatures_in_instruction(&instruction));
}
}
}

PrecompileSignatureDetails {
num_secp256k1_instruction_signatures,
num_ed25519_instruction_signatures,
num_secp256r1_instruction_signatures,
}
}

Expand All @@ -51,6 +58,7 @@ enum ProgramIdStatus {
NotSignature,
Secp256k1,
Ed25519,
Secp256r1,
}

struct SignatureDetailsFilter {
Expand Down Expand Up @@ -86,6 +94,8 @@ impl SignatureDetailsFilter {
ProgramIdStatus::Secp256k1
} else if program_id == &solana_sdk::ed25519_program::ID {
ProgramIdStatus::Ed25519
} else if program_id == &solana_secp256r1_program::ID {
ProgramIdStatus::Secp256r1
} else {
ProgramIdStatus::NotSignature
}
Expand Down Expand Up @@ -140,34 +150,41 @@ mod tests {
Pubkey::new_unique(),
solana_sdk::secp256k1_program::ID,
solana_sdk::ed25519_program::ID,
solana_secp256r1_program::ID,
];
let instructions = [
make_instruction(&program_ids, 1, &[5]),
make_instruction(&program_ids, 2, &[3]),
make_instruction(&program_ids, 3, &[4]),
make_instruction(&program_ids, 0, &[]),
make_instruction(&program_ids, 2, &[2]),
make_instruction(&program_ids, 1, &[1]),
make_instruction(&program_ids, 0, &[]),
make_instruction(&program_ids, 3, &[3]),
];

let signature_details = get_precompile_signature_details(instructions.into_iter());
assert_eq!(signature_details.num_secp256k1_instruction_signatures, 6);
assert_eq!(signature_details.num_ed25519_instruction_signatures, 5);
assert_eq!(signature_details.num_secp256r1_instruction_signatures, 7);
}

#[test]
fn test_get_signature_details_missing_num_signatures() {
let program_ids = [
solana_sdk::secp256k1_program::ID,
solana_sdk::ed25519_program::ID,
solana_secp256r1_program::ID,
];
let instructions = [
make_instruction(&program_ids, 0, &[]),
make_instruction(&program_ids, 1, &[]),
make_instruction(&program_ids, 2, &[]),
];

let signature_details = get_precompile_signature_details(instructions.into_iter());
assert_eq!(signature_details.num_secp256k1_instruction_signatures, 0);
assert_eq!(signature_details.num_ed25519_instruction_signatures, 0);
assert_eq!(signature_details.num_secp256r1_instruction_signatures, 0);
}
}
1 change: 1 addition & 0 deletions sdk/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ solana-sanitize = { workspace = true }
solana-sdk-ids = { workspace = true }
solana-sdk-macro = { workspace = true }
solana-secp256k1-recover = { workspace = true }
solana-secp256r1-program = { workspace = true }
solana-serde-varint = { workspace = true }
solana-serialize-utils = { workspace = true }
solana-sha256-hasher = { workspace = true, features = ["sha2"] }
Expand Down
16 changes: 16 additions & 0 deletions sdk/program/src/message/sanitized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,13 @@ impl SanitizedMessage {
.num_ed25519_instruction_signatures
.saturating_add(u64::from(*num_verifies));
}
} else if solana_secp256r1_program::check_id(program_id) {
if let Some(num_verifies) = instruction.data.first() {
transaction_signature_details.num_secp256r1_instruction_signatures =
transaction_signature_details
.num_secp256r1_instruction_signatures
.saturating_add(u64::from(*num_verifies));
}
}
}

Expand All @@ -419,18 +426,21 @@ pub struct TransactionSignatureDetails {
num_transaction_signatures: u64,
num_secp256k1_instruction_signatures: u64,
num_ed25519_instruction_signatures: u64,
num_secp256r1_instruction_signatures: u64,
}

impl TransactionSignatureDetails {
pub const fn new(
num_transaction_signatures: u64,
num_secp256k1_instruction_signatures: u64,
num_ed25519_instruction_signatures: u64,
num_secp256r1_instruction_signatures: u64,
) -> Self {
Self {
num_transaction_signatures,
num_secp256k1_instruction_signatures,
num_ed25519_instruction_signatures,
num_secp256r1_instruction_signatures,
}
}

Expand All @@ -439,6 +449,7 @@ impl TransactionSignatureDetails {
self.num_transaction_signatures
.saturating_add(self.num_secp256k1_instruction_signatures)
.saturating_add(self.num_ed25519_instruction_signatures)
.saturating_add(self.num_secp256r1_instruction_signatures)
}

/// return the number of transaction signatures
Expand All @@ -455,6 +466,11 @@ impl TransactionSignatureDetails {
pub fn num_ed25519_instruction_signatures(&self) -> u64 {
self.num_ed25519_instruction_signatures
}

/// return the number of secp256r1 instruction signatures
pub fn num_secp256r1_instruction_signatures(&self) -> u64 {
self.num_secp256r1_instruction_signatures
}
}

#[cfg(test)]
Expand Down
3 changes: 3 additions & 0 deletions svm/examples/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 transaction-view/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ edition = { workspace = true }

[dependencies]
solana-sdk = { workspace = true }
solana-secp256r1-program = { workspace = true }
solana-svm-transaction = { workspace = true }

[dev-dependencies]
Expand Down
Loading

0 comments on commit 68e7050

Please sign in to comment.