never speak of the verifier cache again (#3628)

This commit is contained in:
Antioch Peverell
2021-04-01 15:04:53 +01:00
committed by GitHub
parent cccaf98493
commit f6ec77a592
37 changed files with 189 additions and 735 deletions
-1
View File
@@ -23,7 +23,6 @@ pub mod id;
pub mod merkle_proof;
pub mod pmmr;
pub mod transaction;
pub mod verifier_cache;
use crate::consensus::GRIN_BASE;
use util::secp::pedersen::Commitment;
+2 -9
View File
@@ -18,7 +18,6 @@ use crate::consensus::{self, reward, REWARD};
use crate::core::committed::{self, Committed};
use crate::core::compact_block::CompactBlock;
use crate::core::hash::{DefaultHashable, Hash, Hashed, ZERO_HASH};
use crate::core::verifier_cache::VerifierCache;
use crate::core::{
pmmr, transaction, Commitment, Inputs, KernelFeatures, Output, Transaction, TransactionBody,
TxKernel, Weighting,
@@ -34,9 +33,7 @@ use chrono::Duration;
use keychain::{self, BlindingFactor};
use std::convert::TryInto;
use std::fmt;
use std::sync::Arc;
use util::from_hex;
use util::RwLock;
use util::{secp, static_secp_instance};
/// Errors thrown by Block validation
@@ -732,12 +729,8 @@ impl Block {
/// Validates all the elements in a block that can be checked without
/// additional data. Includes commitment sums and kernels, Merkle
/// trees, reward, etc.
pub fn validate(
&self,
prev_kernel_offset: &BlindingFactor,
verifier: Arc<RwLock<dyn VerifierCache>>,
) -> Result<(), Error> {
self.body.validate(Weighting::AsBlock, verifier)?;
pub fn validate(&self, prev_kernel_offset: &BlindingFactor) -> Result<(), Error> {
self.body.validate(Weighting::AsBlock)?;
self.verify_kernel_lock_heights()?;
self.verify_nrd_kernels_for_header_version()?;
+3 -15
View File
@@ -16,7 +16,6 @@
use crate::core::block::HeaderVersion;
use crate::core::hash::{DefaultHashable, Hashed};
use crate::core::verifier_cache::VerifierCache;
use crate::core::{committed, Committed};
use crate::libtx::{aggsig, secp_ser};
use crate::ser::{
@@ -32,12 +31,10 @@ use std::cmp::Ordering;
use std::cmp::{max, min};
use std::convert::{TryFrom, TryInto};
use std::fmt::Display;
use std::sync::Arc;
use std::{error, fmt};
use util::secp;
use util::secp::pedersen::{Commitment, RangeProof};
use util::static_secp_instance;
use util::RwLock;
use util::ToHex;
/// Fee fields as in fix-fees RFC: { future_use: 20, fee_shift: 4, fee: 40 }
@@ -1243,11 +1240,7 @@ impl TransactionBody {
/// Validates all relevant parts of a transaction body. Checks the
/// excess value against the signature as well as range proofs for each
/// output.
pub fn validate(
&self,
weighting: Weighting,
_verifier: Arc<RwLock<dyn VerifierCache>>,
) -> Result<(), Error> {
pub fn validate(&self, weighting: Weighting) -> Result<(), Error> {
self.validate_read(weighting)?;
// Now batch verify all those unverified rangeproofs
@@ -1458,14 +1451,9 @@ impl Transaction {
/// Validates all relevant parts of a fully built transaction. Checks the
/// excess value against the signature as well as range proofs for each
/// output.
pub fn validate(
&self,
weighting: Weighting,
verifier: Arc<RwLock<dyn VerifierCache>>,
height: u64,
) -> Result<(), Error> {
pub fn validate(&self, weighting: Weighting, height: u64) -> Result<(), Error> {
self.body.verify_features()?;
self.body.validate(weighting, verifier)?;
self.body.validate(weighting)?;
self.verify_kernel_sums(self.overage(height), self.offset.clone())?;
Ok(())
}
-103
View File
@@ -1,103 +0,0 @@
// Copyright 2021 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! VerifierCache trait for batch verifying outputs and kernels.
//! We pass a "caching verifier" into the block validation processing with this.
use crate::core::hash::{Hash, Hashed};
use crate::core::{Output, TxKernel};
use lru_cache::LruCache;
/// Verifier cache for caching expensive verification results.
/// Specifically the following -
/// * kernel signature verification
/// * output rangeproof verification
pub trait VerifierCache: Sync + Send {
/// Takes a vec of tx kernels and returns those kernels
/// that have not yet been verified.
fn filter_kernel_sig_unverified(&mut self, kernels: &[TxKernel]) -> Vec<TxKernel>;
/// Takes a vec of tx outputs and returns those outputs
/// that have not yet had their rangeproofs verified.
fn filter_rangeproof_unverified(&mut self, outputs: &[Output]) -> Vec<Output>;
/// Adds a vec of tx kernels to the cache (used in conjunction with the the filter above).
fn add_kernel_sig_verified(&mut self, kernels: Vec<TxKernel>);
/// Adds a vec of outputs to the cache (used in conjunction with the the filter above).
fn add_rangeproof_verified(&mut self, outputs: Vec<Output>);
}
/// An implementation of verifier_cache using lru_cache.
/// Caches tx kernels by kernel hash.
/// Caches outputs by output rangeproof hash (rangeproofs are committed to separately).
pub struct LruVerifierCache {
kernel_sig_verification_cache: LruCache<Hash, ()>,
rangeproof_verification_cache: LruCache<Hash, ()>,
}
impl LruVerifierCache {
/// TODO how big should these caches be?
/// They need to be *at least* large enough to cover a maxed out block.
pub fn new() -> LruVerifierCache {
LruVerifierCache {
kernel_sig_verification_cache: LruCache::new(50_000),
rangeproof_verification_cache: LruCache::new(50_000),
}
}
}
impl VerifierCache for LruVerifierCache {
fn filter_kernel_sig_unverified(&mut self, kernels: &[TxKernel]) -> Vec<TxKernel> {
let res = kernels
.iter()
.filter(|x| !self.kernel_sig_verification_cache.contains_key(&x.hash()))
.cloned()
.collect::<Vec<_>>();
trace!(
"lru_verifier_cache: kernel sigs: {}, not cached (must verify): {}",
kernels.len(),
res.len()
);
res
}
fn filter_rangeproof_unverified(&mut self, outputs: &[Output]) -> Vec<Output> {
let res = outputs
.iter()
.filter(|x| {
!self
.rangeproof_verification_cache
.contains_key(&x.proof.hash())
})
.cloned()
.collect::<Vec<_>>();
trace!(
"lru_verifier_cache: rangeproofs: {}, not cached (must verify): {}",
outputs.len(),
res.len()
);
res
}
fn add_kernel_sig_verified(&mut self, kernels: Vec<TxKernel>) {
for k in kernels {
self.kernel_sig_verification_cache.insert(k.hash(), ());
}
}
fn add_rangeproof_verified(&mut self, outputs: Vec<Output>) {
for o in outputs {
self.rangeproof_verification_cache
.insert(o.proof.hash(), ());
}
}
}
+3 -20
View File
@@ -253,20 +253,12 @@ where
// Just a simple test, most exhaustive tests in the core.
#[cfg(test)]
mod test {
use std::sync::Arc;
use util::RwLock;
use super::*;
use crate::core::transaction::Weighting;
use crate::core::verifier_cache::{LruVerifierCache, VerifierCache};
use crate::global;
use crate::libtx::ProofBuilder;
use keychain::{ExtKeychain, ExtKeychainPath};
fn verifier_cache() -> Arc<RwLock<dyn VerifierCache>> {
Arc::new(RwLock::new(LruVerifierCache::new()))
}
#[test]
fn blind_simple_tx() {
global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
@@ -276,8 +268,6 @@ mod test {
let key_id2 = ExtKeychainPath::new(1, 2, 0, 0, 0).to_identifier();
let key_id3 = ExtKeychainPath::new(1, 3, 0, 0, 0).to_identifier();
let vc = verifier_cache();
let tx = transaction(
KernelFeatures::Plain { fee: 2.into() },
&[input(10, key_id1), input(12, key_id2), output(20, key_id3)],
@@ -287,8 +277,7 @@ mod test {
.unwrap();
let height = 42; // arbitrary
tx.validate(Weighting::AsTransaction, vc.clone(), height)
.unwrap();
tx.validate(Weighting::AsTransaction, height).unwrap();
}
#[test]
@@ -300,8 +289,6 @@ mod test {
let key_id2 = ExtKeychainPath::new(1, 2, 0, 0, 0).to_identifier();
let key_id3 = ExtKeychainPath::new(1, 3, 0, 0, 0).to_identifier();
let vc = verifier_cache();
let tx = transaction(
KernelFeatures::Plain { fee: 2.into() },
&[input(10, key_id1), input(12, key_id2), output(20, key_id3)],
@@ -311,8 +298,7 @@ mod test {
.unwrap();
let height = 42; // arbitrary
tx.validate(Weighting::AsTransaction, vc.clone(), height)
.unwrap();
tx.validate(Weighting::AsTransaction, height).unwrap();
}
#[test]
@@ -323,8 +309,6 @@ mod test {
let key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();
let key_id2 = ExtKeychainPath::new(1, 2, 0, 0, 0).to_identifier();
let vc = verifier_cache();
let tx = transaction(
KernelFeatures::Plain { fee: 4.into() },
&[input(6, key_id1), output(2, key_id2)],
@@ -334,7 +318,6 @@ mod test {
.unwrap();
let height = 42; // arbitrary
tx.validate(Weighting::AsTransaction, vc.clone(), height)
.unwrap();
tx.validate(Weighting::AsTransaction, height).unwrap();
}
}