diff --git a/.changelog/unreleased/improvements/1954-gas-in-sig-ver.md b/.changelog/unreleased/improvements/1954-gas-in-sig-ver.md new file mode 100644 index 0000000000..27ba173c46 --- /dev/null +++ b/.changelog/unreleased/improvements/1954-gas-in-sig-ver.md @@ -0,0 +1,2 @@ +- Increased resoultion of gas accounting for signature verification. + ([\#1954](https://github.com/anoma/namada/pull/1954)) \ No newline at end of file diff --git a/benches/host_env.rs b/benches/host_env.rs index 1c611f4e18..f2e2c3ee2a 100644 --- a/benches/host_env.rs +++ b/benches/host_env.rs @@ -35,7 +35,7 @@ fn tx_section_signature_validation(c: &mut Criterion) { c.bench_function("tx_section_signature_validation", |b| { b.iter(|| { multisig - .verify_signature(&mut HashSet::new(), &pkim, &None) + .verify_signature(&mut HashSet::new(), &pkim, &None, &mut None) .unwrap() }) }); diff --git a/core/src/proto/types.rs b/core/src/proto/types.rs index 186fe4eaf6..aa0ae92060 100644 --- a/core/src/proto/types.rs +++ b/core/src/proto/types.rs @@ -554,6 +554,7 @@ impl Signature { verified_pks: &mut HashSet, public_keys_index_map: &AccountPublicKeysMap, signer: &Option
, + gas_meter: &mut Option<&mut VpGasMeter>, ) -> std::result::Result { // Records whether there are any successful verifications let mut verifications = 0; @@ -565,6 +566,11 @@ impl Signature { if let Some(pk) = public_keys_index_map.get_public_key_from_index(*idx) { + if let Some(meter) = gas_meter { + meter + .consume(VERIFY_TX_SIG_GAS_COST) + .map_err(|_| VerifySigError::OutOfGas)?; + } common::SigScheme::verify_signature( &pk, &self.get_raw_hash(), @@ -585,6 +591,11 @@ impl Signature { if let Some(map_idx) = public_keys_index_map.get_index_from_public_key(pk) { + if let Some(meter) = gas_meter { + meter + .consume(VERIFY_TX_SIG_GAS_COST) + .map_err(|_| VerifySigError::OutOfGas)?; + } common::SigScheme::verify_signature( pk, &self.get_raw_hash(), @@ -1377,7 +1388,7 @@ impl Tx { signer: &Option
, threshold: u8, max_signatures: Option, - mut gas_meter: Option<&mut VpGasMeter>, + gas_meter: &mut Option<&mut VpGasMeter>, ) -> std::result::Result, Error> { let max_signatures = max_signatures.unwrap_or(u8::MAX); // Records the public key indices used in successful signatures @@ -1404,26 +1415,22 @@ impl Tx { } // Finally verify that the signature itself is valid - let prev_verifieds = verified_pks.len(); let amt_verifieds = signatures .verify_signature( &mut verified_pks, &public_keys_index_map, signer, + gas_meter, ) - .map_err(|_| { - Error::InvalidSectionSignature( - "found invalid signature.".to_string(), - ) + .map_err(|e| { + if let VerifySigError::OutOfGas = e { + Error::OutOfGas + } else { + Error::InvalidSectionSignature( + "found invalid signature.".to_string(), + ) + } }); - // Compute the cost of the signature verifications - if let Some(x) = gas_meter.as_mut() { - let amt_verified = usize::from(amt_verifieds.is_err()) - + verified_pks.len() - - prev_verifieds; - x.consume(VERIFY_TX_SIG_GAS_COST * amt_verified as u64) - .map_err(|_| Error::OutOfGas)?; - } // Record the section witnessing these signatures if amt_verifieds? > 0 { witnesses.push(signatures); @@ -1454,7 +1461,7 @@ impl Tx { &None, 1, None, - None, + &mut None, ) .map(|x| *x.first().unwrap()) .map_err(|_| Error::InvalidWrapperSignature) diff --git a/core/src/types/key/mod.rs b/core/src/types/key/mod.rs index 15b1380e2c..f6d226e2f4 100644 --- a/core/src/types/key/mod.rs +++ b/core/src/types/key/mod.rs @@ -124,6 +124,8 @@ pub enum VerifySigError { MissingData, #[error("Signature belongs to a different scheme from the public key.")] MismatchedScheme, + #[error("Signature verification went out of gas")] + OutOfGas, } #[allow(missing_docs)] diff --git a/shared/src/vm/host_env.rs b/shared/src/vm/host_env.rs index ce6e616b1c..0cf928a2a4 100644 --- a/shared/src/vm/host_env.rs +++ b/shared/src/vm/host_env.rs @@ -1875,7 +1875,7 @@ where &Some(signer), threshold, max_signatures, - Some(gas_meter), + &mut Some(gas_meter), ) .is_ok(), ) diff --git a/tests/src/vm_host_env/mod.rs b/tests/src/vm_host_env/mod.rs index ca61bd34d7..b7e6290ed1 100644 --- a/tests/src/vm_host_env/mod.rs +++ b/tests/src/vm_host_env/mod.rs @@ -482,7 +482,7 @@ mod tests { &None, 1, None, - Some(&mut VpGasMeter::new_from_tx_meter( + &mut Some(&mut VpGasMeter::new_from_tx_meter( &TxGasMeter::new_from_sub_limit(u64::MAX.into()) )) ) @@ -503,7 +503,7 @@ mod tests { &None, 1, None, - Some(&mut VpGasMeter::new_from_tx_meter( + &mut Some(&mut VpGasMeter::new_from_tx_meter( &TxGasMeter::new_from_sub_limit(u64::MAX.into()) )) )