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 4, 2024
1 parent 4b309ed commit 8407e4f
Show file tree
Hide file tree
Showing 38 changed files with 283 additions and 268 deletions.
67 changes: 40 additions & 27 deletions chain/chain/src/runtime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use near_chain_configs::{
default_produce_chunk_add_transactions_time_limit, Genesis, MutableConfigValue,
DEFAULT_GC_NUM_EPOCHS_TO_KEEP, NEAR_BASE,
};
use near_crypto::{InMemorySigner, Signer};
use near_crypto::{InMemorySigner, KeyType, Signer};
use near_o11y::testonly::init_test_logger;
use near_primitives::block::Tip;
use near_primitives::challenge::{ChallengesResult, PartialState, SlashedValidator};
Expand Down Expand Up @@ -457,7 +457,8 @@ fn test_validator_rotation() {
let staking_transaction = stake(1, &signer, &block_producers[0], TESTING_INIT_STAKE * 2);
let new_account = AccountId::try_from(format!("test{}", num_nodes + 1)).unwrap();
let new_validator = create_test_signer(new_account.as_str());
let new_signer: Signer = InMemorySigner::test_signer(&new_account);
let new_signer: Signer =
InMemorySigner::from_seed(new_account.clone(), KeyType::ED25519, new_account.as_ref());
let create_account_transaction = SignedTransaction::create_account(
2,
block_producers[0].validator_id().clone(),
Expand All @@ -471,7 +472,7 @@ fn test_validator_rotation() {
let transactions = {
// With the new validator selection algorithm, test2 needs to have less stake to
// become a fisherman.
let signer = InMemorySigner::test_signer(&validators[1]);
let signer = InMemorySigner::test_signer(&validators[1].clone());
vec![
staking_transaction,
create_account_transaction,
Expand Down Expand Up @@ -567,7 +568,10 @@ fn test_validator_stake_change_multiple_times() {
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_signer(&id)).collect();
let signers: Vec<_> = validators
.iter()
.map(|id| InMemorySigner::from_seed(id.clone(), KeyType::ED25519, id.as_ref()))
.collect();

let staking_transaction = stake(1, &signers[0], &block_producers[0], TESTING_INIT_STAKE - 1);
let staking_transaction1 = stake(2, &signers[0], &block_producers[0], TESTING_INIT_STAKE - 2);
Expand Down Expand Up @@ -691,7 +695,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 @@ -1236,7 +1240,10 @@ fn test_fishermen_stake() {
);
let block_producers: Vec<_> =
validators.iter().map(|id| create_test_signer(id.as_str())).collect();
let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test_signer(&id)).collect();
let signers: Vec<_> = validators
.iter()
.map(|id| InMemorySigner::from_seed(id.clone(), KeyType::ED25519, id.as_ref()))
.collect();
let fishermen_stake = 3300 * NEAR_BASE + 1;

let staking_transaction = stake(1, &signers[0], &block_producers[0], fishermen_stake);
Expand Down Expand Up @@ -1300,7 +1307,10 @@ fn test_fishermen_unstake() {
);
let block_producers: Vec<_> =
validators.iter().map(|id| create_test_signer(id.as_str())).collect();
let signers: Vec<_> = validators.iter().map(|id| InMemorySigner::test_signer(&id)).collect();
let signers: Vec<_> = validators
.iter()
.map(|id| InMemorySigner::from_seed(id.clone(), KeyType::ED25519, id.as_ref()))
.collect();
let fishermen_stake = 3300 * NEAR_BASE + 1;

let staking_transaction = stake(1, &signers[0], &block_producers[0], fishermen_stake);
Expand Down Expand Up @@ -1371,17 +1381,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 +1401,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 All @@ -1416,7 +1426,10 @@ fn test_proposal_deduped() {
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_signer(&id)).collect();
let signers: Vec<_> = validators
.iter()
.map(|id| InMemorySigner::from_seed(id.clone(), KeyType::ED25519, id.as_ref()))
.collect();

let staking_transaction1 = stake(1, &signers[1], &block_producers[1], TESTING_INIT_STAKE - 100);
let staking_transaction2 = stake(2, &signers[1], &block_producers[1], TESTING_INIT_STAKE - 10);
Expand All @@ -1434,7 +1447,10 @@ fn test_insufficient_stake() {
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_signer(&id)).collect();
let signers: Vec<_> = validators
.iter()
.map(|id| InMemorySigner::from_seed(id.clone(), KeyType::ED25519, id.as_ref()))
.collect();

let staking_transaction1 = stake(1, &signers[1], &block_producers[1], 100);
let staking_transaction2 = stake(2, &signers[1], &block_producers[1], 100 * NEAR_BASE);
Expand Down Expand Up @@ -1471,13 +1487,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 +1575,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 +1585,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 +1640,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
2 changes: 1 addition & 1 deletion chain/chain/src/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,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
41 changes: 28 additions & 13 deletions core/crypto/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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 +50,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 +71,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 +112,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 {
pub fn from_secret_key(account_id: AccountId, secret_key: SecretKey) -> InMemorySigner {
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 +142,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
4 changes: 2 additions & 2 deletions core/primitives/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1069,13 +1069,13 @@ 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
Loading

0 comments on commit 8407e4f

Please sign in to comment.