Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [2135](https://github.com/FuelLabs/fuel-core/pull/2135): Added metrics logging for number of blocks served over the p2p req/res protocol.
- [2155](https://github.com/FuelLabs/fuel-core/pull/2155): Added trait declaration for block committer data
- [2142](https://github.com/FuelLabs/fuel-core/pull/2142): Added benchmarks for varied forms of db lookups to assist in optimizations.
- [2158](https://github.com/FuelLabs/fuel-core/pull/2158): Log the public address of the signing key, if it is specified

## [Version 0.35.0]

Expand Down
Binary file not shown.
13 changes: 12 additions & 1 deletion bin/fuel-core/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,18 @@ impl Command {
);
consensus_signer = SignMode::Key(Secret::new(key.into()));
}
}
};

if let Ok(signer_address) = consensus_signer.address() {
if let Some(address) = signer_address {
info!(
"Consensus signer is specified and its address is {}",
address
);
}
} else {
warn!("Consensus Signer is specified but it was not possible to retrieve its address");
};

if consensus_signer.is_available() && trigger == Trigger::Never {
warn!("Consensus key configured but block production is disabled!");
Expand Down
82 changes: 82 additions & 0 deletions crates/services/consensus_module/poa/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ use fuel_core_types::{
},
primitives::SecretKeyWrapper,
},
fuel_crypto::PublicKey,
fuel_tx::{
Address,
Input,
},
fuel_vm::Signature,
secrecy::{
ExposeSecret,
Expand Down Expand Up @@ -68,6 +73,34 @@ impl SignMode {
};
Ok(Consensus::PoA(PoAConsensus::new(poa_signature)))
}

/// Returns the public key of the block producer, if any
pub fn public_key(&self) -> anyhow::Result<Option<PublicKey>> {
match self {
SignMode::Unavailable => Ok(None),
SignMode::Key(secret_key) => {
Ok(Some(secret_key.expose_secret().public_key()))
}

#[cfg(feature = "aws-kms")]
SignMode::Kms {
cached_public_key_bytes,
..
} => {
use k256::pkcs8::DecodePublicKey;

let k256_public_key =
k256::PublicKey::from_public_key_der(cached_public_key_bytes)?;
Ok(Some(PublicKey::from(k256_public_key)))
}
}
}

/// Returns the address of the block producer, if any
pub fn address(&self) -> anyhow::Result<Option<Address>> {
let address = self.public_key()?.as_ref().map(Input::owner);
Ok(address)
}
}

#[cfg(feature = "aws-kms")]
Expand Down Expand Up @@ -140,6 +173,8 @@ async fn sign_with_kms(

#[cfg(test)]
mod tests {
use std::str::FromStr;

use super::*;
use fuel_core_types::fuel_crypto::SecretKey;
use rand::{
Expand Down Expand Up @@ -173,4 +208,51 @@ mod tests {
.is_available())
};
}

// The tests are against a keypair generated using fuel-core-keygen, which has
// been tweaked to display the public key associated with a keypair.
// The keypair used in these tests is the following:
// {
// "address:"e2f3f5109c56eec359c124cbf25f35dcc1495b0bbdac5848e0ff37a86fe69a6d",
// "public_key":"9ab6229de634056cdc67dfba26e6a06e4ba082693ea30395e5994b113ab6c6e3189a12a10d8fb08d1d28f7117ca34f6b16c5132acd9570de6e7a005f6bbd8f3d",
// "secret":"2708b7bad8b5b52d031e5795c1d1995660185f464900cbd593328eb433bdb7f6","type":"block-production"
// }
#[test]
fn public_key() {
assert_eq!(SignMode::Unavailable.public_key().unwrap(), None);

let secret_key = SecretKey::from_str(
"2708b7bad8b5b52d031e5795c1d1995660185f464900cbd593328eb433bdb7f6",
)
.expect("Secret key construction should not fail");

let public_key = "9ab6229de634056cdc67dfba26e6a06e4ba082693ea30395e5994b113ab6c6e3189a12a10d8fb08d1d28f7117ca34f6b16c5132acd9570de6e7a005f6bbd8f3d";
Copy link
Contributor Author

@acerone85 acerone85 Sep 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trying to construct a public key from this string slice fails, I am not sure why that is the case.

let _pk = PublicKey::from_str(public_key).unwrap();

yields an error InvalidPublicKey.

If I instead convert the derived public key to a string literal, and i compare it with the string literal above, the test passes.


let derived_public_key = SignMode::Key(Secret::new(secret_key.into()))
.public_key()
.expect("Public key derivation should not fail")
.expect("Public key derivation should yield a defined value")
.to_string();

assert_eq!(public_key, &derived_public_key);
}

#[test]
fn address() {
assert_eq!(SignMode::Unavailable.address().unwrap(), None);

let secret_key = SecretKey::from_str(
"2708b7bad8b5b52d031e5795c1d1995660185f464900cbd593328eb433bdb7f6",
)
.expect("Secret key construction should not fail");

let address = "e2f3f5109c56eec359c124cbf25f35dcc1495b0bbdac5848e0ff37a86fe69a6d";
let derived_address = SignMode::Key(Secret::new(secret_key.into()))
.address()
.expect("Address derivation should not fail")
.expect("Address derivation should yield a defined value")
.to_string();

assert_eq!(address, &derived_address);
}
}