near_primitives/
validator_signer.rs

1use std::fmt::Debug;
2use std::path::Path;
3use std::sync::Arc;
4
5use near_crypto::{InMemorySigner, KeyType, PublicKey, Signature, Signer};
6
7use crate::types::AccountId;
8
9/// Enum for validator signer, that holds validator id and key used for signing data.
10#[derive(Clone, Debug, PartialEq)]
11pub enum ValidatorSigner {
12    /// Dummy validator signer, does not hold a key. Use for tests only!
13    Empty(EmptyValidatorSigner),
14    /// Default validator signer that holds data in memory.
15    InMemory(InMemoryValidatorSigner),
16}
17
18/// Validator signer that is used to sign blocks and approvals.
19impl ValidatorSigner {
20    /// Account id of the given validator.
21    pub fn validator_id(&self) -> &AccountId {
22        match self {
23            ValidatorSigner::Empty(signer) => signer.validator_id(),
24            ValidatorSigner::InMemory(signer) => signer.validator_id(),
25        }
26    }
27
28    /// Public key that identifies this validator.
29    pub fn public_key(&self) -> PublicKey {
30        match self {
31            ValidatorSigner::Empty(signer) => signer.public_key(),
32            ValidatorSigner::InMemory(signer) => signer.public_key(),
33        }
34    }
35
36    pub fn sign_bytes(&self, data: &[u8]) -> Signature {
37        match self {
38            ValidatorSigner::Empty(signer) => signer.noop_signature(),
39            ValidatorSigner::InMemory(signer) => signer.sign_bytes(data),
40        }
41    }
42
43    pub fn compute_vrf_with_proof(
44        &self,
45        data: &[u8],
46    ) -> (near_crypto::vrf::Value, near_crypto::vrf::Proof) {
47        match self {
48            ValidatorSigner::Empty(_) => unimplemented!(),
49            ValidatorSigner::InMemory(signer) => signer.compute_vrf_with_proof(data),
50        }
51    }
52
53    /// Used by test infrastructure, only implement if make sense for testing otherwise raise `unimplemented`.
54    pub fn write_to_file(&self, path: &Path) -> std::io::Result<()> {
55        match self {
56            ValidatorSigner::Empty(_) => unimplemented!(),
57            ValidatorSigner::InMemory(signer) => signer.write_to_file(path),
58        }
59    }
60}
61
62impl From<EmptyValidatorSigner> for ValidatorSigner {
63    fn from(signer: EmptyValidatorSigner) -> Self {
64        ValidatorSigner::Empty(signer)
65    }
66}
67
68/// Test-only signer that "signs" everything with 0s.
69/// Don't use in any production or code that requires signature verification.
70#[derive(smart_default::SmartDefault, Clone, Debug, PartialEq)]
71pub struct EmptyValidatorSigner {
72    #[default("test".parse().unwrap())]
73    account_id: AccountId,
74}
75
76impl EmptyValidatorSigner {
77    pub fn new(account_id: AccountId) -> ValidatorSigner {
78        ValidatorSigner::Empty(Self { account_id })
79    }
80
81    fn validator_id(&self) -> &AccountId {
82        &self.account_id
83    }
84
85    fn public_key(&self) -> PublicKey {
86        PublicKey::empty(KeyType::ED25519)
87    }
88
89    fn noop_signature(&self) -> Signature {
90        Signature::default()
91    }
92}
93
94/// Signer that keeps secret key in memory and signs locally.
95#[derive(Clone, Debug, PartialEq)]
96pub struct InMemoryValidatorSigner {
97    account_id: AccountId,
98    signer: Arc<Signer>,
99}
100
101impl InMemoryValidatorSigner {
102    #[cfg(feature = "rand")]
103    pub fn from_random(account_id: AccountId, key_type: KeyType) -> ValidatorSigner {
104        let signer = Arc::new(InMemorySigner::from_random(account_id.clone(), key_type).into());
105        ValidatorSigner::InMemory(Self { account_id, signer })
106    }
107
108    #[cfg(feature = "rand")]
109    pub fn from_seed(account_id: AccountId, key_type: KeyType, seed: &str) -> ValidatorSigner {
110        let signer = Arc::new(InMemorySigner::from_seed(account_id.clone(), key_type, seed));
111        ValidatorSigner::InMemory(Self { account_id, signer })
112    }
113
114    pub fn public_key(&self) -> PublicKey {
115        self.signer.public_key()
116    }
117
118    pub fn from_signer(signer: Signer) -> ValidatorSigner {
119        ValidatorSigner::InMemory(Self {
120            account_id: signer.get_account_id(),
121            signer: Arc::new(signer),
122        })
123    }
124
125    pub fn from_file(path: &Path) -> std::io::Result<ValidatorSigner> {
126        let signer = InMemorySigner::from_file(path)?;
127        Ok(Self::from_signer(signer))
128    }
129
130    pub fn validator_id(&self) -> &AccountId {
131        &self.account_id
132    }
133
134    fn sign_bytes(&self, bytes: &[u8]) -> Signature {
135        self.signer.sign(bytes)
136    }
137
138    fn compute_vrf_with_proof(
139        &self,
140        data: &[u8],
141    ) -> (near_crypto::vrf::Value, near_crypto::vrf::Proof) {
142        self.signer.compute_vrf_with_proof(data)
143    }
144
145    fn write_to_file(&self, path: &Path) -> std::io::Result<()> {
146        self.signer.write_to_file(path)
147    }
148}