mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
schnorr signature batch verification (#2961)
* schnorr signature batch verification * Split the fee and lock_height verification out from the batch signature verification * Remove the new added fee_height_verify to comply with #2859 * fix: the last n could not be leaf?
This commit is contained in:
parent
2cebdc5868
commit
928279a676
2 changed files with 40 additions and 19 deletions
|
@ -1373,9 +1373,11 @@ impl<'a> Extension<'a> {
|
||||||
|
|
||||||
fn verify_kernel_signatures(&self, status: &dyn TxHashsetWriteStatus) -> Result<(), Error> {
|
fn verify_kernel_signatures(&self, status: &dyn TxHashsetWriteStatus) -> Result<(), Error> {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
const KERNEL_BATCH_SIZE: usize = 5_000;
|
||||||
|
|
||||||
let mut kern_count = 0;
|
let mut kern_count = 0;
|
||||||
let total_kernels = pmmr::n_leaves(self.kernel_pmmr.unpruned_size());
|
let total_kernels = pmmr::n_leaves(self.kernel_pmmr.unpruned_size());
|
||||||
|
let mut tx_kernels: Vec<TxKernel> = Vec::with_capacity(KERNEL_BATCH_SIZE);
|
||||||
for n in 1..self.kernel_pmmr.unpruned_size() + 1 {
|
for n in 1..self.kernel_pmmr.unpruned_size() + 1 {
|
||||||
if pmmr::is_leaf(n) {
|
if pmmr::is_leaf(n) {
|
||||||
let kernel = self
|
let kernel = self
|
||||||
|
@ -1383,20 +1385,20 @@ impl<'a> Extension<'a> {
|
||||||
.get_data(n)
|
.get_data(n)
|
||||||
.ok_or::<Error>(ErrorKind::TxKernelNotFound.into())?;
|
.ok_or::<Error>(ErrorKind::TxKernelNotFound.into())?;
|
||||||
|
|
||||||
kernel.verify()?;
|
tx_kernels.push(kernel.kernel);
|
||||||
kern_count += 1;
|
|
||||||
|
|
||||||
if kern_count % 20 == 0 {
|
|
||||||
status.on_validation(kern_count, total_kernels, 0, 0);
|
|
||||||
}
|
}
|
||||||
if kern_count % 1_000 == 0 {
|
|
||||||
|
if tx_kernels.len() >= KERNEL_BATCH_SIZE || n >= self.kernel_pmmr.unpruned_size() {
|
||||||
|
TxKernel::batch_sig_verify(&tx_kernels)?;
|
||||||
|
kern_count += tx_kernels.len() as u64;
|
||||||
|
tx_kernels.clear();
|
||||||
|
status.on_validation(kern_count, total_kernels, 0, 0);
|
||||||
debug!(
|
debug!(
|
||||||
"txhashset: verify_kernel_signatures: verified {} signatures",
|
"txhashset: verify_kernel_signatures: verified {} signatures",
|
||||||
kern_count,
|
kern_count,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"txhashset: verified {} kernel signatures, pmmr size {}, took {}s",
|
"txhashset: verified {} kernel signatures, pmmr size {}, took {}s",
|
||||||
|
@ -1411,8 +1413,8 @@ impl<'a> Extension<'a> {
|
||||||
fn verify_rangeproofs(&self, status: &dyn TxHashsetWriteStatus) -> Result<(), Error> {
|
fn verify_rangeproofs(&self, status: &dyn TxHashsetWriteStatus) -> Result<(), Error> {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
let mut commits: Vec<Commitment> = vec![];
|
let mut commits: Vec<Commitment> = Vec::with_capacity(1_000);
|
||||||
let mut proofs: Vec<RangeProof> = vec![];
|
let mut proofs: Vec<RangeProof> = Vec::with_capacity(1_000);
|
||||||
|
|
||||||
let mut proof_count = 0;
|
let mut proof_count = 0;
|
||||||
let total_rproofs = pmmr::n_leaves(self.output_pmmr.unpruned_size());
|
let total_rproofs = pmmr::n_leaves(self.output_pmmr.unpruned_size());
|
||||||
|
@ -1443,7 +1445,7 @@ impl<'a> Extension<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if proof_count % 20 == 0 {
|
if proof_count % 1_000 == 0 {
|
||||||
status.on_validation(0, 0, proof_count, total_rproofs);
|
status.on_validation(0, 0, proof_count, total_rproofs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,6 +391,29 @@ impl TxKernel {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Batch signature verification.
|
||||||
|
pub fn batch_sig_verify(tx_kernels: &Vec<TxKernel>) -> Result<(), Error> {
|
||||||
|
let len = tx_kernels.len();
|
||||||
|
let mut sigs: Vec<secp::Signature> = Vec::with_capacity(len);
|
||||||
|
let mut pubkeys: Vec<secp::key::PublicKey> = Vec::with_capacity(len);
|
||||||
|
let mut msgs: Vec<secp::Message> = Vec::with_capacity(len);
|
||||||
|
|
||||||
|
let secp = static_secp_instance();
|
||||||
|
let secp = secp.lock();
|
||||||
|
|
||||||
|
for tx_kernel in tx_kernels {
|
||||||
|
sigs.push(tx_kernel.excess_sig);
|
||||||
|
pubkeys.push(tx_kernel.excess.to_pubkey(&secp)?);
|
||||||
|
msgs.push(tx_kernel.msg_to_sign()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !secp::aggsig::verify_batch(&secp, &sigs, &msgs, &pubkeys) {
|
||||||
|
return Err(Error::IncorrectSignature);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Build an empty tx kernel with zero values.
|
/// Build an empty tx kernel with zero values.
|
||||||
pub fn empty() -> TxKernel {
|
pub fn empty() -> TxKernel {
|
||||||
TxKernel {
|
TxKernel {
|
||||||
|
@ -861,11 +884,7 @@ impl TransactionBody {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Verify the unverified tx kernels.
|
// Verify the unverified tx kernels.
|
||||||
// No ability to batch verify these right now
|
TxKernel::batch_sig_verify(&kernels)?;
|
||||||
// so just do them individually.
|
|
||||||
for x in &kernels {
|
|
||||||
x.verify()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache the successful verification results for the new outputs and kernels.
|
// Cache the successful verification results for the new outputs and kernels.
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue