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:
@@ -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
@@ -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)?;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user