Add Display and FromStr for EcdsaSig

This commit is contained in:
Dr Maxim Orlovsky 2022-01-06 12:01:05 +01:00
parent daf0eacf3d
commit 0af1c3f320
1 changed files with 42 additions and 5 deletions

View File

@ -25,11 +25,12 @@ use io;
use secp256k1::{self, Secp256k1}; use secp256k1::{self, Secp256k1};
use network::constants::Network; use network::constants::Network;
use hashes::{Hash, hash160}; use hashes::{Hash, hash160, hex};
use hashes::hex::FromHex;
use hash_types::{PubkeyHash, WPubkeyHash}; use hash_types::{PubkeyHash, WPubkeyHash};
use util::base58; use util::base58;
use util::key::Error; use util::key::Error;
use blockdata::transaction::EcdsaSigHashType; use blockdata::transaction::{EcdsaSigHashType, NonStandardSigHashType};
/// A Bitcoin ECDSA public key /// A Bitcoin ECDSA public key
@ -426,7 +427,7 @@ pub struct EcdsaSig {
impl EcdsaSig { impl EcdsaSig {
/// Constructs ECDSA bitcoin signature for [`EcdsaSigHashType::All`] /// Constructs ECDSA bitcoin signature for [`EcdsaSigHashType::All`]
pub fn sighash_all(sig: secp256k1::Signature) -> EcdsaSig { pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> EcdsaSig {
EcdsaSig { EcdsaSig {
sig, sig,
hash_ty: EcdsaSigHashType::All hash_ty: EcdsaSigHashType::All
@ -438,7 +439,7 @@ impl EcdsaSig {
let (hash_ty, sig) = sl.split_last() let (hash_ty, sig) = sl.split_last()
.ok_or(EcdsaSigError::EmptySignature)?; .ok_or(EcdsaSigError::EmptySignature)?;
let hash_ty = EcdsaSigHashType::from_u32_standard(*hash_ty as u32) let hash_ty = EcdsaSigHashType::from_u32_standard(*hash_ty as u32)
.map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty))?; .map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty as u32))?;
let sig = secp256k1::ecdsa::Signature::from_der(sig) let sig = secp256k1::ecdsa::Signature::from_der(sig)
.map_err(EcdsaSigError::Secp256k1)?; .map_err(EcdsaSigError::Secp256k1)?;
Ok(EcdsaSig { sig, hash_ty }) Ok(EcdsaSig { sig, hash_ty })
@ -453,11 +454,34 @@ impl EcdsaSig {
} }
} }
impl fmt::Display for EcdsaSig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
hex::format_hex(&self.sig.serialize_der(), f)?;
hex::format_hex(&[self.hash_ty as u8], f)
}
}
impl FromStr for EcdsaSig {
type Err = EcdsaSigError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = Vec::from_hex(s)?;
let (sighash_byte, signature) = bytes.split_last()
.ok_or(EcdsaSigError::EmptySignature)?;
Ok(EcdsaSig {
sig: secp256k1::ecdsa::Signature::from_der(signature)?,
hash_ty: EcdsaSigHashType::from_u32_standard(*sighash_byte as u32)?
})
}
}
/// A key-related error. /// A key-related error.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum EcdsaSigError { pub enum EcdsaSigError {
/// Hex encoding error
HexEncoding(hex::Error),
/// Base58 encoding error /// Base58 encoding error
NonStandardSigHashType(u8), NonStandardSigHashType(u32),
/// Empty Signature /// Empty Signature
EmptySignature, EmptySignature,
/// secp256k1-related error /// secp256k1-related error
@ -474,6 +498,7 @@ impl fmt::Display for EcdsaSigError {
write!(f, "Invalid Ecdsa signature: {}", e), write!(f, "Invalid Ecdsa signature: {}", e),
EcdsaSigError::EmptySignature => EcdsaSigError::EmptySignature =>
write!(f, "Empty ECDSA signature"), write!(f, "Empty ECDSA signature"),
EcdsaSigError::HexEncoding(e) => write!(f, "EcdsaSig hex encoding error: {}", e)
} }
} }
} }
@ -488,6 +513,18 @@ impl From<secp256k1::Error> for EcdsaSigError {
} }
} }
impl From<NonStandardSigHashType> for EcdsaSigError {
fn from(err: NonStandardSigHashType) -> Self {
EcdsaSigError::NonStandardSigHashType(err.0)
}
}
impl From<hex::Error> for EcdsaSigError {
fn from(err: hex::Error) -> Self {
EcdsaSigError::HexEncoding(err)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use io; use io;