Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bls signature base layer registration #596

Open
wants to merge 9 commits into
base: development
Choose a base branch
from
24 changes: 24 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions applications/tari_validator_node/Cargo.toml
Expand Up @@ -40,6 +40,7 @@ anyhow = "1.0.53"
async-trait = "0.1.50"
axum = "0.6.0"
axum-jrpc = { version = "0.3.2", features = ["anyhow_error"] }
blst = "0.3.10"
bytes = "1"
chrono = "0.4.22"
clap = { version = "3.2.5", features = ["env"] }
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_validator_node/src/bootstrap.rs
Expand Up @@ -251,7 +251,7 @@ pub async fn spawn_services(

// Auto-registration
if config.validator_node.auto_register {
let handle = registration::spawn(config.clone(), node_identity.clone(), epoch_manager.clone(), shutdown);
let handle = registration::spawn(config.clone(), node_identity, epoch_manager.clone(), shutdown);
handles.push(handle);
} else {
info!(target: LOG_TARGET, "♽️ Node auto registration is disabled");
Expand Down
6 changes: 6 additions & 0 deletions applications/tari_validator_node/src/config.rs
Expand Up @@ -67,6 +67,8 @@ pub struct ValidatorNodeConfig {
pub shard_key_file: PathBuf,
/// A path to the file that stores your node identity and secret key
pub identity_file: PathBuf,
/// A path to the file that store the BLS signature scheme secret key
pub consensus_secret_key_file: PathBuf,
/// A path to the file that stores the tor hidden service private key, if using the tor transport
pub tor_identity_file: PathBuf,
/// The node's publicly-accessible hostname
Expand Down Expand Up @@ -113,6 +115,9 @@ impl ValidatorNodeConfig {
if !self.identity_file.is_absolute() {
self.identity_file = base_path.as_ref().join(&self.identity_file);
}
if !self.consensus_secret_key_file.is_absolute() {
self.consensus_secret_key_file = base_path.as_ref().join(&self.consensus_secret_key_file);
}
if !self.tor_identity_file.is_absolute() {
self.tor_identity_file = base_path.as_ref().join(&self.tor_identity_file);
}
Expand All @@ -134,6 +139,7 @@ impl Default for ValidatorNodeConfig {
override_from: None,
shard_key_file: PathBuf::from("shard_key.json"),
identity_file: PathBuf::from("validator_node_id.json"),
consensus_secret_key_file: PathBuf::from("consensus_secret_key_file.json"),
tor_identity_file: PathBuf::from("validator_node_tor_id.json"),
public_address: None,
base_node_grpc_address: None,
Expand Down
Expand Up @@ -41,7 +41,11 @@ use tari_crypto::tari_utilities::ByteArray;
use tari_validator_node_client::types::TemplateRegistrationRequest;
use tari_wallet_grpc_client::Client as GrpcWallet;

use crate::{grpc::base_layer_wallet::WalletGrpcError, template_registration_signing::sign_template_registration};
use crate::{
grpc::base_layer_wallet::WalletGrpcError,
template_registration_signing::sign_template_registration,
validator_node_identity::ValidatorNodeIdentity,
};

const _LOG_TARGET: &str = "tari::validator_node::app";

Expand Down Expand Up @@ -77,12 +81,14 @@ impl GrpcWalletClient {

pub async fn register_validator_node(
&mut self,
node_identity: &NodeIdentity,
validator_node_identity: &ValidatorNodeIdentity,
) -> Result<RegisterValidatorNodeResponse, WalletGrpcError> {
let inner = self.connection().await?;
let signature = ValidatorNodeSignature::sign(node_identity.secret_key(), b"");
let message = validator_node_identity.public_key().to_bytes();
let signature = ValidatorNodeSignature::sign(validator_node_identity.node_identity().secret_key(), &message);
// TODO: add signature for bls public key
let request = RegisterValidatorNodeRequest {
validator_node_public_key: node_identity.public_key().to_vec(),
validator_node_public_key: validator_node_identity.node_identity().public_key().to_vec(),
validator_node_signature: Some(signature.signature().into()),
fee_per_gram: 1,
message: "Registering VN".to_string(),
Expand Down
26 changes: 18 additions & 8 deletions applications/tari_validator_node/src/json_rpc/handlers.rs
Expand Up @@ -28,6 +28,7 @@ use axum_jrpc::{
JsonRpcExtractor,
JsonRpcResponse,
};
use blst::min_sig::SecretKey as BlsSecretKey;
use log::*;
use serde::Serialize;
use serde_json::{self as json, json};
Expand All @@ -38,7 +39,6 @@ use tari_comms::{
peer_manager::{NodeId, PeerFeatures},
types::CommsPublicKey,
CommsNode,
NodeIdentity,
};
use tari_comms_logging::SqliteMessageLog;
use tari_crypto::tari_utilities::{hex::Hex, ByteArray};
Expand Down Expand Up @@ -92,14 +92,15 @@ use crate::{
},
p2p::services::mempool::MempoolHandle,
registration,
validator_node_identity::ValidatorNodeIdentity,
Services,
ValidatorNodeConfig,
};

const LOG_TARGET: &str = "tari::validator_node::json_rpc::handlers";

pub struct JsonRpcHandlers {
node_identity: Arc<NodeIdentity>,
validator_node_identity: Arc<ValidatorNodeIdentity>,
wallet_grpc_client: GrpcWalletClient,
mempool: MempoolHandle,
template_manager: TemplateManagerHandle,
Expand All @@ -115,13 +116,16 @@ pub struct JsonRpcHandlers {
impl JsonRpcHandlers {
pub fn new(
wallet_grpc_client: GrpcWalletClient,
consensus_secret_key: BlsSecretKey,
base_node_client: GrpcBaseNodeClient,
services: &Services,
config: ValidatorNodeConfig,
) -> Self {
let node_identity = services.comms.node_identity();
let validator_node_identity = ValidatorNodeIdentity::new(node_identity.as_ref().clone(), consensus_secret_key);
Self {
config,
node_identity: services.comms.node_identity(),
validator_node_identity: Arc::new(validator_node_identity),
wallet_grpc_client,
mempool: services.mempool.clone(),
epoch_manager: services.epoch_manager.clone(),
Expand All @@ -147,9 +151,15 @@ impl JsonRpcHandlers {
pub fn get_identity(&self, value: JsonRpcExtractor) -> JrpcResult {
let answer_id = value.get_answer_id();
let response = GetIdentityResponse {
node_id: self.node_identity.node_id().to_hex(),
public_key: self.node_identity.public_key().to_hex(),
public_address: self.node_identity.public_addresses().first().unwrap().to_string(),
node_id: self.validator_node_identity.node_identity().node_id().to_hex(),
public_key: self.validator_node_identity.node_identity().public_key().to_hex(),
public_address: self
.validator_node_identity
.node_identity()
.public_addresses()
.first()
.unwrap()
.to_string(),
};

Ok(JsonRpcResponse::success(answer_id, response))
Expand Down Expand Up @@ -491,7 +501,7 @@ impl JsonRpcHandlers {
pub async fn register_validator_node(&self, value: JsonRpcExtractor) -> JrpcResult {
let answer_id = value.get_answer_id();

let resp = registration::register(self.wallet_client(), &self.node_identity, &self.epoch_manager)
let resp = registration::register(self.wallet_client(), &self.validator_node_identity, &self.epoch_manager)
.await
.map_err(internal_error(answer_id))?;

Expand All @@ -518,7 +528,7 @@ impl JsonRpcHandlers {

let resp = self
.wallet_client()
.register_template(&self.node_identity, data)
.register_template(self.validator_node_identity.node_identity(), data)
.await
.map_err(internal_error(answer_id))?;

Expand Down
10 changes: 9 additions & 1 deletion applications/tari_validator_node/src/lib.rs
Expand Up @@ -32,6 +32,7 @@ mod json_rpc;
mod p2p;
mod registration;
mod template_registration_signing;
mod validator_node_identity;
// TODO: Hook up transaction executor to process transactions from the mempool and pass the executed result to consensus
// mod transaction_executor;

Expand All @@ -42,6 +43,7 @@ use std::{
process,
};

use blst::min_sig::SecretKey as BlsSecretKey;
use log::*;
use serde::{Deserialize, Serialize};
use tari_app_utilities::identity_management::setup_node_identity;
Expand Down Expand Up @@ -102,6 +104,11 @@ pub async fn run_validator_node(config: &ApplicationConfig, shutdown_signal: Shu
true,
DAN_PEER_FEATURES,
)?;
let consensus_secret_key = BlsSecretKey::from_bytes(
&std::fs::read(config.validator_node.consensus_secret_key_file.clone())
.map_err(|e| ExitError::new(ExitCode::ConfigError, e))?,
)
.map_err(|e| ExitError::new(ExitCode::ConfigError, format!("{:?}", e)))?;
let db_factory = SqliteDbFactory::new(config.validator_node.data_dir.clone());
db_factory
.migrate()
Expand All @@ -124,7 +131,7 @@ pub async fn run_validator_node(config: &ApplicationConfig, shutdown_signal: Shu
let services = spawn_services(
config,
shutdown_signal.clone(),
node_identity.clone(),
node_identity,
global_db,
ConsensusConstants::devnet(), // TODO: change this eventually
)
Expand All @@ -136,6 +143,7 @@ pub async fn run_validator_node(config: &ApplicationConfig, shutdown_signal: Shu
info!(target: LOG_TARGET, "🌐 Started JSON-RPC server on {}", jrpc_address);
let handlers = JsonRpcHandlers::new(
wallet_client,
consensus_secret_key,
base_node_client,
&services,
config.validator_node.clone(),
Expand Down
19 changes: 16 additions & 3 deletions applications/tari_validator_node/src/registration.rs
Expand Up @@ -26,6 +26,7 @@ use std::{
time::Duration,
};

use blst::min_sig::SecretKey as BlsSecretKey;
use log::{error, info, warn};
use tari_app_grpc::tari_rpc::RegisterValidatorNodeResponse;
use tari_base_node_client::BaseNodeClientError;
Expand All @@ -42,6 +43,7 @@ use tokio::{task, task::JoinHandle, time};

use crate::{
grpc::base_layer_wallet::{GrpcWalletClient, WalletGrpcError},
validator_node_identity::ValidatorNodeIdentity,
ApplicationConfig,
};

Expand All @@ -65,7 +67,7 @@ pub enum AutoRegistrationError {

pub async fn register(
mut wallet_client: GrpcWalletClient,
node_identity: &NodeIdentity,
validator_node_identity: &ValidatorNodeIdentity,
epoch_manager: &EpochManagerHandle,
) -> Result<RegisterValidatorNodeResponse, AutoRegistrationError> {
let balance = wallet_client.get_balance().await?;
Expand All @@ -82,7 +84,7 @@ pub async fn register(
let mut attempts = 1;

loop {
match wallet_client.register_validator_node(node_identity).await {
match wallet_client.register_validator_node(validator_node_identity).await {
Ok(resp) => {
let tx_id = resp.transaction_id;
info!(
Expand Down Expand Up @@ -179,7 +181,18 @@ async fn handle_epoch_changed(
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port)
}));

register(wallet_client, node_identity, epoch_manager).await?;
let consensus_secret_key = BlsSecretKey::from_bytes(
&std::fs::read(config.validator_node.consensus_secret_key_file.clone()).map_err(|e| {
AutoRegistrationError::RegistrationFailed {
details: format!("{:?}", e),
}
})?,
)
.map_err(|e| AutoRegistrationError::RegistrationFailed {
details: format!("{:?}", e),
})?;
let validator_node_identity = ValidatorNodeIdentity::new(node_identity.clone(), consensus_secret_key.clone());
register(wallet_client, &validator_node_identity, epoch_manager).await?;
} else {
info!(
target: LOG_TARGET,
Expand Down