diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ed6c4798b4..1596c6744c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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] diff --git a/bin/fuel-core/chainspec/local-testnet/state_transition_bytecode.wasm b/bin/fuel-core/chainspec/local-testnet/state_transition_bytecode.wasm index 0f2ef085553..a2d81c9434c 100755 Binary files a/bin/fuel-core/chainspec/local-testnet/state_transition_bytecode.wasm and b/bin/fuel-core/chainspec/local-testnet/state_transition_bytecode.wasm differ diff --git a/bin/fuel-core/src/cli/run.rs b/bin/fuel-core/src/cli/run.rs index 4c32075056d..44be9d57a98 100644 --- a/bin/fuel-core/src/cli/run.rs +++ b/bin/fuel-core/src/cli/run.rs @@ -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!"); diff --git a/crates/services/consensus_module/poa/src/signer.rs b/crates/services/consensus_module/poa/src/signer.rs index f9ba98d3599..2712b980c7d 100644 --- a/crates/services/consensus_module/poa/src/signer.rs +++ b/crates/services/consensus_module/poa/src/signer.rs @@ -18,6 +18,11 @@ use fuel_core_types::{ }, primitives::SecretKeyWrapper, }, + fuel_crypto::PublicKey, + fuel_tx::{ + Address, + Input, + }, fuel_vm::Signature, secrecy::{ ExposeSecret, @@ -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> { + 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> { + let address = self.public_key()?.as_ref().map(Input::owner); + Ok(address) + } } #[cfg(feature = "aws-kms")] @@ -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::{ @@ -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"; + + 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); + } }