Keybase pubkey file instructions and verification for validators (#5090)
* Document publishing a pubkey on keybase * Verify keybase-pubkey
This commit is contained in:
parent
db7e78bf99
commit
0c87928132
|
@ -2939,6 +2939,7 @@ dependencies = [
|
|||
"bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -255,3 +255,20 @@ Available fields for VALIDATOR_INFO_ARGS:
|
|||
* Website
|
||||
* Keybase ID
|
||||
* Details
|
||||
|
||||
##### Keybase
|
||||
|
||||
Including a Keybase ID 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/ and complete the profile for your validator
|
||||
2. Add your validator **identity pubkey** to Keybase:
|
||||
* Create an empty file on your local computer called `solana_pubkey_<PUBKEY>`
|
||||
* In Keybase, navigate to the Files section, and upload your pubkey file to
|
||||
your public folder: `/keybase/public/<KEYBASE_ID>`
|
||||
* To check your pubkey, ensure you can successfully browse to
|
||||
`https://keybase.pub/<KEYBASE_ID>/solana_pubkey_<PUBKEY>`
|
||||
3. Add or update your `solana-validator-info` with your Keybase ID. The CLI will
|
||||
verify the `solana_pubkey_<PUBKEY>` file
|
||||
|
|
|
@ -16,6 +16,7 @@ cuda = []
|
|||
bincode = "1.1.4"
|
||||
clap = "2.33"
|
||||
dirs = "2.0.1"
|
||||
reqwest = "0.9.18"
|
||||
serde = "1.0.94"
|
||||
serde_derive = "1.0.94"
|
||||
serde_json = "1.0.40"
|
||||
|
|
|
@ -2,6 +2,7 @@ use bincode::deserialize;
|
|||
use clap::{
|
||||
crate_description, crate_name, crate_version, App, AppSettings, Arg, ArgMatches, SubCommand,
|
||||
};
|
||||
use reqwest::Client;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde_json::{Map, Value};
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
|
@ -99,7 +100,30 @@ fn check_details_length(string: String) -> Result<(), String> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_args(matches: &ArgMatches<'_>) -> Result<String, Box<dyn error::Error>> {
|
||||
fn verify_keybase(
|
||||
validator_pubkey: &Pubkey,
|
||||
keybase_id: &Value,
|
||||
) -> Result<(), Box<dyn error::Error>> {
|
||||
if let Some(keybase_id) = keybase_id.as_str() {
|
||||
let url = format!(
|
||||
"https://keybase.pub/{}/solana_pubkey_{:?}",
|
||||
keybase_id, validator_pubkey
|
||||
);
|
||||
let client = Client::new();
|
||||
if client.head(&url).send()?.status().is_success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("keybase_id could not be confirmed at: {}. Please add this pubkey file to your keybase profile to connect", url))?
|
||||
}
|
||||
} else {
|
||||
Err(format!(
|
||||
"keybase_id could not be parsed as String: {}",
|
||||
keybase_id
|
||||
))?
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_args(matches: &ArgMatches<'_>) -> Value {
|
||||
let mut map = Map::new();
|
||||
map.insert(
|
||||
"name".to_string(),
|
||||
|
@ -117,8 +141,7 @@ fn parse_args(matches: &ArgMatches<'_>) -> Result<String, Box<dyn error::Error>>
|
|||
Value::String(keybase_id.to_string()),
|
||||
);
|
||||
}
|
||||
let string = serde_json::to_string(&Value::Object(map))?;
|
||||
Ok(string)
|
||||
Value::Object(map)
|
||||
}
|
||||
|
||||
fn parse_validator_info(account_data: &[u8]) -> Result<(Pubkey, String), Box<dyn error::Error>> {
|
||||
|
@ -271,9 +294,13 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||
|
||||
// Prepare validator info
|
||||
let keys = vec![(id(), false), (validator_keypair.pubkey(), true)];
|
||||
let validator_info = parse_args(&matches)?;
|
||||
let validator_info = parse_args(&matches);
|
||||
if let Some(string) = validator_info.get("keybaseId") {
|
||||
verify_keybase(&validator_keypair.pubkey(), &string)?;
|
||||
}
|
||||
let validator_string = serde_json::to_string(&validator_info)?;
|
||||
let validator_info = ValidatorInfo {
|
||||
info: validator_info,
|
||||
info: validator_string,
|
||||
};
|
||||
|
||||
// Check existence of validator-info account
|
||||
|
@ -400,12 +427,11 @@ mod tests {
|
|||
.arg(Arg::with_name("keybase_id").short("k").takes_value(true))
|
||||
.arg(Arg::with_name("details").short("d").takes_value(true))
|
||||
.get_matches_from(vec!["test", "-n", "Alice", "-k", "464bb0f2956f7e83"]);
|
||||
let expected_string = serde_json::to_string(&json!({
|
||||
let expected = json!({
|
||||
"name": "Alice",
|
||||
"keybaseId": "464bb0f2956f7e83",
|
||||
}))
|
||||
.unwrap();
|
||||
assert_eq!(parse_args(&matches).unwrap(), expected_string);
|
||||
});
|
||||
assert_eq!(parse_args(&matches), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue