Skip to content

Commit

Permalink
refactor(InMemorySigner) factory methods to return Signer interface
Browse files Browse the repository at this point in the history
Following the issue #11531, the Signer/ValidatorSigner wrapper
interfaces should be used. The commit implements migration to Signer
wrapper for following InMemorySigner factory functions:
- InMemorySigner::from_seed
- InMemorySigner::from_file
Additionally:
- The Signer interface is extented by get_acount_id method
- Added From<Signer> for KeyFile implementation
  • Loading branch information
mkamonMdt committed Dec 5, 2024
1 parent 6af8e01 commit b6dcadc
Show file tree
Hide file tree
Showing 37 changed files with 263 additions and 275 deletions.
37 changes: 17 additions & 20 deletions chain/chain/src/runtime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ fn test_verify_validator_signature() {
(0..2).map(|i| AccountId::try_from(format!("test{}", i + 1)).unwrap()).collect::<Vec<_>>();
let env = TestEnv::new(vec![validators.clone()], 2, true);
let data = [0; 32];
let signer = InMemorySigner::test(&validators[0]);
let signer = InMemorySigner::test_signer(&validators[0]);
let signature = signer.sign(&data);
assert!(env
.epoch_manager
Expand Down Expand Up @@ -1371,17 +1371,17 @@ fn test_delete_account_after_unstake() {
let mut env = TestEnv::new(vec![validators.clone()], 4, false);
let block_producers: Vec<_> =
validators.iter().map(|id| create_test_signer(id.as_str())).collect();
let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test(&id)).collect();
let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test_signer(&id)).collect();

let staking_transaction1 = stake(1, &signers[1].clone().into(), &block_producers[1], 0);
let staking_transaction1 = stake(1, &signers[1], &block_producers[1], 0);
env.step_default(vec![staking_transaction1]);
let account = env.view_account(block_producers[1].validator_id());
assert_eq!(account.amount, TESTING_INIT_BALANCE - TESTING_INIT_STAKE);
assert_eq!(account.locked, TESTING_INIT_STAKE);
for _ in 2..=5 {
env.step_default(vec![]);
}
let staking_transaction2 = stake(2, &signers[1].clone().into(), &block_producers[1], 1);
let staking_transaction2 = stake(2, &signers[1], &block_producers[1], 1);
env.step_default(vec![staking_transaction2]);
for _ in 7..=13 {
env.step_default(vec![]);
Expand All @@ -1391,11 +1391,11 @@ fn test_delete_account_after_unstake() {

let delete_account_transaction = SignedTransaction::from_actions(
4,
signers[1].account_id.clone(),
signers[1].account_id.clone(),
&signers[1].clone().into(),
signers[1].get_account_id(),
signers[1].get_account_id(),
&signers[1],
vec![Action::DeleteAccount(DeleteAccountAction {
beneficiary_id: signers[0].account_id.clone(),
beneficiary_id: signers[0].get_account_id(),
})],
// runtime does not validate block history
CryptoHash::default(),
Expand Down Expand Up @@ -1471,13 +1471,13 @@ fn test_trie_and_flat_state_equality() {
.map(|i| AccountId::try_from(format!("test{}", i + 1)).unwrap())
.collect::<Vec<_>>();
let mut env = TestEnv::new(vec![validators.clone()], 4, false);
let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test(&id)).collect();
let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test_signer(&id)).collect();

let transfer_tx = SignedTransaction::from_actions(
4,
signers[0].account_id.clone(),
signers[0].get_account_id(),
validators[1].clone(),
&signers[0].clone().into(),
&signers[0],
vec![Action::Transfer(TransferAction { deposit: 10 })],
// runtime does not validate block history
CryptoHash::default(),
Expand Down Expand Up @@ -1559,10 +1559,7 @@ fn test_genesis_hash() {
/// Creates a signed transaction between each pair of `signers`,
/// where transactions outcoming from a single signer differ by nonce.
/// The transactions are then shuffled and used to fill a transaction pool.
fn generate_transaction_pool(
signers: &Vec<InMemorySigner>,
block_hash: CryptoHash,
) -> TransactionPool {
fn generate_transaction_pool(signers: &Vec<Signer>, block_hash: CryptoHash) -> TransactionPool {
const TEST_SEED: RngSeed = [3; 32];
let mut rng = StdRng::from_seed(TEST_SEED);
let signer_count = signers.len();
Expand All @@ -1572,9 +1569,9 @@ fn generate_transaction_pool(
for i in 0..signer_count {
let transaction = SignedTransaction::send_money(
round.try_into().unwrap(),
signers[i].account_id.clone(),
signers[(i + round) % signer_count].account_id.clone(),
&signers[i].clone().into(),
signers[i].get_account_id(),
signers[(i + round) % signer_count].get_account_id(),
&signers[i],
round.try_into().unwrap(),
block_hash,
);
Expand Down Expand Up @@ -1627,7 +1624,7 @@ fn get_test_env_with_chain_and_pool() -> (TestEnv, Chain, TransactionPool) {
// Produce a single block, so that `prev_block_hash` is valid.
env.step_default(vec![]);

let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test(&id)).collect();
let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test_signer(&id)).collect();

let transaction_pool = generate_transaction_pool(&signers, env.head.prev_block_hash);
(env, chain, transaction_pool)
Expand Down Expand Up @@ -1876,7 +1873,7 @@ fn stake(
nonce,
sender.validator_id().clone(),
sender.validator_id().clone(),
&*signer,
&signer,
vec![Action::Stake(Box::new(StakeAction { stake, public_key: sender.public_key() }))],
// runtime does not validate block history
CryptoHash::default(),
Expand Down
2 changes: 1 addition & 1 deletion chain/chain/src/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ mod tests {
nonce,
account_id,
"bob".parse().unwrap(),
&signer.into(),
&signer,
10,
CryptoHash::default(),
)
Expand Down
2 changes: 1 addition & 1 deletion chain/chunks/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ mod tests {
nonce,
signer_id.clone(),
receiver_id.clone(),
&signer.into(),
&signer,
deposit,
CryptoHash::default(),
);
Expand Down
16 changes: 8 additions & 8 deletions chain/client/src/test_utils/test_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use near_chain_configs::GenesisConfig;
use near_chain_primitives::error::QueryError;
use near_chunks::client::ShardsManagerResponse;
use near_chunks::test_utils::{MockClientAdapterForShardsManager, SynchronousShardsManagerAdapter};
use near_crypto::InMemorySigner;
use near_crypto::{InMemorySigner, Signer};
use near_network::client::ProcessTxResponse;
use near_network::shards_manager::ShardsManagerRequestFromNetwork;
use near_network::test_utils::MockPeerManagerAdapter;
Expand Down Expand Up @@ -737,15 +737,15 @@ impl TestEnv {
pub fn tx_from_actions(
&mut self,
actions: Vec<Action>,
signer: &InMemorySigner,
signer: &Signer,
receiver: AccountId,
) -> SignedTransaction {
let tip = self.clients[0].chain.head().unwrap();
SignedTransaction::from_actions(
tip.height + 1,
signer.account_id.clone(),
signer.get_account_id(),
receiver,
&signer.clone().into(),
&signer,
actions,
tip.last_block_hash,
0,
Expand All @@ -760,13 +760,13 @@ impl TestEnv {
relayer: AccountId,
receiver_id: AccountId,
) -> SignedTransaction {
let inner_signer = InMemorySigner::test(&sender);
let inner_signer = InMemorySigner::test_signer(&sender);
let relayer_signer = InMemorySigner::test_signer(&relayer);
let tip = self.clients[0].chain.head().unwrap();
let user_nonce = tip.height + 1;
let relayer_nonce = tip.height + 1;
let delegate_action = DelegateAction {
sender_id: inner_signer.account_id.clone(),
sender_id: inner_signer.get_account_id(),
receiver_id,
actions: actions
.into_iter()
Expand Down Expand Up @@ -821,14 +821,14 @@ impl TestEnv {
/// `InMemorySigner::from_seed` produces a valid signer that has it's key
/// deployed already.
pub fn call_main(&mut self, account: &AccountId) -> FinalExecutionOutcomeView {
let signer = InMemorySigner::test(&account.clone());
let signer = InMemorySigner::test_signer(&account);
let actions = vec![Action::FunctionCall(Box::new(FunctionCallAction {
method_name: "main".to_string(),
args: vec![],
gas: 3 * 10u64.pow(14),
deposit: 0,
}))];
let tx = self.tx_from_actions(actions, &signer, signer.account_id.clone());
let tx = self.tx_from_actions(actions, &signer, signer.get_account_id());
self.execute_tx(tx).unwrap()
}

Expand Down
14 changes: 7 additions & 7 deletions chain/pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,8 @@ mod tests {
end_nonce: u64,
) -> Vec<SignedTransaction> {
let signer_id: AccountId = signer_id.parse().unwrap();
let signer = Arc::new(
InMemorySigner::from_seed(signer_id.clone(), KeyType::ED25519, signer_seed).into(),
);
let signer =
Arc::new(InMemorySigner::from_seed(signer_id.clone(), KeyType::ED25519, signer_seed));
(starting_nonce..=end_nonce)
.map(|i| {
SignedTransaction::send_money(
Expand Down Expand Up @@ -467,10 +466,11 @@ mod tests {
.map(|i| {
let signer_id = AccountId::try_from(format!("user_{}", i % 5)).unwrap();
let signer_seed = format!("user_{}", i % 3);
let signer = Arc::new(
InMemorySigner::from_seed(signer_id.clone(), KeyType::ED25519, &signer_seed)
.into(),
);
let signer = Arc::new(InMemorySigner::from_seed(
signer_id.clone(),
KeyType::ED25519,
&signer_seed,
));
SignedTransaction::send_money(
i,
signer_id,
Expand Down
50 changes: 27 additions & 23 deletions core/crypto/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ use near_account_id::AccountId;
use std::fmt::{self, Debug};
use std::io;
use std::path::Path;
use std::sync::Arc;

/// Enum for Signer, that can sign with some subset of supported curves.
#[derive(Debug, PartialEq)]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
pub enum Signer {
/// Dummy signer, does not hold a key. Use for tests only!
Empty(EmptySigner),
Expand Down Expand Up @@ -50,6 +49,13 @@ impl Signer {
Signer::InMemory(signer) => signer.write_to_file(path),
}
}

pub fn get_account_id(&self) -> AccountId {
match self {
Signer::Empty(_) => unimplemented!(),
Signer::InMemory(signer) => signer.account_id.clone(),
}
}
}

impl From<EmptySigner> for Signer {
Expand All @@ -64,8 +70,21 @@ impl From<InMemorySigner> for Signer {
}
}

impl From<Signer> for KeyFile {
fn from(signer: Signer) -> KeyFile {
match signer {
Signer::Empty(_) => unimplemented!(),
Signer::InMemory(signer) => KeyFile {
account_id: signer.account_id,
public_key: signer.public_key,
secret_key: signer.secret_key,
},
}
}
}

// Signer that returns empty signature. Used for transaction testing.
#[derive(Debug, PartialEq)]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
pub struct EmptySigner {}

impl EmptySigner {
Expand All @@ -92,17 +111,17 @@ pub struct InMemorySigner {

impl InMemorySigner {
#[cfg(feature = "rand")]
pub fn from_seed(account_id: AccountId, key_type: KeyType, seed: &str) -> Self {
pub fn from_seed(account_id: AccountId, key_type: KeyType, seed: &str) -> Signer {
let secret_key = SecretKey::from_seed(key_type, seed);
Self { account_id, public_key: secret_key.public_key(), secret_key }
Signer::InMemory(Self { account_id, public_key: secret_key.public_key(), secret_key })
}

pub fn from_secret_key(account_id: AccountId, secret_key: SecretKey) -> Self {
Self { account_id, public_key: secret_key.public_key(), secret_key }
}

pub fn from_file(path: &Path) -> io::Result<Self> {
KeyFile::from_file(path).map(Self::from)
pub fn from_file(path: &Path) -> io::Result<Signer> {
KeyFile::from_file(path).map(Self::from).map(|s| Signer::InMemory(s))
}

pub fn public_key(&self) -> PublicKey {
Expand All @@ -122,14 +141,9 @@ impl InMemorySigner {
KeyFile::from(self).write_to_file(path)
}

#[cfg(feature = "rand")]
pub fn test(account_id: &AccountId) -> Self {
InMemorySigner::from_seed(account_id.clone(), KeyType::ED25519, account_id.as_ref())
}

#[cfg(feature = "rand")]
pub fn test_signer(account_id: &AccountId) -> Signer {
InMemorySigner::test(account_id).into()
InMemorySigner::from_seed(account_id.clone(), KeyType::ED25519, account_id.as_ref())
}
}

Expand Down Expand Up @@ -162,13 +176,3 @@ impl From<&InMemorySigner> for KeyFile {
}
}
}

impl From<Arc<InMemorySigner>> for KeyFile {
fn from(signer: Arc<InMemorySigner>) -> KeyFile {
KeyFile {
account_id: signer.account_id.clone(),
public_key: signer.public_key.clone(),
secret_key: signer.secret_key.clone(),
}
}
}
3 changes: 2 additions & 1 deletion core/primitives/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,13 +1075,14 @@ pub fn create_test_signer(account_name: &str) -> ValidatorSigner {
#[cfg(feature = "rand")]
pub fn create_user_test_signer(
account_name: &near_primitives_core::account::id::AccountIdRef,
) -> near_crypto::InMemorySigner {
) -> near_crypto::Signer {
let account_id = account_name.to_owned();
if account_id == near_implicit_test_account() {
near_crypto::InMemorySigner::from_secret_key(
account_id,
near_implicit_test_account_secret(),
)
.into()
} else {
near_crypto::InMemorySigner::from_seed(
account_id,
Expand Down
6 changes: 3 additions & 3 deletions core/primitives/src/validator_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,16 @@ impl InMemoryValidatorSigner {
#[cfg(feature = "rand")]

pub fn from_seed(account_id: AccountId, key_type: KeyType, seed: &str) -> Self {
let signer = Arc::new(InMemorySigner::from_seed(account_id.clone(), key_type, seed).into());
let signer = Arc::new(InMemorySigner::from_seed(account_id.clone(), key_type, seed));
Self { account_id, signer }
}

pub fn public_key(&self) -> PublicKey {
self.signer.public_key()
}

pub fn from_signer(signer: InMemorySigner) -> Self {
Self { account_id: signer.account_id.clone(), signer: Arc::new(signer.into()) }
pub fn from_signer(signer: Signer) -> Self {
Self { account_id: signer.get_account_id(), signer: Arc::new(signer) }
}

pub fn from_file(path: &Path) -> std::io::Result<Self> {
Expand Down
6 changes: 3 additions & 3 deletions genesis-tools/genesis-populate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ impl GenesisBuilder {
let mut state_update =
self.state_updates.remove(&shard_id).expect("State update should have been added");

let signer = InMemorySigner::test(&account_id);
let signer = InMemorySigner::test_signer(&account_id);
let account = Account::new(
testing_init_balance,
testing_init_stake,
Expand All @@ -347,13 +347,13 @@ impl GenesisBuilder {
records.push(account_record);
let access_key_record = StateRecord::AccessKey {
account_id: account_id.clone(),
public_key: signer.public_key.clone(),
public_key: signer.public_key(),
access_key: AccessKey::full_access(),
};
set_access_key(
&mut state_update,
account_id.clone(),
signer.public_key,
signer.public_key(),
&AccessKey::full_access(),
);
records.push(access_key_record);
Expand Down
Loading

0 comments on commit b6dcadc

Please sign in to comment.