From 2dcc45ad819c0474e6c7b229c3792b02e5124527 Mon Sep 17 00:00:00 2001
From: stefan-mysten <135084671+stefan-mysten@users.noreply.github.com>
Date: Mon, 4 Dec 2023 11:22:06 -0800
Subject: [PATCH] [cli/alias] Add alias to keytool list (#15168)
## Description
Display alias for each key when calling `sui keytool list`.
## Test Plan
Extra tests added for new keystore APIs that were introduced.
---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.
### Type of Change (Check all that apply)
- [ ] protocol change
- [x] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration
### Release notes
Added functionality to show the aliases of each address when calling the
`sui keytool list` command.
---
crates/sui-keys/src/keystore.rs | 6 +++---
crates/sui-keys/tests/tests.rs | 16 ++++++++++++++++
crates/sui/src/keytool.rs | 15 +++++++++++----
3 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/crates/sui-keys/src/keystore.rs b/crates/sui-keys/src/keystore.rs
index 930742ec8c02f..14584adad9b3d 100644
--- a/crates/sui-keys/src/keystore.rs
+++ b/crates/sui-keys/src/keystore.rs
@@ -55,8 +55,8 @@ pub trait AccountKeystore: Send + Sync {
.map(|a| a.alias.as_str())
.collect()
}
+ /// Get alias of address
fn get_alias_by_address(&self, address: &SuiAddress) -> Result;
-
/// Check if an alias exists by its name
fn alias_exists(&self, alias: &str) -> bool {
self.alias_names().contains(&alias)
@@ -225,7 +225,7 @@ impl AccountKeystore for FileBasedKeystore {
}
}
- /// Get the alias if it exists, or return an error if it does not exist.
+ /// Get alias of address
fn get_alias_by_address(&self, address: &SuiAddress) -> Result {
match self.aliases.get(address) {
Some(alias) => Ok(alias.alias.clone()),
@@ -455,7 +455,7 @@ impl AccountKeystore for InMemKeystore {
}
}
- /// Get an alias by its address
+ /// Get alias of address
fn get_alias_by_address(&self, address: &SuiAddress) -> Result {
match self.aliases.get(address) {
Some(alias) => Ok(alias.alias.clone()),
diff --git a/crates/sui-keys/tests/tests.rs b/crates/sui-keys/tests/tests.rs
index daf4111f3822f..815498712f652 100644
--- a/crates/sui-keys/tests/tests.rs
+++ b/crates/sui-keys/tests/tests.rs
@@ -174,3 +174,19 @@ fn keystore_display_test() -> Result<(), anyhow::Error> {
assert!(!keystore.to_string().contains("keys:"));
Ok(())
}
+
+#[test]
+fn get_alias_by_address_test() {
+ let temp_dir = TempDir::new().unwrap();
+ let keystore_path = temp_dir.path().join("sui.keystore");
+ let mut keystore = Keystore::from(FileBasedKeystore::new(&keystore_path).unwrap());
+ let alias = "my_alias_test".to_string();
+ let keypair = keystore
+ .generate_and_add_new_key(SignatureScheme::ED25519, Some(alias.clone()), None, None)
+ .unwrap();
+ assert_eq!(alias, keystore.get_alias_by_address(&keypair.0).unwrap());
+
+ // Test getting an alias of an address that is not in keystore
+ let address = generate_new_key(SignatureScheme::ED25519, None, None).unwrap();
+ assert!(keystore.get_alias_by_address(&address.0).is_err())
+}
diff --git a/crates/sui/src/keytool.rs b/crates/sui/src/keytool.rs
index b6de2c7c5fad4..156236fc6bab2 100644
--- a/crates/sui/src/keytool.rs
+++ b/crates/sui/src/keytool.rs
@@ -278,6 +278,7 @@ pub struct DecodedMultiSigOutput {
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Key {
+ alias: Option,
sui_address: SuiAddress,
public_base64_key: String,
key_scheme: String,
@@ -487,6 +488,7 @@ impl KeyToolCommand {
let file_name = format!("bls-{sui_address}.key");
write_authority_keypair_to_file(&kp, file_name)?;
CommandOutput::Generate(Key {
+ alias: None,
sui_address,
public_base64_key: kp.public().encode_base64(),
key_scheme: key_scheme.to_string(),
@@ -551,9 +553,12 @@ impl KeyToolCommand {
let keys = keystore
.keys()
.into_iter()
- .map(Key::from)
- .collect::>();
-
+ .map(|pk| {
+ let mut key = Key::from(pk);
+ key.alias = keystore.get_alias_by_address(&key.sui_address).ok();
+ key
+ })
+ .collect();
CommandOutput::List(keys)
}
@@ -667,6 +672,7 @@ impl KeyToolCommand {
Ok(keypair) => {
let public_base64_key = keypair.public().encode_base64();
CommandOutput::Show(Key {
+ alias: None, // alias does not get stored in key files
sui_address: (keypair.public()).into(),
public_base64_key,
key_scheme: SignatureScheme::BLS12381.to_string(),
@@ -1046,7 +1052,8 @@ impl From<&SuiKeyPair> for Key {
impl From for Key {
fn from(key: PublicKey) -> Self {
Key {
- sui_address: Into::::into(&key),
+ alias: None, // this is retrieved later
+ sui_address: SuiAddress::from(&key),
public_base64_key: key.encode_base64(),
key_scheme: key.scheme().to_string(),
mnemonic: None,