From 4e49b85b8233741243b5895cbc9a8f173b3dd2ee Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Tue, 3 Oct 2017 22:27:26 +0000 Subject: [PATCH] Cleanup for block validation errors --- core/src/core/block.rs | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/core/src/core/block.rs b/core/src/core/block.rs index be21d602b..51f581d5a 100644 --- a/core/src/core/block.rs +++ b/core/src/core/block.rs @@ -28,7 +28,6 @@ use ser::{self, Readable, Reader, Writeable, Writer}; use global; use keychain; - bitflags! { /// Options for block validation pub flags BlockFeatures: u8 { @@ -37,6 +36,23 @@ bitflags! { } } +/// Errors thrown by Block validation +#[derive(Debug, PartialEq)] +pub enum Error { + /// The sum of output minus input commitments does not match the sum of + /// kernel commitments + KernelSumMismatch, + /// Underlying Secp256k1 error (signature validation or invalid public + /// key typically) + Secp(secp::Error), +} + +impl From for Error { + fn from(e: secp::Error) -> Error { + Error::Secp(e) + } +} + /// Block header, fairly standard compared to other blockchains. #[derive(Clone, Debug, PartialEq)] pub struct BlockHeader { @@ -400,18 +416,17 @@ 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, secp: &Secp256k1) -> Result<(), secp::Error> { + /// additional data. Includes commitment sums and kernels, Merkle + /// trees, reward, etc. + pub fn validate(&self, secp: &Secp256k1) -> Result<(), Error> { self.verify_coinbase(secp)?; self.verify_kernels(secp)?; Ok(()) } /// Validate the sum of input/output commitments match the sum in kernels - /// and - /// that all kernel signatures are valid. - pub fn verify_kernels(&self, secp: &Secp256k1) -> Result<(), secp::Error> { + /// and that all kernel signatures are valid. + pub fn verify_kernels(&self, secp: &Secp256k1) -> Result<(), Error> { // sum all inputs and outs commitments let io_sum = self.sum_commitments(secp)?; @@ -421,8 +436,7 @@ impl Block { // both should be the same if proof_sum != io_sum { - // TODO more specific error - return Err(secp::Error::IncorrectCommitSum); + return Err(Error::KernelSumMismatch); } // verify all signatures with the commitment as pk @@ -437,7 +451,7 @@ impl Block { // * That the sum of all coinbase-marked outputs equal the supply. // * That the sum of blinding factors for all coinbase-marked outputs match // the coinbase-marked kernels. - fn verify_coinbase(&self, secp: &Secp256k1) -> Result<(), secp::Error> { + fn verify_coinbase(&self, secp: &Secp256k1) -> Result<(), Error> { let cb_outs = self.outputs .iter() .filter(|out| out.features.contains(COINBASE_OUTPUT)) @@ -617,13 +631,13 @@ mod test { assert_eq!( b.verify_coinbase(&keychain.secp()), - Err(secp::Error::IncorrectCommitSum) + Err(Error::KernelSumMismatch) ); assert_eq!(b.verify_kernels(&keychain.secp()), Ok(())); assert_eq!( b.validate(&keychain.secp()), - Err(secp::Error::IncorrectCommitSum) + Err(Error::KernelSumMismatch) ); } @@ -639,13 +653,13 @@ mod test { assert_eq!( b.verify_coinbase(&keychain.secp()), - Err(secp::Error::IncorrectCommitSum) + Err(Error::Secp(secp::Error::IncorrectCommitSum)) ); assert_eq!(b.verify_kernels(&keychain.secp()), Ok(())); assert_eq!( b.validate(&keychain.secp()), - Err(secp::Error::IncorrectCommitSum) + Err(Error::Secp(secp::Error::IncorrectCommitSum)) ); }