1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0
// Copyright 2021 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/
use serde::Serialize;
use diem_crypto::hash::CryptoHash;
use diem_global_constants::CONSENSUS_KEY;
use diem_types::{
account_address::AccountAddress,
validator_config::{
ConsensusPrivateKey, ConsensusPublicKey, ConsensusSignature,
ConsensusVRFPrivateKey,
},
validator_signer::ValidatorSigner,
};
use crate::{Error, PersistentSafetyStorage};
/// A ConfigurableValidatorSigner is a ValidatorSigner wrapper that offers
/// either a ValidatorSigner instance or a ValidatorHandle instance, depending
/// on the configuration chosen. This abstracts away the complexities of
/// handling either instance, while offering the same API as a ValidatorSigner.
pub enum ConfigurableValidatorSigner {
Signer(ValidatorSigner),
Handle(ValidatorHandle),
}
impl ConfigurableValidatorSigner {
/// Returns a new ValidatorSigner instance
pub fn new_signer(
author: AccountAddress, consensus_key: ConsensusPrivateKey,
vrf_private_key: Option<ConsensusVRFPrivateKey>,
) -> Self {
let signer =
ValidatorSigner::new(author, consensus_key, vrf_private_key);
ConfigurableValidatorSigner::Signer(signer)
}
/// Returns a new ValidatorHandle instance
pub fn new_handle(
author: AccountAddress, key_version: ConsensusPublicKey,
) -> Self {
let handle = ValidatorHandle::new(author, key_version);
ConfigurableValidatorSigner::Handle(handle)
}
/// Returns the author associated with the signer configuration.
pub fn author(&self) -> AccountAddress {
match self {
ConfigurableValidatorSigner::Signer(signer) => signer.author(),
ConfigurableValidatorSigner::Handle(handle) => handle.author(),
}
}
/// Returns the public key associated with the signer configuration.
pub fn public_key(&self) -> ConsensusPublicKey {
match self {
ConfigurableValidatorSigner::Signer(signer) => signer.public_key(),
ConfigurableValidatorSigner::Handle(handle) => handle.key_version(),
}
}
/// Signs a given message using the signer configuration.
pub fn sign<T: Serialize + CryptoHash>(
&self, message: &T, storage: &PersistentSafetyStorage,
) -> Result<ConsensusSignature, Error> {
match self {
ConfigurableValidatorSigner::Signer(signer) => {
Ok(signer.sign(message))
}
ConfigurableValidatorSigner::Handle(handle) => {
handle.sign(message, storage)
}
}
}
}
/// A ValidatorHandle associates a validator with a consensus key version held
/// in storage. In contrast to a ValidatorSigner, ValidatorHandle does not hold
/// the private key directly but rather holds a reference to that private key
/// which should be accessed using the handle and the secure storage backend.
pub struct ValidatorHandle {
author: AccountAddress,
key_version: ConsensusPublicKey,
}
impl ValidatorHandle {
pub fn new(
author: AccountAddress, key_version: ConsensusPublicKey,
) -> Self {
ValidatorHandle {
author,
key_version,
}
}
/// Returns the author associated with this handle.
pub fn author(&self) -> AccountAddress { self.author }
/// Returns the public key version associated with this handle.
pub fn key_version(&self) -> ConsensusPublicKey { self.key_version.clone() }
/// Signs a given message using this handle and a given secure storage
/// backend.
pub fn sign<T: Serialize + CryptoHash>(
&self, message: &T, storage: &PersistentSafetyStorage,
) -> Result<ConsensusSignature, Error> {
storage.sign(CONSENSUS_KEY.into(), self.key_version(), message)
}
}