Skip to content

Commit

Permalink
Improve keygen
Browse files Browse the repository at this point in the history
Make the keygen a crate that can be implemented and extended from other places
(like a forc-plugin). Upgraded its dependencies to avoid depending on protoc
for building
  • Loading branch information
cr-fuel committed Oct 4, 2023
1 parent d0e48ba commit 98257e8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 58 deletions.
41 changes: 35 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bin/keygen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ description = "Command line utilities for fuel-core key management"
anyhow = { workspace = true }
clap = { workspace = true, features = ["derive", "env"] }
fuel-core-types = { workspace = true, features = ["serde", "random"] }
libp2p-core = { version = "0.38", features = ["secp256k1"] }
libp2p-identity = { version = "0.2.4", features = ["secp256k1", "peerid"] }
serde_json = { workspace = true, features = ["raw_value"] }
71 changes: 22 additions & 49 deletions bin/keygen/src/keygen.rs
Original file line number Diff line number Diff line change
@@ -1,70 +1,41 @@
use clap::{
Parser,
ValueEnum,
};
use crate::{BLOCK_PRODUCTION, P2P};
use clap::ValueEnum;
use fuel_core_types::{
fuel_crypto::{
rand::{
prelude::StdRng,
SeedableRng,
},
rand::{prelude::StdRng, SeedableRng},
SecretKey,
},
fuel_tx::Input,
};
use libp2p_core::{
identity::{
secp256k1,
Keypair,
},
PeerId,
};
use libp2p_identity::{secp256k1, Keypair, PeerId};
use serde_json::json;
use std::{
ops::Deref,
str::FromStr,
};

/// Key management utilities for configuring fuel-core
#[derive(Debug, Parser)]
pub(crate) enum Command {
New(NewKey),
Parse(ParseSecret),
}

impl Command {
pub(crate) fn exec(&self) -> anyhow::Result<()> {
match self {
Command::New(cmd) => cmd.exec(),
Command::Parse(cmd) => cmd.exec(),
}
}
}
use std::{ops::Deref, str::FromStr};

/// Generate a random new secret & public key in the format expected by fuel-core
#[derive(Debug, clap::Args)]
#[clap(author, version, about)]
pub(crate) struct NewKey {
pub struct NewKey {
#[clap(long = "pretty", short = 'p')]
pretty: bool,
#[clap(
long = "key-type",
short = 'k',
value_enum,
default_value = "block-production"
default_value = BLOCK_PRODUCTION,
)]
key_type: KeyType,
}

#[derive(Clone, Debug, Default, ValueEnum)]
pub(crate) enum KeyType {
#[clap(rename_all = "snake_case")]
pub enum KeyType {
#[default]
BlockProduction,
Peering,
}

impl NewKey {
fn exec(&self) -> anyhow::Result<()> {
pub fn exec(&self) -> anyhow::Result<()> {
let mut rng = StdRng::from_entropy();
let secret = SecretKey::random(&mut rng);
let public_key = secret.public_key();
Expand All @@ -76,19 +47,20 @@ impl NewKey {
json!({
"secret": secret_str,
"address": address,
"type": "block_production"
"type": BLOCK_PRODUCTION,
})
}
KeyType::Peering => {
let mut bytes = *secret.deref();
let p2p_secret = secp256k1::SecretKey::from_bytes(&mut bytes)
let p2p_secret = secp256k1::SecretKey::try_from_bytes(&mut bytes)
.expect("Should be a valid private key");
let libp2p_keypair = Keypair::Secp256k1(p2p_secret.into());
let p2p_keypair = secp256k1::Keypair::from(p2p_secret);
let libp2p_keypair = Keypair::from(p2p_keypair);
let peer_id = PeerId::from_public_key(&libp2p_keypair.public());
json!({
"secret": secret_str,
"peer_id": peer_id.to_string(),
"type": "p2p"
"type": P2P
})
}
};
Expand All @@ -99,21 +71,21 @@ impl NewKey {
/// Parse a secret key to view the associated public key
#[derive(Debug, clap::Args)]
#[clap(author, version, about)]
pub(crate) struct ParseSecret {
pub struct ParseSecret {
secret: String,
#[clap(long = "pretty", short = 'p')]
pretty: bool,
#[clap(
long = "key-type",
short = 'k',
value_enum,
default_value = "block-production"
default_value = BLOCK_PRODUCTION,
)]
key_type: KeyType,
}

impl ParseSecret {
fn exec(&self) -> anyhow::Result<()> {
pub fn exec(&self) -> anyhow::Result<()> {
let secret = SecretKey::from_str(&self.secret)?;
match self.key_type {
KeyType::BlockProduction => {
Expand All @@ -126,13 +98,14 @@ impl ParseSecret {
}
KeyType::Peering => {
let mut bytes = *secret.deref();
let p2p_secret = secp256k1::SecretKey::from_bytes(&mut bytes)
let p2p_secret = secp256k1::SecretKey::try_from_bytes(&mut bytes)
.expect("Should be a valid private key");
let libp2p_keypair = Keypair::Secp256k1(p2p_secret.into());
let p2p_keypair = secp256k1::Keypair::from(p2p_secret);
let libp2p_keypair = Keypair::from(p2p_keypair);
let peer_id = PeerId::from_public_key(&libp2p_keypair.public());
let output = json!({
"peer_id": peer_id.to_string(),
"type": "p2p"
"type": P2P
});
print_value(output, self.pretty)
}
Expand Down
6 changes: 6 additions & 0 deletions bin/keygen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! Keygen crate

pub const BLOCK_PRODUCTION: &str = "block_production";
pub const P2P: &str = "p2p";

pub mod keygen;
19 changes: 17 additions & 2 deletions bin/keygen/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
//! A simple keygen cli utility tool for configuring fuel-core

use clap::Parser;
use fuel_core_keygen::keygen;

pub mod keygen;
/// Key management utilities for configuring fuel-core
#[derive(Debug, Parser)]
pub(crate) enum Command {
New(keygen::NewKey),
Parse(keygen::ParseSecret),
}

impl Command {
pub(crate) fn exec(&self) -> anyhow::Result<()> {
match self {
Command::New(cmd) => cmd.exec(),
Command::Parse(cmd) => cmd.exec(),
}
}
}

fn main() -> anyhow::Result<()> {
let cmd = keygen::Command::parse();
let cmd = Command::parse();
cmd.exec()
}

0 comments on commit 98257e8

Please sign in to comment.