Hide Keybase and replace with URL (#31852)

This commit is contained in:
Michael 2023-06-06 15:22:55 +02:00 committed by GitHub
parent 4227d0ee35
commit 2f4a189d47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 31 deletions

View File

@ -1,6 +1,6 @@
use solana_config_program::ConfigState;
pub const MAX_SHORT_FIELD_LENGTH: usize = 70;
pub const MAX_SHORT_FIELD_LENGTH: usize = 80;
pub const MAX_LONG_FIELD_LENGTH: usize = 300;
pub const MAX_VALIDATOR_INFO: u64 = 576;

View File

@ -3,7 +3,7 @@ use {
cli::{CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult},
spend_utils::{resolve_spend_tx_and_check_account_balance, SpendAmount},
},
bincode::deserialize,
bincode::{deserialize, serialized_size},
clap::{App, AppSettings, Arg, ArgMatches, SubCommand},
reqwest::blocking::Client,
serde_json::{Map, Value},
@ -41,6 +41,19 @@ pub fn check_details_length(string: String) -> Result<(), String> {
}
}
pub fn check_total_length(info: &ValidatorInfo) -> Result<(), String> {
let size = serialized_size(&info).unwrap();
let limit = ValidatorInfo::max_space();
if size > limit {
Err(format!(
"Total size {size:?} exceeds limit of {limit:?} bytes"
))
} else {
Ok(())
}
}
// Return an error if url field is too long or cannot be parsed.
pub fn check_url(string: String) -> Result<(), String> {
is_url(string.clone())?;
@ -91,6 +104,10 @@ fn parse_args(matches: &ArgMatches<'_>) -> Value {
if let Some(url) = matches.value_of("website") {
map.insert("website".to_string(), Value::String(url.to_string()));
}
if let Some(icon_url) = matches.value_of("icon_url") {
map.insert("iconUrl".to_string(), Value::String(icon_url.to_string()));
}
if let Some(details) = matches.value_of("details") {
map.insert("details".to_string(), Value::String(details.to_string()));
}
@ -161,6 +178,15 @@ impl ValidatorInfoSubCommands for App<'_, '_> {
.validator(check_url)
.help("Validator website url"),
)
.arg(
Arg::with_name("icon_url")
.short("i")
.long("icon-url")
.value_name("URL")
.takes_value(true)
.validator(check_url)
.help("Validator icon URL"),
)
.arg(
Arg::with_name("keybase_username")
.short("n")
@ -168,6 +194,7 @@ impl ValidatorInfoSubCommands for App<'_, '_> {
.value_name("USERNAME")
.takes_value(true)
.validator(is_short_field)
.hidden(hidden_unless_forced()) // Being phased out
.help("Validator Keybase username"),
)
.arg(
@ -240,11 +267,11 @@ pub fn process_set_validator_info(
) -> ProcessResult {
// Validate keybase username
if let Some(string) = validator_info.get("keybaseUsername") {
let result = verify_keybase(&config.signers[0].pubkey(), string);
if result.is_err() {
if force_keybase {
println!("--force supplied, ignoring: {result:?}");
} else {
if force_keybase {
println!("--force supplied, skipping Keybase verification");
} else {
let result = verify_keybase(&config.signers[0].pubkey(), string);
if result.is_err() {
result.map_err(|err| {
CliError::BadParameter(format!("Invalid validator keybase username: {err}"))
})?;
@ -255,6 +282,14 @@ pub fn process_set_validator_info(
let validator_info = ValidatorInfo {
info: validator_string,
};
let result = check_total_length(&validator_info);
if result.is_err() {
result.map_err(|err| {
CliError::BadParameter(format!("Maximum size for validator info: {err}"))
})?;
}
// Check for existing validator-info account
let all_config = rpc_client.get_program_accounts(&solana_config_program::id())?;
let existing_account = all_config
@ -426,7 +461,7 @@ mod tests {
fn test_check_url() {
let url = "http://test.com";
assert_eq!(check_url(url.to_string()), Ok(()));
let long_url = "http://7cLvFwLCbyHuXQ1RGzhCMobAWYPMSZ3VbUml1qWi1nkc3FD7zj9hzTZzMvYJ.com";
let long_url = "http://7cLvFwLCbyHuXQ1RGzhCMobAWYPMSZ3VbUml1CMobAWYPMSZ3VbUml1qWi1nkc3FD7zj9hzTZzMvYJ.com";
assert!(check_url(long_url.to_string()).is_err());
let non_url = "not parseable";
assert!(check_url(non_url.to_string()).is_err());
@ -436,7 +471,7 @@ mod tests {
fn test_is_short_field() {
let name = "Alice Validator";
assert_eq!(is_short_field(name.to_string()), Ok(()));
let long_name = "Alice 7cLvFwLCbyHuXQ1RGzhCMobAWYPMSZ3VbUml1qWi1nkc3FD7zj9hzTZzMvYJt6rY9";
let long_name = "Alice 7cLvFwLCbyHuXQ1RGzhCMobAWYPMSZ3VbUml1qWi1nkc3FD7zj9hzTZzMvYJt6rY9j9hzTZzMvYJt6rY9";
assert!(is_short_field(long_name.to_string()).is_err());
}
@ -460,6 +495,8 @@ mod tests {
"Alice",
"-n",
"alice_keybase",
"-i",
"https://test.com/icon.png",
]);
let subcommand_matches = matches.subcommand();
assert_eq!(subcommand_matches.0, "validator-info");
@ -471,6 +508,7 @@ mod tests {
let expected = json!({
"name": "Alice",
"keybaseUsername": "alice_keybase",
"iconUrl": "https://test.com/icon.png",
});
assert_eq!(parse_args(matches), expected);
}

View File

@ -18,12 +18,14 @@ For details about optional fields for VALIDATOR_INFO_ARGS:
solana validator-info publish --help
```
The recommended dimensions for the validator icon are 360x360px and PNG format.
## Example Commands
Example publish command:
```bash
solana validator-info publish "Elvis Validator" -n elvis -w "https://elvis-validates.com"
solana validator-info publish "Elvis Validator" -w "https://elvis-validates.com" -i "https://elvis-validates.com/my-icon.png"
```
Example query command:
@ -37,28 +39,11 @@ which outputs
```text
Validator info from 8WdJvDz6obhADdxpGCiJKZsDYwTLNEDFizayqziDc9ah
Validator pubkey: 6dMH3u76qZ7XG4bVboVRnBHR2FfrxEqTTTyj4xmyDMWo
Info: {"keybaseUsername":"elvis","name":"Elvis Validator","website":"https://elvis-validates.com"}
Info: {"iconUrl":"elvis","name":"Elvis Validator","website":"https://elvis-validates.com"}
```
For older accounts instead of `iconUrl` you might see `keybaseUsername` as those accounts used Keybase for their validator icon (see next section for further information).
## Keybase
Including a Keybase username allows client applications \(like the Solana
Network Explorer\) to automatically pull in your validator public profile,
including cryptographic proofs, brand identity, etc. To connect your validator
pubkey with Keybase:
1. Join [https://keybase.io/](https://keybase.io/) and complete the profile for your validator
2. Add your validator **identity pubkey** to Keybase:
- Create an empty file on your local computer called `validator-<PUBKEY>`
- In Keybase, navigate to the Files section, and upload your pubkey file to
a `solana` subdirectory in your public folder: `/keybase/public/<KEYBASE_USERNAME>/solana`
- To check your pubkey, ensure you can successfully browse to
`https://keybase.pub/<KEYBASE_USERNAME>/solana/validator-<PUBKEY>`
3. Add or update your `solana validator-info` with your Keybase username. The
CLI will verify the `validator-<PUBKEY>` file
Previously Keybase was used by validators to provide their validator icon, however Keybase has sunset its service and thus is no longer supported. Some old validator info accounts will still contain keybase usernames this is reflected in the serialized data returend when querying these validator info accounts.