Consolidate validation in Block and Transaction (#1354)

* Consolidate validation in Block and Transaction

Introduce TransactionBody which is included into block and tx.
Fixes #1333
This commit is contained in:
hashmap
2018-08-15 23:14:48 +02:00
committed by GitHub
parent 37fa413329
commit 99a66c1960
20 changed files with 570 additions and 476 deletions
+9 -9
View File
@@ -170,8 +170,8 @@ pub fn initial_tx<K>(mut tx: Transaction) -> Box<Append<K>>
where
K: Keychain,
{
assert_eq!(tx.kernels.len(), 1);
let kern = tx.kernels.remove(0);
assert_eq!(tx.kernels().len(), 1);
let kern = tx.kernels_mut().remove(0);
Box::new(
move |_build, (_, _, sum)| -> (Transaction, TxKernel, BlindSum) {
(tx.clone(), kern.clone(), sum)
@@ -204,8 +204,8 @@ where
let blind_sum = ctx.keychain.blind_sum(&sum)?;
// we only support building a tx with a single kernel via build::transaction()
assert!(tx.kernels.is_empty());
tx.kernels.push(kern);
assert!(tx.kernels().is_empty());
tx.kernels_mut().push(kern);
Ok((tx, blind_sum))
}
@@ -219,16 +219,16 @@ where
K: Keychain,
{
let (mut tx, blind_sum) = partial_transaction(elems, keychain)?;
assert_eq!(tx.kernels.len(), 1);
assert_eq!(tx.kernels().len(), 1);
let mut kern = tx.kernels.remove(0);
let mut kern = tx.kernels_mut().remove(0);
let msg = secp::Message::from_slice(&kernel_sig_msg(kern.fee, kern.lock_height))?;
let skey = blind_sum.secret_key(&keychain.secp())?;
kern.excess = keychain.secp().commit(0, skey)?;
kern.excess_sig = aggsig::sign_with_blinding(&keychain.secp(), &msg, &blind_sum).unwrap();
tx.kernels.push(kern);
tx.kernels_mut().push(kern);
Ok(tx)
}
@@ -264,8 +264,8 @@ where
// commitments will sum correctly when including the offset
tx.offset = k2.clone();
assert!(tx.kernels.is_empty());
tx.kernels.push(kern);
assert!(tx.kernels().is_empty());
tx.kernels_mut().push(kern);
Ok(tx)
}
+16 -12
View File
@@ -113,7 +113,7 @@ impl Slate {
K: Keychain,
{
// Append to the exiting transaction
if self.tx.kernels.len() != 0 {
if self.tx.kernels().len() != 0 {
elems.insert(0, build::initial_tx(self.tx.clone()));
}
let (tx, blind) = build::partial_transaction(elems, keychain)?;
@@ -179,7 +179,8 @@ impl Slate {
/// Return the sum of public nonces
fn pub_nonce_sum(&self, secp: &secp::Secp256k1) -> Result<PublicKey, Error> {
let pub_nonces = self.participant_data
let pub_nonces = self
.participant_data
.iter()
.map(|p| &p.public_nonce)
.collect();
@@ -191,7 +192,8 @@ impl Slate {
/// Return the sum of public blinding factors
fn pub_blind_sum(&self, secp: &secp::Secp256k1) -> Result<PublicKey, Error> {
let pub_blinds = self.participant_data
let pub_blinds = self
.participant_data
.iter()
.map(|p| &p.public_blind_excess)
.collect();
@@ -250,9 +252,11 @@ impl Slate {
// the aggsig context with the "split" key
self.tx.offset =
BlindingFactor::from_secret_key(SecretKey::new(&keychain.secp(), &mut thread_rng()));
let blind_offset = keychain.blind_sum(&BlindSum::new()
.add_blinding_factor(BlindingFactor::from_secret_key(sec_key.clone()))
.sub_blinding_factor(self.tx.offset))?;
let blind_offset = keychain.blind_sum(
&BlindSum::new()
.add_blinding_factor(BlindingFactor::from_secret_key(sec_key.clone()))
.sub_blinding_factor(self.tx.offset),
)?;
*sec_key = blind_offset.secret_key(&keychain.secp())?;
Ok(())
}
@@ -262,7 +266,7 @@ impl Slate {
// double check the fee amount included in the partial tx
// we don't necessarily want to just trust the sender
// we could just overwrite the fee here (but we won't) due to the sig
let fee = tx_fee(self.tx.inputs.len(), self.tx.outputs.len(), None);
let fee = tx_fee(self.tx.inputs().len(), self.tx.outputs().len(), None);
if fee > self.tx.fee() {
return Err(ErrorKind::Fee(
format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(),
@@ -361,7 +365,7 @@ impl Slate {
// build the final excess based on final tx and offset
let final_excess = {
// TODO - do we need to verify rangeproofs here?
for x in &final_tx.outputs {
for x in final_tx.outputs() {
x.verify_proof()?;
}
@@ -379,13 +383,13 @@ impl Slate {
};
// update the tx kernel to reflect the offset excess and sig
assert_eq!(final_tx.kernels.len(), 1);
final_tx.kernels[0].excess = final_excess.clone();
final_tx.kernels[0].excess_sig = final_sig.clone();
assert_eq!(final_tx.kernels().len(), 1);
final_tx.kernels_mut()[0].excess = final_excess.clone();
final_tx.kernels_mut()[0].excess_sig = final_sig.clone();
// confirm the kernel verifies successfully before proceeding
debug!(LOGGER, "Validating final transaction");
final_tx.kernels[0].verify()?;
final_tx.kernels()[0].verify()?;
// confirm the overall transaction is valid (including the updated kernel)
let _ = final_tx.validate(false)?;
+2 -2
View File
@@ -217,7 +217,7 @@ mod test {
let tx1 = build::transaction(vec![build::output(105, key_id1.clone())], &keychain).unwrap();
let tx2 = build::transaction(vec![build::input(105, key_id1.clone())], &keychain).unwrap();
assert_eq!(tx1.outputs[0].features, tx2.inputs[0].features);
assert_eq!(tx1.outputs[0].commitment(), tx2.inputs[0].commitment());
assert_eq!(tx1.outputs()[0].features, tx2.inputs()[0].features);
assert_eq!(tx1.outputs()[0].commitment(), tx2.inputs()[0].commitment());
}
}