Skip to content

Commit

Permalink
Add GetUtxoReturnAddress RPC scaffolding
Browse files Browse the repository at this point in the history
  • Loading branch information
coderofstuff committed Mar 22, 2024
1 parent 8c41c67 commit c5e03c3
Show file tree
Hide file tree
Showing 20 changed files with 205 additions and 11 deletions.
14 changes: 14 additions & 0 deletions cli/src/modules/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,20 @@ impl Rpc {
}
}
}
RpcApiOps::GetUtxoReturnAddress => {
if argv.is_empty() || argv.len() != 2 {
return Err(Error::custom("Please specify a txid and a accepting_block_daa_score"));
}

let txid = argv.remove(0);
let txid = RpcHash::from_hex(txid.as_str())?;

let accepting_block_daa_score = argv.remove(0).parse::<u64>()?;

let result = rpc.get_utxo_return_address_call(GetUtxoReturnAddressRequest { txid, accepting_block_daa_score }).await?;

self.println(&ctx, result);
}
_ => {
tprintln!(ctx, "rpc method exists but is not supported by the cli: '{op_str}'\r\n");
return Ok(());
Expand Down
6 changes: 5 additions & 1 deletion components/consensusmanager/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use kaspa_consensus_core::{
header::Header,
pruning::{PruningPointProof, PruningPointTrustedData, PruningPointsList},
trusted::{ExternalGhostdagData, TrustedBlock},
tx::{MutableTransaction, Transaction, TransactionOutpoint, UtxoEntry},
tx::{MutableTransaction, ScriptPublicKey, Transaction, TransactionOutpoint, UtxoEntry},
BlockHashSet, BlueWorkType, ChainPath, Hash,
};
use kaspa_utils::sync::rwlock::*;
Expand Down Expand Up @@ -291,6 +291,10 @@ impl ConsensusSessionOwned {
self.clone().spawn_blocking(|c| c.get_chain_block_samples()).await
}

pub async fn async_get_utxo_return_address(&self, txid: Hash, accepting_block_daa_score: u64) -> Option<ScriptPublicKey> {
self.clone().spawn_blocking(move |c| c.get_utxo_return_address(txid, accepting_block_daa_score)).await
}

/// Returns the antipast of block `hash` from the POV of `context`, i.e. `antipast(hash) ∩ past(context)`.
/// Since this might be an expensive operation for deep blocks, we allow the caller to specify a limit
/// `max_traversal_allowed` on the maximum amount of blocks to traverse for obtaining the answer
Expand Down
6 changes: 5 additions & 1 deletion consensus/core/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
header::Header,
pruning::{PruningPointProof, PruningPointTrustedData, PruningPointsList},
trusted::{ExternalGhostdagData, TrustedBlock},
tx::{MutableTransaction, Transaction, TransactionOutpoint, UtxoEntry},
tx::{MutableTransaction, ScriptPublicKey, Transaction, TransactionOutpoint, UtxoEntry},
BlockHashSet, BlueWorkType, ChainPath,
};
use kaspa_hashes::Hash;
Expand Down Expand Up @@ -155,6 +155,10 @@ pub trait ConsensusApi: Send + Sync {
unimplemented!()
}

fn get_utxo_return_address(&self, txid: Hash, daa_score: u64) -> Option<ScriptPublicKey> {
unimplemented!()
}

fn get_virtual_parents(&self) -> BlockHashSet {
unimplemented!()
}
Expand Down
68 changes: 66 additions & 2 deletions consensus/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,16 @@ use kaspa_consensus_core::{
errors::{
coinbase::CoinbaseResult,
consensus::{ConsensusError, ConsensusResult},
difficulty::DifficultyError,
pruning::PruningImportError,
tx::TxResult,
},
errors::{difficulty::DifficultyError, pruning::PruningImportError},
header::Header,
muhash::MuHashExtensions,
network::NetworkType,
pruning::{PruningPointProof, PruningPointTrustedData, PruningPointsList},
trusted::{ExternalGhostdagData, TrustedBlock},
tx::{MutableTransaction, Transaction, TransactionOutpoint, UtxoEntry},
tx::{MutableTransaction, ScriptPublicKey, Transaction, TransactionOutpoint, UtxoEntry},
BlockHashSet, BlueWorkType, ChainPath,
};
use kaspa_consensus_notify::root::ConsensusNotificationRoot;
Expand Down Expand Up @@ -610,6 +611,69 @@ impl ConsensusApi for Consensus {
sample_headers
}

fn get_utxo_return_address(&self, txid: Hash, daa_score: u64) -> Option<ScriptPublicKey> {
// We need consistency between the past pruning points, selected chain and header store reads
let _guard = self.pruning_lock.blocking_read();

let sc_read = self.selected_chain_store.read();

let low = self.pruning_point_store.read().get().unwrap().pruning_point;
let high = sc_read.get_tip().unwrap().1;

let mut low_index = sc_read.get_by_hash(low).unwrap();
let mut high_index = sc_read.get_by_hash(high).unwrap();

// let mut locator = Vec::with_capacity((high_index - low_index).ceiling_log_base_2() as usize);
// let mut current_index = high_index;
let mut matching_chain_block_hash: Option<Hash> = None;
while low_index < high_index {
let mid = low_index + (high_index - low_index) / 2;

if let Ok(hash) = sc_read.get_by_index(mid) {
if let Ok(compact_header) = self.headers_store.get_compact_header_data(hash) {
if compact_header.daa_score == daa_score {
// We found the chain block we need
matching_chain_block_hash = Some(hash);
break;
} else if compact_header.daa_score < daa_score {
low_index = mid + 1;
} else {
high_index = mid - 1;
}
} else {
println!("Did not find a compact header with hash {}", hash);
break;
}
} else {
println!("Did not find a hash at index {}", mid);
break;
}
}

if matching_chain_block_hash.is_none() {
println!("No matching chain block hash found");
return None;
}

if let Ok(acceptance_data) = self.acceptance_data_store.get(matching_chain_block_hash.unwrap()) {
let containing_acceptance = acceptance_data
.iter()
.find(|&mbad| mbad.accepted_transactions.iter().find(|&tx| tx.transaction_id == txid).is_some())
.cloned();

if let Some(containing_acceptance) = containing_acceptance {
// I found the merged block containing the TXID
// let txs = self.block_transactions_store.get(containing_acceptance.block_hash).unwrap().iter().find(|tx| => )
} else {
return None;
}

return None;
} else {
return None;
};
}

fn get_virtual_parents(&self) -> BlockHashSet {
self.lkg_virtual_state.load().parents.iter().copied().collect()
}
Expand Down
2 changes: 2 additions & 0 deletions rpc/core/src/api/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ pub enum RpcApiOps {
GetCoinSupply,
/// Get DAA Score timestamp estimate
GetDaaScoreTimestampEstimate,
/// Get UTXO Return Addresses
GetUtxoReturnAddress,

// Subscription commands for starting/stopping notifications
NotifyBlockAdded,
Expand Down
5 changes: 5 additions & 0 deletions rpc/core/src/api/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ pub trait RpcApi: Sync + Send + AnySync {
request: GetDaaScoreTimestampEstimateRequest,
) -> RpcResult<GetDaaScoreTimestampEstimateResponse>;

async fn get_utxo_return_address(&self, txid: RpcHash, accepting_block_daa_score: u64) -> RpcResult<Option<RpcAddress>> {
Ok(self.get_utxo_return_address_call(GetUtxoReturnAddressRequest { txid, accepting_block_daa_score }).await?.return_address)
}
async fn get_utxo_return_address_call(&self, request: GetUtxoReturnAddressRequest) -> RpcResult<GetUtxoReturnAddressResponse>;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Notification API

Expand Down
25 changes: 25 additions & 0 deletions rpc/core/src/model/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,31 @@ impl GetDaaScoreTimestampEstimateResponse {
}
}

#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, BorshSchema)]
#[serde(rename_all = "camelCase")]
pub struct GetUtxoReturnAddressRequest {
pub txid: RpcHash,
pub accepting_block_daa_score: u64,
}

impl GetUtxoReturnAddressRequest {
pub fn new(txid: RpcHash, accepting_block_daa_score: u64) -> Self {
Self { txid, accepting_block_daa_score }
}
}

#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, BorshSchema)]
#[serde(rename_all = "camelCase")]
pub struct GetUtxoReturnAddressResponse {
pub return_address: Option<RpcAddress>,
}

impl GetUtxoReturnAddressResponse {
pub fn new(return_address: Option<RpcAddress>) -> Self {
Self { return_address }
}
}

// ----------------------------------------------------------------------------
// Subscriptions & notifications
// ----------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions rpc/grpc/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ impl RpcApi for GrpcClient {
route!(get_mempool_entries_by_addresses_call, GetMempoolEntriesByAddresses);
route!(get_coin_supply_call, GetCoinSupply);
route!(get_daa_score_timestamp_estimate_call, GetDaaScoreTimestampEstimate);
route!(get_utxo_return_address_call, GetUtxoReturnAddress);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Notification API
Expand Down
6 changes: 4 additions & 2 deletions rpc/grpc/core/proto/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ message KaspadRequest {
GetMetricsRequestMessage getMetricsRequest = 1090;
GetServerInfoRequestMessage getServerInfoRequest = 1092;
GetSyncStatusRequestMessage getSyncStatusRequest = 1094;
GetDaaScoreTimestampEstimateRequestMessage GetDaaScoreTimestampEstimateRequest = 1096;
GetDaaScoreTimestampEstimateRequestMessage getDaaScoreTimestampEstimateRequest = 1096;
GetUtxoReturnAddressRequestMessage GetUtxoReturnAddressRequest = 1098;
}
}

Expand Down Expand Up @@ -117,7 +118,8 @@ message KaspadResponse {
GetMetricsResponseMessage getMetricsResponse= 1091;
GetServerInfoResponseMessage getServerInfoResponse = 1093;
GetSyncStatusResponseMessage getSyncStatusResponse = 1095;
GetDaaScoreTimestampEstimateResponseMessage GetDaaScoreTimestampEstimateResponse = 1097;
GetDaaScoreTimestampEstimateResponseMessage getDaaScoreTimestampEstimateResponse = 1097;
GetUtxoReturnAddressResponseMessage GetUtxoReturnAddressResponse = 1099;
}
}

Expand Down
18 changes: 14 additions & 4 deletions rpc/grpc/core/proto/rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -844,10 +844,20 @@ message GetSyncStatusResponseMessage{
}

message GetDaaScoreTimestampEstimateRequestMessage {
repeated uint64 daa_scores = 1;
repeated uint64 daa_scores = 1;
}

message GetDaaScoreTimestampEstimateResponseMessage{
repeated uint64 timestamps = 1;
RPCError error = 1000;
message GetDaaScoreTimestampEstimateResponseMessage {
repeated uint64 timestamps = 1;
RPCError error = 1000;
}

message GetUtxoReturnAddressRequestMessage {
string txid = 1;
uint64 accepting_block_daa_score = 2;
}

message GetUtxoReturnAddressResponseMessage {
string return_address = 1;
RPCError error = 1000;
}
2 changes: 2 additions & 0 deletions rpc/grpc/core/src/convert/kaspad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub mod kaspad_request_convert {
impl_into_kaspad_request!(GetServerInfo);
impl_into_kaspad_request!(GetSyncStatus);
impl_into_kaspad_request!(GetDaaScoreTimestampEstimate);
impl_into_kaspad_request!(GetUtxoReturnAddress);

impl_into_kaspad_request!(NotifyBlockAdded);
impl_into_kaspad_request!(NotifyNewBlockTemplate);
Expand Down Expand Up @@ -188,6 +189,7 @@ pub mod kaspad_response_convert {
impl_into_kaspad_response!(GetServerInfo);
impl_into_kaspad_response!(GetSyncStatus);
impl_into_kaspad_response!(GetDaaScoreTimestampEstimate);
impl_into_kaspad_response!(GetUtxoReturnAddress);

impl_into_kaspad_notify_response!(NotifyBlockAdded);
impl_into_kaspad_notify_response!(NotifyNewBlockTemplate);
Expand Down
29 changes: 28 additions & 1 deletion rpc/grpc/core/src/convert/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! The SubmitBlockResponse is a notable exception to this general rule.

use crate::protowire::{self, submit_block_response_message::RejectReason};
use kaspa_consensus_core::network::NetworkId;
use kaspa_consensus_core::{network::NetworkId, Hash};
use kaspa_core::debug;
use kaspa_notify::subscription::Command;
use kaspa_rpc_core::{
Expand Down Expand Up @@ -394,6 +394,21 @@ from!(item: RpcResult<&kaspa_rpc_core::GetDaaScoreTimestampEstimateResponse>, pr
Self { timestamps: item.timestamps.clone(), error: None }
});

from!(item: &kaspa_rpc_core::GetUtxoReturnAddressRequest, protowire::GetUtxoReturnAddressRequestMessage, {
Self {
txid: item.txid.to_string(),
accepting_block_daa_score: item.accepting_block_daa_score
}
});
from!(item: RpcResult<&kaspa_rpc_core::GetUtxoReturnAddressResponse>, protowire::GetUtxoReturnAddressResponseMessage, {
if let Some(return_address) = &item.return_address {
Self { return_address: return_address.into(), error: None }
} else {
Self { return_address: String::from(""), error: None }
}

});

from!(&kaspa_rpc_core::PingRequest, protowire::PingRequestMessage);
from!(RpcResult<&kaspa_rpc_core::PingResponse>, protowire::PingResponseMessage);

Expand Down Expand Up @@ -791,6 +806,18 @@ try_from!(item: &protowire::GetDaaScoreTimestampEstimateResponseMessage, RpcResu
Self { timestamps: item.timestamps.clone() }
});

try_from!(item: &protowire::GetUtxoReturnAddressRequestMessage, kaspa_rpc_core::GetUtxoReturnAddressRequest , {
Self {
txid: if let Ok(txid) = Hash::from_str(&item.txid) { txid } else { Hash::default() },
accepting_block_daa_score: item.accepting_block_daa_score
}
});
try_from!(item: &protowire::GetUtxoReturnAddressResponseMessage, RpcResult<kaspa_rpc_core::GetUtxoReturnAddressResponse>, {
// Self { return_address: Some(Address::from(item.return_address)) }
// TODO: import Address
Self { return_address: None }
});

try_from!(&protowire::PingRequestMessage, kaspa_rpc_core::PingRequest);
try_from!(&protowire::PingResponseMessage, RpcResult<kaspa_rpc_core::PingResponse>);

Expand Down
1 change: 1 addition & 0 deletions rpc/grpc/core/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub enum KaspadPayloadOps {
GetServerInfo,
GetSyncStatus,
GetDaaScoreTimestampEstimate,
GetUtxoReturnAddress,

// Subscription commands for starting/stopping notifications
NotifyBlockAdded,
Expand Down
1 change: 1 addition & 0 deletions rpc/grpc/server/src/request_handler/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl Factory {
GetServerInfo,
GetSyncStatus,
GetDaaScoreTimestampEstimate,
GetUtxoReturnAddress,
NotifyBlockAdded,
NotifyNewBlockTemplate,
NotifyFinalityConflict,
Expand Down
4 changes: 4 additions & 0 deletions rpc/grpc/server/src/tests/rpc_core_mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ impl RpcApi for RpcCoreMock {
Err(RpcError::NotImplemented)
}

async fn get_utxo_return_address_call(&self, _request: GetUtxoReturnAddressRequest) -> RpcResult<GetUtxoReturnAddressResponse> {
Err(RpcError::NotImplemented)
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Notification API

Expand Down
7 changes: 7 additions & 0 deletions rpc/service/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,13 @@ NOTE: This error usually indicates an RPC conversion error between the node and
Ok(GetDaaScoreTimestampEstimateResponse::new(timestamps))
}

async fn get_utxo_return_address_call(&self, request: GetUtxoReturnAddressRequest) -> RpcResult<GetUtxoReturnAddressResponse> {
// let session = self.consensus_manager.consensus().session().await;
println!("{} {}", request.txid, request.accepting_block_daa_score);
// let mut maybe_spk = session.async_get_utxo_return_address(request.txid, request.accepting_block_daa_score).await;
Ok(GetUtxoReturnAddressResponse { return_address: None })
}

async fn ping_call(&self, _: PingRequest) -> RpcResult<PingResponse> {
Ok(PingResponse {})
}
Expand Down
1 change: 1 addition & 0 deletions rpc/wrpc/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ impl RpcApi for KaspaRpcClient {
GetCoinSupply,
GetConnectedPeerInfo,
GetDaaScoreTimestampEstimate,
GetUtxoReturnAddress,
GetServerInfo,
GetCurrentNetwork,
GetHeaders,
Expand Down
1 change: 1 addition & 0 deletions rpc/wrpc/server/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ impl Router {
GetCoinSupply,
GetConnectedPeerInfo,
GetDaaScoreTimestampEstimate,
GetUtxoReturnAddress,
GetServerInfo,
GetCurrentNetwork,
GetHeaders,
Expand Down
Loading

0 comments on commit c5e03c3

Please sign in to comment.