Add handling for fallible signers (#8367)

automerge
This commit is contained in:
Tyera Eulberg
2020-02-20 20:04:53 -07:00
committed by GitHub
parent 18fd52367e
commit 0b7e8d0162
9 changed files with 181 additions and 83 deletions

View File

@@ -1,6 +1,6 @@
//! The `signature` module provides functionality for public, and private keys.
use crate::pubkey::Pubkey;
use crate::{pubkey::Pubkey, transaction::TransactionError};
use generic_array::{typenum::U64, GenericArray};
use hmac::Hmac;
use rand::{rngs::OsRng, CryptoRng, RngCore};
@@ -132,11 +132,11 @@ pub trait Signer {
fn pubkey(&self) -> Pubkey {
self.try_pubkey().unwrap_or_default()
}
fn try_pubkey(&self) -> Result<Pubkey, Box<dyn error::Error>>;
fn try_pubkey(&self) -> Result<Pubkey, SignerError>;
fn sign_message(&self, message: &[u8]) -> Signature {
self.try_sign_message(message).unwrap_or_default()
}
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, Box<dyn error::Error>>;
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError>;
}
impl Signer for Keypair {
@@ -145,7 +145,7 @@ impl Signer for Keypair {
Pubkey::new(self.0.public.as_ref())
}
fn try_pubkey(&self) -> Result<Pubkey, Box<dyn error::Error>> {
fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
Ok(self.pubkey())
}
@@ -153,7 +153,7 @@ impl Signer for Keypair {
Signature::new(&self.0.sign(message).to_bytes())
}
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, Box<dyn error::Error>> {
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
Ok(self.sign_message(message))
}
}
@@ -167,6 +167,41 @@ where
}
}
#[derive(Debug, Error, PartialEq)]
pub enum SignerError {
#[error("keypair-pubkey mismatch")]
KeypairPubkeyMismatch,
#[error("not enough signers")]
NotEnoughSigners,
#[error("transaction error")]
TransactionError(#[from] TransactionError),
#[error("custom error: {0}")]
CustomError(String),
// Presigner-specific Errors
#[error("presigner error")]
PresignerError(#[from] PresignerError),
// Remote Keypair-specific Errors
#[error("connection error: {0}")]
ConnectionError(String),
#[error("invalid input: {0}")]
InvalidInput(String),
#[error("no device found")]
NoDeviceFound,
#[error("device protocol error: {0}")]
Protocol(String),
#[error("operation has been cancelled")]
UserCancel,
}
#[derive(Debug, Default)]
pub struct Presigner {
pubkey: Pubkey,
@@ -184,17 +219,17 @@ impl Presigner {
}
#[derive(Debug, Error, PartialEq)]
enum PresignerError {
pub enum PresignerError {
#[error("pre-generated signature cannot verify data")]
VerificationFailure,
}
impl Signer for Presigner {
fn try_pubkey(&self) -> Result<Pubkey, Box<dyn error::Error>> {
fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
Ok(self.pubkey)
}
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, Box<dyn error::Error>> {
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
if self.signature.verify(self.pubkey.as_ref(), message) {
Ok(self.signature)
} else {