Gate libsecp256k1 update (backport #18656) (#18700)

* hijack secp256k1 enablement feature plumbing for libsecp256k1 upgrade

* Bump libsecp256k1 to v0.5.0

* gate libsecp256k1 upgrade to v0.5.0

Co-authored-by: Trent Nelson <trent@solana.com>
This commit is contained in:
mergify[bot]
2021-07-16 03:34:13 +00:00
committed by GitHub
parent e15721f22d
commit 63d7fdb4bd
19 changed files with 208 additions and 194 deletions

54
Cargo.lock generated
View File

@ -1760,13 +1760,13 @@ dependencies = [
[[package]] [[package]]
name = "hmac-drbg" name = "hmac-drbg"
version = "0.2.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1"
dependencies = [ dependencies = [
"digest 0.8.1", "digest 0.9.0",
"generic-array 0.12.3", "generic-array 0.14.3",
"hmac 0.7.1", "hmac 0.8.1",
] ]
[[package]] [[package]]
@ -2298,20 +2298,52 @@ dependencies = [
[[package]] [[package]]
name = "libsecp256k1" name = "libsecp256k1"
version = "0.3.5" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" checksum = "bd1137239ab33b41aa9637a88a28249e5e70c40a42ccc92db7f12cc356c1fcd7"
dependencies = [ dependencies = [
"arrayref", "arrayref",
"crunchy", "base64 0.12.3",
"digest 0.8.1", "digest 0.9.0",
"hmac-drbg", "hmac-drbg",
"libsecp256k1-core",
"libsecp256k1-gen-ecmult",
"libsecp256k1-gen-genmult",
"rand 0.7.3", "rand 0.7.3",
"sha2 0.8.2", "serde",
"subtle 2.2.2", "sha2 0.9.2",
"typenum", "typenum",
] ]
[[package]]
name = "libsecp256k1-core"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee11012b293ea30093c129173cac4335513064094619f4639a25b310fd33c11"
dependencies = [
"crunchy",
"digest 0.9.0",
"subtle 2.2.2",
]
[[package]]
name = "libsecp256k1-gen-ecmult"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32239626ffbb6a095b83b37a02ceb3672b2443a87a000a884fc3c4d16925c9c0"
dependencies = [
"libsecp256k1-core",
]
[[package]]
name = "libsecp256k1-gen-genmult"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76acb433e21d10f5f9892b1962c2856c58c7f39a9e4bd68ac82b9436a0ffd5b9"
dependencies = [
"libsecp256k1-core",
]
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
version = "0.5.3" version = "0.5.3"

View File

@ -131,10 +131,13 @@ impl BanksServer {
} }
} }
fn verify_transaction(transaction: &Transaction) -> transaction::Result<()> { fn verify_transaction(
transaction: &Transaction,
libsecp256k1_0_5_upgrade_enabled: bool,
) -> transaction::Result<()> {
if let Err(err) = transaction.verify() { if let Err(err) = transaction.verify() {
Err(err) Err(err)
} else if let Err(err) = transaction.verify_precompiles() { } else if let Err(err) = transaction.verify_precompiles(libsecp256k1_0_5_upgrade_enabled) {
Err(err) Err(err)
} else { } else {
Ok(()) Ok(())
@ -215,7 +218,10 @@ impl Banks for BanksServer {
transaction: Transaction, transaction: Transaction,
commitment: CommitmentLevel, commitment: CommitmentLevel,
) -> Option<transaction::Result<()>> { ) -> Option<transaction::Result<()>> {
if let Err(err) = verify_transaction(&transaction) { if let Err(err) = verify_transaction(
&transaction,
self.bank(commitment).libsecp256k1_0_5_upgrade_enabled(),
) {
return Some(Err(err)); return Some(Err(err));
} }

View File

@ -985,16 +985,15 @@ impl BankingStage {
fn transactions_from_packets( fn transactions_from_packets(
msgs: &Packets, msgs: &Packets,
transaction_indexes: &[usize], transaction_indexes: &[usize],
secp256k1_program_enabled: bool, libsecp256k1_0_5_upgrade_enabled: bool,
) -> (Vec<HashedTransaction<'static>>, Vec<usize>) { ) -> (Vec<HashedTransaction<'static>>, Vec<usize>) {
transaction_indexes transaction_indexes
.iter() .iter()
.filter_map(|tx_index| { .filter_map(|tx_index| {
let p = &msgs.packets[*tx_index]; let p = &msgs.packets[*tx_index];
let tx: Transaction = limited_deserialize(&p.data[0..p.meta.size]).ok()?; let tx: Transaction = limited_deserialize(&p.data[0..p.meta.size]).ok()?;
if secp256k1_program_enabled { tx.verify_precompiles(libsecp256k1_0_5_upgrade_enabled)
tx.verify_precompiles().ok()?; .ok()?;
}
let message_bytes = Self::packet_message(p)?; let message_bytes = Self::packet_message(p)?;
let message_hash = Message::hash_raw_message(message_bytes); let message_hash = Message::hash_raw_message(message_bytes);
Some(( Some((
@ -1058,7 +1057,7 @@ impl BankingStage {
let (transactions, transaction_to_packet_indexes) = Self::transactions_from_packets( let (transactions, transaction_to_packet_indexes) = Self::transactions_from_packets(
msgs, msgs,
&packet_indexes, &packet_indexes,
bank.secp256k1_program_enabled(), bank.libsecp256k1_0_5_upgrade_enabled(),
); );
packet_conversion_time.stop(); packet_conversion_time.stop();
@ -1129,7 +1128,7 @@ impl BankingStage {
let (transactions, transaction_to_packet_indexes) = Self::transactions_from_packets( let (transactions, transaction_to_packet_indexes) = Self::transactions_from_packets(
msgs, msgs,
&transaction_indexes, &transaction_indexes,
bank.secp256k1_program_enabled(), bank.libsecp256k1_0_5_upgrade_enabled(),
); );
let tx_count = transaction_to_packet_indexes.len(); let tx_count = transaction_to_packet_indexes.len();

View File

@ -246,7 +246,7 @@ mod tests {
..GenesisConfig::default() ..GenesisConfig::default()
}; };
let mut bank = Arc::new(Bank::new(&genesis_config)); let mut bank = Arc::new(Bank::new(&genesis_config));
let sysvar_and_native_program_delta = 10; let sysvar_and_native_program_delta = 11;
assert_eq!( assert_eq!(
bank.capitalization(), bank.capitalization(),
(num_genesis_accounts + num_non_circulating_accounts + num_stake_accounts) * balance (num_genesis_accounts + num_non_circulating_accounts + num_stake_accounts) * balance

View File

@ -1870,12 +1870,15 @@ impl JsonRpcRequestProcessor {
} }
} }
fn verify_transaction(transaction: &Transaction) -> Result<()> { fn verify_transaction(
transaction: &Transaction,
libsecp256k1_0_5_upgrade_enabled: bool,
) -> Result<()> {
if transaction.verify().is_err() { if transaction.verify().is_err() {
return Err(RpcCustomError::TransactionSignatureVerificationFailure.into()); return Err(RpcCustomError::TransactionSignatureVerificationFailure.into());
} }
if let Err(e) = transaction.verify_precompiles() { if let Err(e) = transaction.verify_precompiles(libsecp256k1_0_5_upgrade_enabled) {
return Err(RpcCustomError::TransactionPrecompileVerificationFailure(e).into()); return Err(RpcCustomError::TransactionPrecompileVerificationFailure(e).into());
} }
@ -3138,7 +3141,10 @@ pub mod rpc_full {
} }
if !config.skip_preflight { if !config.skip_preflight {
if let Err(e) = verify_transaction(&transaction) { if let Err(e) = verify_transaction(
&transaction,
preflight_bank.libsecp256k1_0_5_upgrade_enabled(),
) {
return Err(e); return Err(e);
} }
@ -3201,6 +3207,7 @@ pub mod rpc_full {
let encoding = config.encoding.unwrap_or(UiTransactionEncoding::Base58); let encoding = config.encoding.unwrap_or(UiTransactionEncoding::Base58);
let (_, mut transaction) = deserialize_transaction(data, encoding)?; let (_, mut transaction) = deserialize_transaction(data, encoding)?;
let bank = &*meta.bank(config.commitment);
if config.sig_verify { if config.sig_verify {
if config.replace_recent_blockhash { if config.replace_recent_blockhash {
return Err(Error::invalid_params( return Err(Error::invalid_params(
@ -3208,11 +3215,12 @@ pub mod rpc_full {
)); ));
} }
if let Err(e) = verify_transaction(&transaction) { if let Err(e) =
verify_transaction(&transaction, bank.libsecp256k1_0_5_upgrade_enabled())
{
return Err(e); return Err(e);
} }
} }
let bank = &*meta.bank(config.commitment);
if config.replace_recent_blockhash { if config.replace_recent_blockhash {
transaction.message.recent_blockhash = bank.last_blockhash(); transaction.message.recent_blockhash = bank.last_blockhash();
} }

View File

@ -2284,13 +2284,13 @@ fn main() {
let mut store_failed_count = 0; let mut store_failed_count = 0;
if force_enabled_count >= 1 { if force_enabled_count >= 1 {
if base_bank if base_bank
.get_account(&feature_set::secp256k1_program_enabled::id()) .get_account(&feature_set::spl_token_v2_multisig_fix::id())
.is_some() .is_some()
{ {
// steal some lamports from the pretty old feature not to affect // steal some lamports from the pretty old feature not to affect
// capitalizaion, which doesn't affect inflation behavior! // capitalizaion, which doesn't affect inflation behavior!
base_bank.store_account( base_bank.store_account(
&feature_set::secp256k1_program_enabled::id(), &feature_set::spl_token_v2_multisig_fix::id(),
&AccountSharedData::default(), &AccountSharedData::default(),
); );
force_enabled_count -= 1; force_enabled_count -= 1;

View File

@ -752,8 +752,8 @@ pub fn confirm_slot(
}; };
let check_start = Instant::now(); let check_start = Instant::now();
let check_result = let check_result = entries
entries.verify_and_hash_transactions(skip_verification, bank.secp256k1_program_enabled()); .verify_and_hash_transactions(skip_verification, bank.libsecp256k1_0_5_upgrade_enabled());
if check_result.is_none() { if check_result.is_none() {
warn!("Ledger proof of history failed at slot: {}", slot); warn!("Ledger proof of history failed at slot: {}", slot);
return Err(BlockError::InvalidEntryHash.into()); return Err(BlockError::InvalidEntryHash.into());

View File

@ -367,7 +367,7 @@ pub trait EntrySlice {
fn verify_and_hash_transactions( fn verify_and_hash_transactions(
&self, &self,
skip_verification: bool, skip_verification: bool,
secp256k1_program_enabled: bool, libsecp256k1_0_5_upgrade_enabled: bool,
) -> Option<Vec<EntryType<'_>>>; ) -> Option<Vec<EntryType<'_>>>;
} }
@ -522,7 +522,7 @@ impl EntrySlice for [Entry] {
fn verify_and_hash_transactions<'a>( fn verify_and_hash_transactions<'a>(
&'a self, &'a self,
skip_verification: bool, skip_verification: bool,
secp256k1_program_enabled: bool, libsecp256k1_0_5_upgrade_enabled: bool,
) -> Option<Vec<EntryType<'a>>> { ) -> Option<Vec<EntryType<'a>>> {
let verify_and_hash = |tx: &'a Transaction| -> Option<HashedTransaction<'a>> { let verify_and_hash = |tx: &'a Transaction| -> Option<HashedTransaction<'a>> {
let message_hash = if !skip_verification { let message_hash = if !skip_verification {
@ -530,10 +530,8 @@ impl EntrySlice for [Entry] {
if size > PACKET_DATA_SIZE as u64 { if size > PACKET_DATA_SIZE as u64 {
return None; return None;
} }
if secp256k1_program_enabled { tx.verify_precompiles(libsecp256k1_0_5_upgrade_enabled)
// Verify tx precompiles if secp256k1 program is enabled. .ok()?;
tx.verify_precompiles().ok()?;
}
tx.verify_and_hash_message().ok()? tx.verify_and_hash_message().ok()?
} else { } else {
tx.message().hash() tx.message().hash()

118
programs/bpf/Cargo.lock generated
View File

@ -647,16 +647,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-mac"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
dependencies = [
"generic-array 0.12.3",
"subtle 1.0.0",
]
[[package]] [[package]]
name = "crypto-mac" name = "crypto-mac"
version = "0.8.0" version = "0.8.0"
@ -664,7 +654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
dependencies = [ dependencies = [
"generic-array 0.14.3", "generic-array 0.14.3",
"subtle 2.2.2", "subtle",
] ]
[[package]] [[package]]
@ -674,7 +664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca" checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca"
dependencies = [ dependencies = [
"generic-array 0.14.3", "generic-array 0.14.3",
"subtle 2.2.2", "subtle",
] ]
[[package]] [[package]]
@ -684,7 +674,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6"
dependencies = [ dependencies = [
"generic-array 0.14.3", "generic-array 0.14.3",
"subtle 2.2.2", "subtle",
] ]
[[package]] [[package]]
@ -696,7 +686,7 @@ dependencies = [
"byteorder 1.3.4", "byteorder 1.3.4",
"digest 0.8.1", "digest 0.8.1",
"rand_core 0.5.1", "rand_core 0.5.1",
"subtle 2.2.2", "subtle",
"zeroize", "zeroize",
] ]
@ -709,7 +699,7 @@ dependencies = [
"byteorder 1.3.4", "byteorder 1.3.4",
"digest 0.9.0", "digest 0.9.0",
"rand_core 0.5.1", "rand_core 0.5.1",
"subtle 2.2.2", "subtle",
"zeroize", "zeroize",
] ]
@ -830,7 +820,7 @@ dependencies = [
"rand 0.7.3", "rand 0.7.3",
"serde", "serde",
"serde_bytes", "serde_bytes",
"sha2 0.9.2", "sha2",
"zeroize", "zeroize",
] ]
@ -844,7 +834,7 @@ dependencies = [
"ed25519-dalek", "ed25519-dalek",
"failure", "failure",
"hmac 0.9.0", "hmac 0.9.0",
"sha2 0.9.2", "sha2",
] ]
[[package]] [[package]]
@ -1265,16 +1255,6 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "hmac"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
dependencies = [
"crypto-mac 0.7.0",
"digest 0.8.1",
]
[[package]] [[package]]
name = "hmac" name = "hmac"
version = "0.8.1" version = "0.8.1"
@ -1307,13 +1287,13 @@ dependencies = [
[[package]] [[package]]
name = "hmac-drbg" name = "hmac-drbg"
version = "0.2.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1"
dependencies = [ dependencies = [
"digest 0.8.1", "digest 0.9.0",
"generic-array 0.12.3", "generic-array 0.14.3",
"hmac 0.7.1", "hmac 0.8.1",
] ]
[[package]] [[package]]
@ -1589,20 +1569,52 @@ dependencies = [
[[package]] [[package]]
name = "libsecp256k1" name = "libsecp256k1"
version = "0.3.5" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" checksum = "bd1137239ab33b41aa9637a88a28249e5e70c40a42ccc92db7f12cc356c1fcd7"
dependencies = [ dependencies = [
"arrayref", "arrayref",
"crunchy", "base64 0.12.3",
"digest 0.8.1", "digest 0.9.0",
"hmac-drbg", "hmac-drbg",
"libsecp256k1-core",
"libsecp256k1-gen-ecmult",
"libsecp256k1-gen-genmult",
"rand 0.7.3", "rand 0.7.3",
"sha2 0.8.2", "serde",
"subtle 2.2.2", "sha2",
"typenum", "typenum",
] ]
[[package]]
name = "libsecp256k1-core"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee11012b293ea30093c129173cac4335513064094619f4639a25b310fd33c11"
dependencies = [
"crunchy",
"digest 0.9.0",
"subtle",
]
[[package]]
name = "libsecp256k1-gen-ecmult"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32239626ffbb6a095b83b37a02ceb3672b2443a87a000a884fc3c4d16925c9c0"
dependencies = [
"libsecp256k1-core",
]
[[package]]
name = "libsecp256k1-gen-genmult"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76acb433e21d10f5f9892b1962c2856c58c7f39a9e4bd68ac82b9436a0ffd5b9"
dependencies = [
"libsecp256k1-core",
]
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
version = "0.5.4" version = "0.5.4"
@ -2720,18 +2732,6 @@ dependencies = [
"opaque-debug 0.2.3", "opaque-debug 0.2.3",
] ]
[[package]]
name = "sha2"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
dependencies = [
"block-buffer 0.7.3",
"digest 0.8.1",
"fake-simd",
"opaque-debug 0.2.3",
]
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.9.2" version = "0.9.2"
@ -3327,7 +3327,7 @@ dependencies = [
"rustc_version", "rustc_version",
"serde", "serde",
"serde_derive", "serde_derive",
"sha2 0.9.2", "sha2",
"solana-frozen-abi-macro 1.6.17", "solana-frozen-abi-macro 1.6.17",
"solana-logger 1.6.17", "solana-logger 1.6.17",
"thiserror", "thiserror",
@ -3347,7 +3347,7 @@ dependencies = [
"rustc_version", "rustc_version",
"serde", "serde",
"serde_derive", "serde_derive",
"sha2 0.9.2", "sha2",
"solana-frozen-abi-macro 1.7.1", "solana-frozen-abi-macro 1.7.1",
"solana-logger 1.7.1", "solana-logger 1.7.1",
"thiserror", "thiserror",
@ -3461,7 +3461,7 @@ dependencies = [
"serde", "serde",
"serde_bytes", "serde_bytes",
"serde_derive", "serde_derive",
"sha2 0.9.2", "sha2",
"sha3", "sha3",
"solana-frozen-abi 1.6.17", "solana-frozen-abi 1.6.17",
"solana-frozen-abi-macro 1.6.17", "solana-frozen-abi-macro 1.6.17",
@ -3495,7 +3495,7 @@ dependencies = [
"serde", "serde",
"serde_bytes", "serde_bytes",
"serde_derive", "serde_derive",
"sha2 0.9.2", "sha2",
"sha3", "sha3",
"solana-frozen-abi 1.7.1", "solana-frozen-abi 1.7.1",
"solana-frozen-abi-macro 1.7.1", "solana-frozen-abi-macro 1.7.1",
@ -3639,7 +3639,7 @@ dependencies = [
"serde_bytes", "serde_bytes",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"sha2 0.9.2", "sha2",
"sha3", "sha3",
"solana-crate-features", "solana-crate-features",
"solana-frozen-abi 1.6.17", "solana-frozen-abi 1.6.17",
@ -3839,12 +3839,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "subtle"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.2.2" version = "2.2.2"
@ -4037,7 +4031,7 @@ dependencies = [
"pbkdf2 0.4.0", "pbkdf2 0.4.0",
"rand 0.7.3", "rand 0.7.3",
"rustc-hash", "rustc-hash",
"sha2 0.9.2", "sha2",
"thiserror", "thiserror",
"unicode-normalization", "unicode-normalization",
"zeroize", "zeroize",

View File

@ -11,7 +11,7 @@ edition = "2018"
[dependencies] [dependencies]
solana-sdk = { path = "../../sdk", version = "=1.6.17" } solana-sdk = { path = "../../sdk", version = "=1.6.17" }
libsecp256k1 = "0.3.5" libsecp256k1 = "0.5.0"
sha3 = "0.9.1" sha3 = "0.9.1"
digest = "0.9.0" digest = "0.9.0"
bincode = "1.3.1" bincode = "1.3.1"

View File

@ -34,7 +34,7 @@ pub mod test {
SIGNATURE_OFFSETS_SERIALIZED_SIZE SIGNATURE_OFFSETS_SERIALIZED_SIZE
); );
let secp_privkey = secp256k1::SecretKey::random(&mut thread_rng()); let secp_privkey = libsecp256k1::SecretKey::random(&mut thread_rng());
let message_arr = b"hello"; let message_arr = b"hello";
let mut secp_instruction = new_secp256k1_instruction(&secp_privkey, message_arr); let mut secp_instruction = new_secp256k1_instruction(&secp_privkey, message_arr);
let mint_keypair = Keypair::new(); let mint_keypair = Keypair::new();
@ -46,7 +46,7 @@ pub mod test {
Hash::default(), Hash::default(),
); );
assert!(tx.verify_precompiles().is_ok()); assert!(tx.verify_precompiles(false).is_ok());
let index = thread_rng().gen_range(0, secp_instruction.data.len()); let index = thread_rng().gen_range(0, secp_instruction.data.len());
secp_instruction.data[index] = secp_instruction.data[index].wrapping_add(12); secp_instruction.data[index] = secp_instruction.data[index].wrapping_add(12);
@ -56,6 +56,6 @@ pub mod test {
&[&mint_keypair], &[&mint_keypair],
Hash::default(), Hash::default(),
); );
assert!(tx.verify_precompiles().is_err()); assert!(tx.verify_precompiles(false).is_err());
} }
} }

View File

@ -21,7 +21,7 @@ use solana_sdk::{
bpf_loader_upgradeable::{self, UpgradeableLoaderState}, bpf_loader_upgradeable::{self, UpgradeableLoaderState},
clock::{Slot, INITIAL_RENT_EPOCH}, clock::{Slot, INITIAL_RENT_EPOCH},
feature_set::{self, FeatureSet}, feature_set::{self, FeatureSet},
fee_calculator::{FeeCalculator, FeeConfig}, fee_calculator::FeeCalculator,
genesis_config::ClusterType, genesis_config::ClusterType,
hash::Hash, hash::Hash,
message::Message, message::Message,
@ -407,10 +407,6 @@ impl Accounts {
rent_collector: &RentCollector, rent_collector: &RentCollector,
feature_set: &FeatureSet, feature_set: &FeatureSet,
) -> Vec<TransactionLoadResult> { ) -> Vec<TransactionLoadResult> {
let fee_config = FeeConfig {
secp256k1_program_enabled: feature_set
.is_active(&feature_set::secp256k1_program_enabled::id()),
};
txs.zip(lock_results) txs.zip(lock_results)
.map(|etx| match etx { .map(|etx| match etx {
(tx, (Ok(()), nonce_rollback)) => { (tx, (Ok(()), nonce_rollback)) => {
@ -423,7 +419,7 @@ impl Accounts {
.cloned() .cloned()
}); });
let fee = if let Some(fee_calculator) = fee_calculator { let fee = if let Some(fee_calculator) = fee_calculator {
fee_calculator.calculate_fee_with_config(tx.message(), &fee_config) fee_calculator.calculate_fee(tx.message())
} else { } else {
return (Err(TransactionError::BlockhashNotFound), None); return (Err(TransactionError::BlockhashNotFound), None);
}; };

View File

@ -49,7 +49,7 @@ use solana_sdk::{
epoch_schedule::EpochSchedule, epoch_schedule::EpochSchedule,
feature, feature,
feature_set::{self, FeatureSet}, feature_set::{self, FeatureSet},
fee_calculator::{FeeCalculator, FeeConfig, FeeRateGovernor}, fee_calculator::{FeeCalculator, FeeRateGovernor},
genesis_config::{ClusterType, GenesisConfig}, genesis_config::{ClusterType, GenesisConfig},
hard_forks::HardForks, hard_forks::HardForks,
hash::{extend_and_hash, hashv, Hash}, hash::{extend_and_hash, hashv, Hash},
@ -3210,10 +3210,6 @@ impl Bank {
let hash_queue = self.blockhash_queue.read().unwrap(); let hash_queue = self.blockhash_queue.read().unwrap();
let mut fees = 0; let mut fees = 0;
let fee_config = FeeConfig {
secp256k1_program_enabled: self.secp256k1_program_enabled(),
};
let results = txs let results = txs
.zip(executed) .zip(executed)
.map(|(tx, (res, nonce_rollback))| { .map(|(tx, (res, nonce_rollback))| {
@ -3231,7 +3227,7 @@ impl Bank {
}); });
let fee_calculator = fee_calculator.ok_or(TransactionError::BlockhashNotFound)?; let fee_calculator = fee_calculator.ok_or(TransactionError::BlockhashNotFound)?;
let fee = fee_calculator.calculate_fee_with_config(tx.message(), &fee_config); let fee = fee_calculator.calculate_fee(tx.message());
let message = tx.message(); let message = tx.message();
match *res { match *res {
@ -4826,11 +4822,6 @@ impl Bank {
self.rc.accounts.accounts_db.shrink_candidate_slots() self.rc.accounts.accounts_db.shrink_candidate_slots()
} }
pub fn secp256k1_program_enabled(&self) -> bool {
self.feature_set
.is_active(&feature_set::secp256k1_program_enabled::id())
}
pub fn no_overflow_rent_distribution_enabled(&self) -> bool { pub fn no_overflow_rent_distribution_enabled(&self) -> bool {
self.feature_set self.feature_set
.is_active(&feature_set::no_overflow_rent_distribution::id()) .is_active(&feature_set::no_overflow_rent_distribution::id())
@ -4851,6 +4842,11 @@ impl Bank {
.is_active(&feature_set::check_duplicates_by_hash::id()) .is_active(&feature_set::check_duplicates_by_hash::id())
} }
pub fn libsecp256k1_0_5_upgrade_enabled(&self) -> bool {
self.feature_set
.is_active(&feature_set::libsecp256k1_0_5_upgrade_enabled::id())
}
// Check if the wallclock time from bank creation to now has exceeded the allotted // Check if the wallclock time from bank creation to now has exceeded the allotted
// time for transaction processing // time for transaction processing
pub fn should_bank_still_be_processing_txs( pub fn should_bank_still_be_processing_txs(
@ -5394,7 +5390,7 @@ pub(crate) mod tests {
cluster_type: ClusterType::MainnetBeta, cluster_type: ClusterType::MainnetBeta,
..GenesisConfig::default() ..GenesisConfig::default()
})); }));
let sysvar_and_native_proram_delta0 = 10; let sysvar_and_native_proram_delta0 = 11;
assert_eq!( assert_eq!(
bank0.capitalization(), bank0.capitalization(),
42 * 42 + sysvar_and_native_proram_delta0 42 * 42 + sysvar_and_native_proram_delta0
@ -7066,10 +7062,10 @@ pub(crate) mod tests {
// not being eagerly-collected for exact rewards calculation // not being eagerly-collected for exact rewards calculation
bank0.restore_old_behavior_for_fragile_tests(); bank0.restore_old_behavior_for_fragile_tests();
let sysvar_and_native_proram_delta0 = 10; let sysvar_and_native_program_delta0 = 11;
assert_eq!( assert_eq!(
bank0.capitalization(), bank0.capitalization(),
42 * 1_000_000_000 + sysvar_and_native_proram_delta0 42 * 1_000_000_000 + sysvar_and_native_program_delta0
); );
assert!(bank0.rewards.read().unwrap().is_empty()); assert!(bank0.rewards.read().unwrap().is_empty());
@ -7190,7 +7186,7 @@ pub(crate) mod tests {
// not being eagerly-collected for exact rewards calculation // not being eagerly-collected for exact rewards calculation
bank.restore_old_behavior_for_fragile_tests(); bank.restore_old_behavior_for_fragile_tests();
let sysvar_and_native_proram_delta = 10; let sysvar_and_native_proram_delta = 11;
assert_eq!( assert_eq!(
bank.capitalization(), bank.capitalization(),
42 * 1_000_000_000 + sysvar_and_native_proram_delta 42 * 1_000_000_000 + sysvar_and_native_proram_delta
@ -10410,25 +10406,25 @@ pub(crate) mod tests {
if bank.slot == 0 { if bank.slot == 0 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"6oxxAqridoSSPQ1rnEh8qBhQpMmLUve3X4fsNNr2gExE" "46i22T7axvpksuZ6k4XXwdzuX9957qtLWrhE2Kar97ys",
); );
} }
if bank.slot == 32 { if bank.slot == 32 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"7AkMgAb2v4tuoiSf3NnVgaBxSvp7XidbrSwsPEn4ENTp" "235cgdycjuz57eea3doYDiu2QYXPXKmxcfLnLAgBYjcG",
); );
} }
if bank.slot == 64 { if bank.slot == 64 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"2JzWWRBtQgdXboaACBRXNNKsHeBtn57uYmqH1AgGUkdG" "BTMBZpzx4ifH87neeZ7EubrHHGShCs3v7E4ZxnB1SGyk",
); );
} }
if bank.slot == 128 { if bank.slot == 128 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"FQnVhDVjhCyfBxFb3bdm3CLiuCePvWuW5TGDsLBZnKAo" "EcYx7YkUczHBUDuuVqfZYfZNfpsbKqe8JhSs7pwwWAUj",
); );
break; break;
} }
@ -10574,7 +10570,7 @@ pub(crate) mod tests {
// No more slots should be shrunk // No more slots should be shrunk
assert_eq!(bank2.shrink_candidate_slots(), 0); assert_eq!(bank2.shrink_candidate_slots(), 0);
// alive_counts represents the count of alive accounts in the three slots 0,1,2 // alive_counts represents the count of alive accounts in the three slots 0,1,2
assert_eq!(alive_counts, vec![9, 1, 7]); assert_eq!(alive_counts, vec![10, 1, 7]);
} }
#[test] #[test]
@ -10622,7 +10618,7 @@ pub(crate) mod tests {
.map(|_| bank.process_stale_slot_with_budget(0, force_to_return_alive_account)) .map(|_| bank.process_stale_slot_with_budget(0, force_to_return_alive_account))
.sum(); .sum();
// consumed_budgets represents the count of alive accounts in the three slots 0,1,2 // consumed_budgets represents the count of alive accounts in the three slots 0,1,2
assert_eq!(consumed_budgets, 10); assert_eq!(consumed_budgets, 11);
} }
#[test] #[test]

View File

@ -3,7 +3,6 @@ use crate::{
system_instruction_processor, system_instruction_processor,
}; };
use solana_sdk::{ use solana_sdk::{
feature_set,
instruction::InstructionError, instruction::InstructionError,
keyed_account::KeyedAccount, keyed_account::KeyedAccount,
process_instruction::{stable_log, InvokeContext, ProcessInstructionWithContext}, process_instruction::{stable_log, InvokeContext, ProcessInstructionWithContext},
@ -70,6 +69,11 @@ fn genesis_builtins() -> Vec<Builtin> {
solana_config_program::id(), solana_config_program::id(),
with_program_logging!(solana_config_program::config_processor::process_instruction), with_program_logging!(solana_config_program::config_processor::process_instruction),
), ),
Builtin::new(
"secp256k1_program",
solana_sdk::secp256k1_program::id(),
solana_secp256k1_program::process_instruction,
),
] ]
} }
@ -88,15 +92,7 @@ pub enum ActivationType {
/// normal child Bank creation. /// normal child Bank creation.
/// https://github.com/solana-labs/solana/blob/84b139cc94b5be7c9e0c18c2ad91743231b85a0d/runtime/src/bank.rs#L1723 /// https://github.com/solana-labs/solana/blob/84b139cc94b5be7c9e0c18c2ad91743231b85a0d/runtime/src/bank.rs#L1723
fn feature_builtins() -> Vec<(Builtin, Pubkey, ActivationType)> { fn feature_builtins() -> Vec<(Builtin, Pubkey, ActivationType)> {
vec![( vec![]
Builtin::new(
"secp256k1_program",
solana_sdk::secp256k1_program::id(),
solana_secp256k1_program::process_instruction,
),
feature_set::secp256k1_program_enabled::id(),
ActivationType::NewProgram,
)]
} }
pub(crate) fn get() -> Builtins { pub(crate) fn get() -> Builtins {

View File

@ -53,7 +53,7 @@ hex = "0.4.2"
hmac = "0.10.1" hmac = "0.10.1"
itertools = "0.9.0" itertools = "0.9.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
libsecp256k1 = { version = "0.3.5", optional = true } libsecp256k1 = { version = "0.5.0", optional = true }
log = "0.4.11" log = "0.4.11"
memmap2 = { version = "0.1.0", optional = true } memmap2 = { version = "0.1.0", optional = true }
num-derive = "0.3" num-derive = "0.3"

View File

@ -19,18 +19,6 @@ impl Default for FeeCalculator {
} }
} }
pub struct FeeConfig {
pub secp256k1_program_enabled: bool,
}
impl Default for FeeConfig {
fn default() -> Self {
Self {
secp256k1_program_enabled: true,
}
}
}
impl FeeCalculator { impl FeeCalculator {
pub fn new(lamports_per_signature: u64) -> Self { pub fn new(lamports_per_signature: u64) -> Self {
Self { Self {
@ -39,20 +27,14 @@ impl FeeCalculator {
} }
pub fn calculate_fee(&self, message: &Message) -> u64 { 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; let mut num_secp256k1_signatures: u64 = 0;
if fee_config.secp256k1_program_enabled { for instruction in &message.instructions {
for instruction in &message.instructions { let program_index = instruction.program_id_index as usize;
let program_index = instruction.program_id_index as usize; // Transaction may not be sanitized here
// Transaction may not be sanitized here if program_index < message.account_keys.len() {
if program_index < message.account_keys.len() { let id = message.account_keys[program_index];
let id = message.account_keys[program_index]; if secp256k1_program::check_id(&id) && !instruction.data.is_empty() {
if secp256k1_program::check_id(&id) && !instruction.data.is_empty() { num_secp256k1_signatures += instruction.data[0] as u64;
num_secp256k1_signatures += instruction.data[0] as u64;
}
} }
} }
} }
@ -258,15 +240,6 @@ mod tests {
Some(&pubkey0), Some(&pubkey0),
); );
assert_eq!(FeeCalculator::new(1).calculate_fee(&message), 2); assert_eq!(FeeCalculator::new(1).calculate_fee(&message), 2);
assert_eq!(
FeeCalculator::new(1).calculate_fee_with_config(
&message,
&FeeConfig {
secp256k1_program_enabled: false
}
),
1
);
secp_instruction.data = vec![0]; secp_instruction.data = vec![0];
secp_instruction2.data = vec![10]; secp_instruction2.data = vec![10];

View File

@ -10,10 +10,6 @@ pub mod instructions_sysvar_enabled {
solana_sdk::declare_id!("EnvhHCLvg55P7PDtbvR1NwuTuAeodqpusV3MR5QEK8gs"); solana_sdk::declare_id!("EnvhHCLvg55P7PDtbvR1NwuTuAeodqpusV3MR5QEK8gs");
} }
pub mod secp256k1_program_enabled {
solana_sdk::declare_id!("E3PHP7w8kB7np3CTQ1qQ2tW3KCtjRSXBQgW9vM2mWv2Y");
}
pub mod consistent_recent_blockhashes_sysvar { pub mod consistent_recent_blockhashes_sysvar {
solana_sdk::declare_id!("3h1BQWPDS5veRsq6mDBWruEpgPxRJkfwGexg5iiQ9mYg"); solana_sdk::declare_id!("3h1BQWPDS5veRsq6mDBWruEpgPxRJkfwGexg5iiQ9mYg");
} }
@ -162,11 +158,14 @@ pub mod updated_verify_policy {
solana_sdk::declare_id!("k15tVxtkgsmo7dy6iJ56N5hBCxuQAtqRgYwoTDuwbia"); solana_sdk::declare_id!("k15tVxtkgsmo7dy6iJ56N5hBCxuQAtqRgYwoTDuwbia");
} }
pub mod libsecp256k1_0_5_upgrade_enabled {
solana_sdk::declare_id!("DhsYfRjxfnh2g7HKJYSzT79r74Afa1wbHkAgHndrA1oy");
}
lazy_static! { lazy_static! {
/// Map of feature identifiers to user-visible description /// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [ pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
(instructions_sysvar_enabled::id(), "instructions sysvar"), (instructions_sysvar_enabled::id(), "instructions sysvar"),
(secp256k1_program_enabled::id(), "secp256k1 program"),
(consistent_recent_blockhashes_sysvar::id(), "consistent recentblockhashes sysvar"), (consistent_recent_blockhashes_sysvar::id(), "consistent recentblockhashes sysvar"),
(deprecate_rewards_sysvar::id(), "deprecate unused rewards sysvar"), (deprecate_rewards_sysvar::id(), "deprecate unused rewards sysvar"),
(pico_inflation::id(), "pico inflation"), (pico_inflation::id(), "pico inflation"),
@ -201,6 +200,7 @@ lazy_static! {
(dedupe_config_program_signers::id(), "dedupe config program signers"), (dedupe_config_program_signers::id(), "dedupe config program signers"),
(vote_stake_checked_instructions::id(), "vote/state program checked instructions #18345"), (vote_stake_checked_instructions::id(), "vote/state program checked instructions #18345"),
(updated_verify_policy::id(), "Update verify policy"), (updated_verify_policy::id(), "Update verify policy"),
(libsecp256k1_0_5_upgrade_enabled::id(), "upgrade libsecp256k1 to v0.5.0"),
/*************** ADD NEW FEATURES HERE ***************/ /*************** ADD NEW FEATURES HERE ***************/
] ]
.iter() .iter()

View File

@ -29,18 +29,18 @@ pub struct SecpSignatureOffsets {
} }
pub fn new_secp256k1_instruction( pub fn new_secp256k1_instruction(
priv_key: &secp256k1::SecretKey, priv_key: &libsecp256k1::SecretKey,
message_arr: &[u8], message_arr: &[u8],
) -> Instruction { ) -> Instruction {
let secp_pubkey = secp256k1::PublicKey::from_secret_key(priv_key); let secp_pubkey = libsecp256k1::PublicKey::from_secret_key(priv_key);
let eth_pubkey = construct_eth_pubkey(&secp_pubkey); let eth_pubkey = construct_eth_pubkey(&secp_pubkey);
let mut hasher = sha3::Keccak256::new(); let mut hasher = sha3::Keccak256::new();
hasher.update(&message_arr); hasher.update(&message_arr);
let message_hash = hasher.finalize(); let message_hash = hasher.finalize();
let mut message_hash_arr = [0u8; 32]; let mut message_hash_arr = [0u8; 32];
message_hash_arr.copy_from_slice(&message_hash.as_slice()); message_hash_arr.copy_from_slice(&message_hash.as_slice());
let message = secp256k1::Message::parse(&message_hash_arr); let message = libsecp256k1::Message::parse(&message_hash_arr);
let (signature, recovery_id) = secp256k1::sign(&message, priv_key); let (signature, recovery_id) = libsecp256k1::sign(&message, priv_key);
let signature_arr = signature.serialize(); let signature_arr = signature.serialize();
assert_eq!(signature_arr.len(), SIGNATURE_SERIALIZED_SIZE); assert_eq!(signature_arr.len(), SIGNATURE_SERIALIZED_SIZE);
@ -84,7 +84,9 @@ pub fn new_secp256k1_instruction(
} }
} }
pub fn construct_eth_pubkey(pubkey: &secp256k1::PublicKey) -> [u8; HASHED_PUBKEY_SERIALIZED_SIZE] { pub fn construct_eth_pubkey(
pubkey: &libsecp256k1::PublicKey,
) -> [u8; HASHED_PUBKEY_SERIALIZED_SIZE] {
let mut addr = [0u8; HASHED_PUBKEY_SERIALIZED_SIZE]; let mut addr = [0u8; HASHED_PUBKEY_SERIALIZED_SIZE];
addr.copy_from_slice(&sha3::Keccak256::digest(&pubkey.serialize()[1..])[12..]); addr.copy_from_slice(&sha3::Keccak256::digest(&pubkey.serialize()[1..])[12..]);
assert_eq!(addr.len(), HASHED_PUBKEY_SERIALIZED_SIZE); assert_eq!(addr.len(), HASHED_PUBKEY_SERIALIZED_SIZE);
@ -94,6 +96,7 @@ pub fn construct_eth_pubkey(pubkey: &secp256k1::PublicKey) -> [u8; HASHED_PUBKEY
pub fn verify_eth_addresses( pub fn verify_eth_addresses(
data: &[u8], data: &[u8],
instruction_datas: &[&[u8]], instruction_datas: &[&[u8]],
libsecp256k1_0_5_upgrade_enabled: bool,
) -> Result<(), Secp256k1Error> { ) -> Result<(), Secp256k1Error> {
if data.is_empty() { if data.is_empty() {
return Err(Secp256k1Error::InvalidInstructionDataSize); return Err(Secp256k1Error::InvalidInstructionDataSize);
@ -121,11 +124,20 @@ pub fn verify_eth_addresses(
if sig_end >= signature_instruction.len() { if sig_end >= signature_instruction.len() {
return Err(Secp256k1Error::InvalidSignature); return Err(Secp256k1Error::InvalidSignature);
} }
let signature =
secp256k1::Signature::parse_slice(&signature_instruction[sig_start..sig_end])
.map_err(|_| Secp256k1Error::InvalidSignature)?;
let recovery_id = secp256k1::RecoveryId::parse(signature_instruction[sig_end]) let sig_parse_result = if libsecp256k1_0_5_upgrade_enabled {
libsecp256k1::Signature::parse_standard_slice(
&signature_instruction[sig_start..sig_end],
)
} else {
libsecp256k1::Signature::parse_overflowing_slice(
&signature_instruction[sig_start..sig_end],
)
};
let signature = sig_parse_result.map_err(|_| Secp256k1Error::InvalidSignature)?;
let recovery_id = libsecp256k1::RecoveryId::parse(signature_instruction[sig_end])
.map_err(|_| Secp256k1Error::InvalidRecoveryId)?; .map_err(|_| Secp256k1Error::InvalidRecoveryId)?;
// Parse out pubkey // Parse out pubkey
@ -148,8 +160,8 @@ pub fn verify_eth_addresses(
hasher.update(message_slice); hasher.update(message_slice);
let message_hash = hasher.finalize(); let message_hash = hasher.finalize();
let pubkey = secp256k1::recover( let pubkey = libsecp256k1::recover(
&secp256k1::Message::parse_slice(&message_hash).unwrap(), &libsecp256k1::Message::parse_slice(&message_hash).unwrap(),
&signature, &signature,
&recovery_id, &recovery_id,
) )
@ -193,7 +205,7 @@ pub mod test {
let writer = std::io::Cursor::new(&mut instruction_data[1..]); let writer = std::io::Cursor::new(&mut instruction_data[1..]);
bincode::serialize_into(writer, &offsets).unwrap(); bincode::serialize_into(writer, &offsets).unwrap();
verify_eth_addresses(&instruction_data, &[&[0u8; 100]]) verify_eth_addresses(&instruction_data, &[&[0u8; 100]], false)
} }
#[test] #[test]
@ -208,7 +220,7 @@ pub mod test {
instruction_data.truncate(instruction_data.len() - 1); instruction_data.truncate(instruction_data.len() - 1);
assert_eq!( assert_eq!(
verify_eth_addresses(&instruction_data, &[&[0u8; 100]]), verify_eth_addresses(&instruction_data, &[&[0u8; 100]], false),
Err(Secp256k1Error::InvalidInstructionDataSize) Err(Secp256k1Error::InvalidInstructionDataSize)
); );

View File

@ -387,7 +387,7 @@ impl Transaction {
.collect() .collect()
} }
pub fn verify_precompiles(&self) -> Result<()> { pub fn verify_precompiles(&self, libsecp256k1_0_5_upgrade_enabled: bool) -> Result<()> {
for instruction in &self.message().instructions { for instruction in &self.message().instructions {
// The Transaction may not be sanitized at this point // The Transaction may not be sanitized at this point
if instruction.program_id_index as usize >= self.message().account_keys.len() { if instruction.program_id_index as usize >= self.message().account_keys.len() {
@ -402,7 +402,11 @@ impl Transaction {
.map(|instruction| instruction.data.as_ref()) .map(|instruction| instruction.data.as_ref())
.collect(); .collect();
let data = &instruction.data; let data = &instruction.data;
let e = verify_eth_addresses(data, &instruction_datas); let e = verify_eth_addresses(
data,
&instruction_datas,
libsecp256k1_0_5_upgrade_enabled,
);
e.map_err(|_| TransactionError::InvalidAccountIndex)?; e.map_err(|_| TransactionError::InvalidAccountIndex)?;
} }
} }