diff --git a/applications/tari_app_grpc/proto/base_node.proto b/applications/tari_app_grpc/proto/base_node.proto index 4b61816a22..7902ee8232 100644 --- a/applications/tari_app_grpc/proto/base_node.proto +++ b/applications/tari_app_grpc/proto/base_node.proto @@ -467,6 +467,7 @@ message GetShardKeyRequest { message GetShardKeyResponse { bytes shard_key = 1; + bool found = 2; } message GetTemplateRegistrationsRequest { diff --git a/applications/tari_base_node/src/grpc/base_node_grpc_server.rs b/applications/tari_base_node/src/grpc/base_node_grpc_server.rs index 09bd6783b7..4698648d1a 100644 --- a/applications/tari_base_node/src/grpc/base_node_grpc_server.rs +++ b/applications/tari_base_node/src/grpc/base_node_grpc_server.rs @@ -1461,13 +1461,22 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let mut handler = self.node_service.clone(); let public_key = PublicKey::from_bytes(&request.public_key) .map_err(|e| obscure_error_if_true(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); obscure_error_if_true(report_error_flag, Status::internal(e.to_string())) })?; - Ok(Response::new(tari_rpc::GetShardKeyResponse { - shard_key: shard_key.to_vec(), - })) + if let Some(shard_key) = shard_key { + Ok(Response::new(tari_rpc::GetShardKeyResponse { + shard_key: shard_key.to_vec(), + found: true, + })) + } else { + Ok(Response::new(tari_rpc::GetShardKeyResponse { + shard_key: vec![], + found: false, + })) + } } async fn get_active_validator_nodes( diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 9dd0d6b360..30509fe6f3 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -78,7 +78,7 @@ pub enum NodeCommsResponse { }, FetchValidatorNodesKeysResponse(Vec<(PublicKey, [u8; 32])>), FetchCommitteeResponse(Vec), - GetShardKeyResponse([u8; 32]), + GetShardKeyResponse(Option<[u8; 32]>), FetchTemplateRegistrationsResponse(Vec), } diff --git a/base_layer/core/src/base_node/comms_interface/local_interface.rs b/base_layer/core/src/base_node/comms_interface/local_interface.rs index 6f283ba0bd..a6f084cea3 100644 --- a/base_layer/core/src/base_node/comms_interface/local_interface.rs +++ b/base_layer/core/src/base_node/comms_interface/local_interface.rs @@ -302,7 +302,11 @@ impl LocalNodeCommsInterface { } } - pub async fn get_shard_key(&mut self, height: u64, public_key: PublicKey) -> Result<[u8; 32], CommsInterfaceError> { + pub async fn get_shard_key( + &mut self, + height: u64, + public_key: PublicKey, + ) -> Result, CommsInterfaceError> { match self .request_sender .call(NodeCommsRequest::GetShardKey { height, public_key }) diff --git a/base_layer/core/src/chain_storage/async_db.rs b/base_layer/core/src/chain_storage/async_db.rs index b25228a46a..27ff288bbb 100644 --- a/base_layer/core/src/chain_storage/async_db.rs +++ b/base_layer/core/src/chain_storage/async_db.rs @@ -269,7 +269,7 @@ impl AsyncBlockchainDb { make_async_fn!(fetch_committee(height: u64, shard: [u8;32]) -> Vec, "fetch_committee"); - make_async_fn!(get_shard_key(height:u64, public_key: PublicKey) -> [u8;32], "get_shard_key"); + make_async_fn!(get_shard_key(height:u64, public_key: PublicKey) -> Option<[u8;32]>, "get_shard_key"); make_async_fn!(fetch_template_registrations(from_height: u64) -> Vec, "fetch_template_registrations"); } diff --git a/base_layer/core/src/chain_storage/blockchain_backend.rs b/base_layer/core/src/chain_storage/blockchain_backend.rs index b30e280daa..b653477bd8 100644 --- a/base_layer/core/src/chain_storage/blockchain_backend.rs +++ b/base_layer/core/src/chain_storage/blockchain_backend.rs @@ -195,6 +195,6 @@ pub trait BlockchainBackend: Send + Sync { fn fetch_active_validator_nodes(&self, height: u64) -> Result, ChainStorageError>; fn fetch_committee(&self, height: u64, shard: [u8; 32]) -> Result, ChainStorageError>; - fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError>; + fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result, ChainStorageError>; fn fetch_template_registrations(&self, from_height: u64) -> Result, ChainStorageError>; } diff --git a/base_layer/core/src/chain_storage/blockchain_database.rs b/base_layer/core/src/chain_storage/blockchain_database.rs index d52954c388..b9da0d96bd 100644 --- a/base_layer/core/src/chain_storage/blockchain_database.rs +++ b/base_layer/core/src/chain_storage/blockchain_database.rs @@ -841,7 +841,7 @@ where B: BlockchainBackend db.fetch_mmr_size(tree) } - pub fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError> { + pub fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result, ChainStorageError> { let db = self.db_read_access()?; db.get_shard_key(height, public_key) } diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 50238f03ce..c4056aa92e 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -2562,19 +2562,18 @@ impl BlockchainBackend for LMDBDatabase { Ok(result) } - fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError> { + fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result, ChainStorageError> { let txn = self.read_transaction()?; - let validator_nodes: Vec = - 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(), - }) + let mut validator_nodes: Vec = + lmdb_fetch_matching_after(&txn, &self.validator_nodes, public_key.as_bytes())?; + validator_nodes = validator_nodes + .into_iter() + .filter(|a| a.from_height <= height && height <= a.to_height) + .collect(); + // get the last one + validator_nodes.sort_by(|a, b| a.from_height.cmp(&b.from_height)); + + Ok(validator_nodes.into_iter().map(|a| a.shard_key).last()) } fn fetch_template_registrations(&self, from_height: u64) -> Result, ChainStorageError> { diff --git a/base_layer/core/src/test_helpers/blockchain.rs b/base_layer/core/src/test_helpers/blockchain.rs index 655e5a1e54..2219f0089c 100644 --- a/base_layer/core/src/test_helpers/blockchain.rs +++ b/base_layer/core/src/test_helpers/blockchain.rs @@ -423,7 +423,7 @@ impl BlockchainBackend for TempDatabase { self.db.as_ref().unwrap().fetch_committee(height, shard) } - fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result<[u8; 32], ChainStorageError> { + fn get_shard_key(&self, height: u64, public_key: PublicKey) -> Result, ChainStorageError> { self.db.as_ref().unwrap().get_shard_key(height, public_key) } diff --git a/clients/nodejs/base_node_grpc_client/src/index.js b/clients/nodejs/base_node_grpc_client/src/index.js index 4413265dd7..7a9a219d6d 100644 --- a/clients/nodejs/base_node_grpc_client/src/index.js +++ b/clients/nodejs/base_node_grpc_client/src/index.js @@ -9,7 +9,7 @@ const path = require("path"); const packageDefinition = protoLoader.loadSync( path.resolve( __dirname, - "../../../applications/tari_app_grpc/proto/base_node.proto" + "../../../../applications/tari_app_grpc/proto/base_node.proto" ), { keepCase: true, diff --git a/clients/nodejs/wallet_grpc_client/index.js b/clients/nodejs/wallet_grpc_client/index.js index f05c4cb24f..bd3c942615 100644 --- a/clients/nodejs/wallet_grpc_client/index.js +++ b/clients/nodejs/wallet_grpc_client/index.js @@ -6,7 +6,7 @@ const protoLoader = require("@grpc/proto-loader"); const { promisifyAll } = require("grpc-promise"); const packageDefinition = protoLoader.loadSync( - `${__dirname}/../../applications/tari_app_grpc/proto/wallet.proto`, + `${__dirname}/../../../applications/tari_app_grpc/proto/wallet.proto`, { keepCase: true, longs: String,