Skip to content

Commit

Permalink
feat: add grpc to get shard key for public key (#4654)
Browse files Browse the repository at this point in the history
Description
---
Add GRPC call for getting shard key for a public key.
  • Loading branch information
Cifko committed Sep 12, 2022
1 parent 96a30c1 commit 0fd3256
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 11 deletions.
11 changes: 10 additions & 1 deletion applications/tari_app_grpc/proto/base_node.proto
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ service BaseNode {
// Get VNs
rpc GetActiveValidatorNodes(GetActiveValidatorNodesRequest) returns (stream ActiveValidatorNode);
rpc GetCommittee(GetCommitteeRequest) returns (GetCommitteeResponse);

rpc GetShardKey(GetShardKeyRequest) returns (GetShardKeyResponse);
}

message GetAssetMetadataRequest {
Expand Down Expand Up @@ -455,4 +455,13 @@ message GetCommitteeRequest {

message GetCommitteeResponse {
repeated bytes public_key = 1;
}

message GetShardKeyRequest {
uint64 height = 1;
bytes public_key = 2;
}

message GetShardKeyResponse {
bytes shard_key = 1;
}
20 changes: 19 additions & 1 deletion applications/tari_base_node/src/grpc/base_node_grpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use tari_app_grpc::{
tari_rpc::{CalcType, Sorting},
};
use tari_app_utilities::consts;
use tari_common_types::types::{Commitment, Signature};
use tari_common_types::types::{Commitment, PublicKey, Signature};
use tari_comms::{Bytes, CommsNode};
use tari_core::{
base_node::{
Expand Down Expand Up @@ -1599,6 +1599,24 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer {
Ok(Response::new(tari_rpc::GetCommitteeResponse { public_key: response }))
}

async fn get_shard_key(
&self,
request: Request<tari_rpc::GetShardKeyRequest>,
) -> Result<Response<tari_rpc::GetShardKeyResponse>, Status> {
let request = request.into_inner();
let report_error_flag = self.report_error_flag();
let mut handler = self.node_service.clone();
let public_key = PublicKey::from_bytes(&request.public_key)
.map_err(|e| report_error(report_error_flag, Status::invalid_argument(e.to_string())))?;
let shard_key = handler.get_shard_key(request.height, public_key).await.map_err(|e| {
error!(target: LOG_TARGET, "Error {}", e);
report_error(report_error_flag, Status::internal(e.to_string()))
})?;
Ok(Response::new(tari_rpc::GetShardKeyResponse {
shard_key: shard_key.to_vec(),
}))
}

async fn get_active_validator_nodes(
&self,
request: Request<tari_rpc::GetActiveValidatorNodesRequest>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::{
};

use serde::{Deserialize, Serialize};
use tari_common_types::types::{Commitment, HashOutput, PrivateKey, Signature};
use tari_common_types::types::{Commitment, HashOutput, PrivateKey, PublicKey, Signature};
use tari_utilities::hex::Hex;

use crate::{blocks::NewBlockTemplate, chain_storage::MmrTree, proof_of_work::PowAlgorithm};
Expand Down Expand Up @@ -58,6 +58,7 @@ pub enum NodeCommsRequest {
FetchMempoolTransactionsByExcessSigs { excess_sigs: Vec<PrivateKey> },
FetchValidatorNodesKeys { height: u64 },
FetchCommittee { height: u64, shard: [u8; 32] },
GetShardKey { height: u64, public_key: PublicKey },
}

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -102,6 +103,9 @@ impl Display for NodeCommsRequest {
FetchCommittee { height, shard } => {
write!(f, "FetchCommittee height ({}), shard({:?})", height, shard)
},
GetShardKey { height, public_key } => {
write!(f, "GetShardKey height ({}), public key ({:?})", height, public_key)
},
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub enum NodeCommsResponse {
},
FetchValidatorNodesKeysResponse(Vec<ActiveValidatorNode>),
FetchCommitteeResponse(Vec<ActiveValidatorNode>),
GetShardKeyResponse([u8; 32]),
}

impl Display for NodeCommsResponse {
Expand Down Expand Up @@ -113,6 +114,7 @@ impl Display for NodeCommsResponse {
FetchOutputsByContractIdResponse { .. } => write!(f, "FetchOutputsByContractIdResponse"),
FetchValidatorNodesKeysResponse(_) => write!(f, "FetchValidatorNodesKeysResponse"),
FetchCommitteeResponse(_) => write!(f, "FetchCommitteeResponse"),
GetShardKeyResponse(_) => write!(f, "GetShardKeyResponse"),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,10 @@ where B: BlockchainBackend + 'static
let validator_nodes = self.blockchain_db.fetch_committee(height, shard).await?;
Ok(NodeCommsResponse::FetchCommitteeResponse(validator_nodes))
},
NodeCommsRequest::GetShardKey { height, public_key } => {
let shard_key = self.blockchain_db.get_shard_key(height, public_key).await?;
Ok(NodeCommsResponse::GetShardKeyResponse(shard_key))
},
}
}

Expand Down
13 changes: 12 additions & 1 deletion base_layer/core/src/base_node/comms_interface/local_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::{ops::RangeInclusive, sync::Arc};

use tari_common_types::{
chain_metadata::ChainMetadata,
types::{BlockHash, Commitment, HashOutput, Signature},
types::{BlockHash, Commitment, HashOutput, PublicKey, Signature},
};
use tari_service_framework::{reply_channel::SenderService, Service};
use tokio::sync::broadcast;
Expand Down Expand Up @@ -301,4 +301,15 @@ impl LocalNodeCommsInterface {
_ => Err(CommsInterfaceError::UnexpectedApiResponse),
}
}

pub async fn get_shard_key(&mut self, height: u64, public_key: PublicKey) -> Result<[u8; 32], CommsInterfaceError> {
match self
.request_sender
.call(NodeCommsRequest::GetShardKey { height, public_key })
.await??
{
NodeCommsResponse::GetShardKeyResponse(shard_key) => Ok(shard_key),
_ => Err(CommsInterfaceError::UnexpectedApiResponse),
}
}
}
4 changes: 3 additions & 1 deletion base_layer/core/src/chain_storage/async_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use log::*;
use rand::{rngs::OsRng, RngCore};
use tari_common_types::{
chain_metadata::ChainMetadata,
types::{BlockHash, Commitment, HashOutput, Signature},
types::{BlockHash, Commitment, HashOutput, PublicKey, Signature},
};
use tari_utilities::epoch_time::EpochTime;

Expand Down Expand Up @@ -271,6 +271,8 @@ impl<B: BlockchainBackend + 'static> AsyncBlockchainDb<B> {
make_async_fn!(fetch_committee(height: u64, shard: [u8;32]) -> Vec<ActiveValidatorNode>, "fetch_committee");

make_async_fn!(get_validator_nodes_mr() -> Vec<u8>, "get_validator_nodes_mr");

make_async_fn!(get_shard_key(height:u64, public_key:PublicKey) -> [u8;32], "get_shard_key");
}

impl<B: BlockchainBackend + 'static> From<BlockchainDatabase<B>> for AsyncBlockchainDb<B> {
Expand Down
3 changes: 2 additions & 1 deletion base_layer/core/src/chain_storage/blockchain_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use croaring::Bitmap;
use tari_common_types::{
chain_metadata::ChainMetadata,
types::{Commitment, HashOutput, Signature},
types::{Commitment, HashOutput, PublicKey, Signature},
};

use super::ActiveValidatorNode;
Expand Down Expand Up @@ -195,4 +195,5 @@ pub trait BlockchainBackend: Send + Sync {

fn fetch_active_validator_nodes(&self, height: u64) -> Result<Vec<ActiveValidatorNode>, ChainStorageError>;
fn fetch_committee(&self, height: u64, shard: [u8; 32]) -> Result<Vec<ActiveValidatorNode>, ChainStorageError>;
fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError>;
}
7 changes: 6 additions & 1 deletion base_layer/core/src/chain_storage/blockchain_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use log::*;
use serde::{Deserialize, Serialize};
use tari_common_types::{
chain_metadata::ChainMetadata,
types::{BlockHash, Commitment, FixedHash, HashOutput, Signature},
types::{BlockHash, Commitment, FixedHash, HashOutput, PublicKey, Signature},
};
use tari_mmr::pruned_hashset::PrunedHashSet;
use tari_utilities::{epoch_time::EpochTime, hex::Hex, ByteArray};
Expand Down Expand Up @@ -848,6 +848,11 @@ where B: BlockchainBackend
Ok(mmr.get_merkle_root().unwrap())
}

pub fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError> {
let db = self.db_read_access()?;
db.get_shard_key(height, public_key)
}

/// Tries to add a block to the longest chain.
///
/// The block is added to the longest chain if and only if
Expand Down
17 changes: 16 additions & 1 deletion base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ pub fn create_lmdb_database<P: AsRef<Path>>(
.add_database(LMDB_DB_ORPHAN_PARENT_MAP_INDEX, flags | db::DUPSORT)
.add_database(LMDB_DB_BAD_BLOCK_LIST, flags)
.add_database(LMDB_DB_REORGS, flags | db::INTEGERKEY)
.add_database(LMDB_DB_VALIDATOR_NODES, flags)
.add_database(LMDB_DB_VALIDATOR_NODES, flags | db::DUPSORT)
.add_database(LMDB_DB_VALIDATOR_NODES_MAPPING, flags | db::DUPSORT)
.build()
.map_err(|err| ChainStorageError::CriticalError(format!("Could not create LMDB store:{}", err)))?;
Expand Down Expand Up @@ -2471,6 +2471,21 @@ impl BlockchainBackend for LMDBDatabase {
}
Ok(result)
}

fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError> {
let txn = self.read_transaction()?;
let validator_nodes: Vec<ActiveValidatorNode> =
lmdb_get_multiple(&txn, &self.validator_nodes, public_key.as_bytes())?;
validator_nodes
.iter()
.find(|a| a.from_height <= height && height <= a.to_height)
.map(|a| a.shard_key)
.ok_or(ChainStorageError::ValueNotFound {
entity: "ShardKey",
field: "public_key",
value: public_key.to_hex(),
})
}
}

// Fetch the chain metadata
Expand Down
12 changes: 10 additions & 2 deletions base_layer/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ mod domain_hashing {
);
pub type InputMmrHasherBlake256 = DomainSeparatedHasher<Blake256, InputMmrHashDomain>;
pub type PrunedInputMmr = MerkleMountainRange<InputMmrHasherBlake256, PrunedHashSet>;
}

#[cfg(feature = "base_node")]
pub use domain_hashing::*;

mod validator_domain_hashing {
use tari_crypto::{hash::blake2::Blake256, hash_domain, hashing::DomainSeparatedHasher};
use tari_mmr::{Hash, MerkleMountainRange};

hash_domain!(
ValidatorNodeMmrHashDomain,
Expand All @@ -117,5 +125,5 @@ mod domain_hashing {
pub type ValidatorNodeMmrHasherBlake256 = DomainSeparatedHasher<Blake256, ValidatorNodeMmrHashDomain>;
pub type ValidatorNodeMmr = MerkleMountainRange<ValidatorNodeMmrHasherBlake256, Vec<Hash>>;
}
#[cfg(feature = "base_node")]
pub use domain_hashing::*;

pub use validator_domain_hashing::*;
6 changes: 5 additions & 1 deletion base_layer/core/src/test_helpers/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use croaring::Bitmap;
use tari_common::configuration::Network;
use tari_common_types::{
chain_metadata::ChainMetadata,
types::{Commitment, HashOutput, Signature},
types::{Commitment, HashOutput, PublicKey, Signature},
};
use tari_storage::lmdb_store::LMDBConfig;
use tari_test_utils::paths::create_temporary_data_path;
Expand Down Expand Up @@ -424,6 +424,10 @@ impl BlockchainBackend for TempDatabase {
fn fetch_committee(&self, height: u64, shard: [u8; 32]) -> Result<Vec<ActiveValidatorNode>, ChainStorageError> {
self.db.as_ref().unwrap().fetch_committee(height, shard)
}

fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError> {
self.db.as_ref().unwrap().get_shard_key(height, public_key)
}
}

pub fn create_chained_blocks<T: Into<BlockSpecs>>(
Expand Down

0 comments on commit 0fd3256

Please sign in to comment.