Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
cc1181d
Begin work on low-level db api, and serialization.
D-Stacks Jan 22, 2026
a011a42
Unpolished crate.
D-Stacks Jan 22, 2026
415bf75
refractor, add resync logic.
D-Stacks Jan 26, 2026
d05501e
hook up to daemon, do args, and put into index processor.
D-Stacks Jan 26, 2026
388e817
hook up to all notifications, implement new retention root changed n…
D-Stacks Jan 27, 2026
385143d
some refractoring, get it running..
D-Stacks Jan 27, 2026
45856fe
start rpc implementation.
D-Stacks Jan 27, 2026
252cb86
start rpc implementation 2.
D-Stacks Jan 28, 2026
ee59cf8
finish rpc (without wasm).
D-Stacks Jan 29, 2026
4c716c0
move accepting blue scores away from db, and into subscription. some …
D-Stacks Jan 30, 2026
38af90e
integration tests
D-Stacks Feb 1, 2026
318d650
remove height scanning rpc
D-Stacks Feb 2, 2026
1e07622
wasm: centralize ITransactionData / inclusion & acceptance interfaces…
D-Stacks Feb 2, 2026
9045f25
remove tx_id from transaction data, fix some fmt and clippy.
D-Stacks Feb 2, 2026
6d35073
fix clippy warnings
D-Stacks Feb 2, 2026
e1deaf9
merge with master.
D-Stacks Feb 2, 2026
552bb7b
merge with master.
D-Stacks Feb 2, 2026
c4de18a
some clippy fixes
D-Stacks Feb 2, 2026
47dca99
some more fmt / clippy.
D-Stacks Feb 2, 2026
c3c735a
refractor some model into index core.
D-Stacks Feb 2, 2026
a483744
refractor some model into index core.
D-Stacks Feb 2, 2026
1695d32
u
D-Stacks Feb 2, 2026
89fc9a8
fix to wasm build.
D-Stacks Feb 2, 2026
3d694c4
some clean up.
D-Stacks Feb 3, 2026
3a183f8
some bug fixes.
D-Stacks Feb 3, 2026
c2560f0
makes notifer code and tests more readable.
D-Stacks Feb 4, 2026
6ccf358
make arg bool, add to everywhere.
D-Stacks Feb 4, 2026
88acdd3
fix pruning again.
D-Stacks Feb 5, 2026
ce4ccfc
fix pruning again.
D-Stacks Feb 5, 2026
9494178
rpc: replace GetTransaction includeTransactions bool with optional tr…
D-Stacks Feb 5, 2026
6f31104
work with optional transaction and verbosity.
D-Stacks Feb 5, 2026
9acddcb
work with optional transaction and verbosity.
D-Stacks Feb 6, 2026
8aec0ff
bug fix for include_unaccepted.
D-Stacks Feb 6, 2026
4245391
remove my gitignores.
D-Stacks Feb 6, 2026
6667bb3
update comment.
D-Stacks Feb 6, 2026
9f992bc
turn info to debug message.
D-Stacks Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ members = [
"notify",
"indexes/core",
"indexes/processor",
"indexes/txindex",
"indexes/utxoindex",
"rpc/macros",
"rpc/core",
Expand Down Expand Up @@ -119,6 +120,7 @@ kaspa-pow = { version = "1.1.0-rc.2", path = "consensus/pow" }
kaspa-rpc-core = { version = "1.1.0-rc.2", path = "rpc/core" }
kaspa-rpc-macros = { version = "1.1.0-rc.2", path = "rpc/macros" }
kaspa-rpc-service = { version = "1.1.0-rc.2", path = "rpc/service" }
kaspa-txindex = { version = "1.1.0-rc.2", path = "indexes/txindex" }
kaspa-txscript = { version = "1.1.0-rc.2", path = "crypto/txscript" }
kaspa-txscript-errors = { version = "1.1.0-rc.2", path = "crypto/txscript/errors" }
kaspa-utils = { version = "1.1.0-rc.2", path = "utils" }
Expand Down Expand Up @@ -235,6 +237,7 @@ secp256k1 = { version = "0.29.0", features = [
"rand-std",
"serde",
] } # TODO "0.28.0"
self_cell = "1.2.2"
separator = "0.4.1"
seqlock = "0.2.0"
serde = { version = "1.0.190", features = ["derive", "rc"] }
Expand Down
41 changes: 41 additions & 0 deletions cli/src/modules/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,47 @@ impl Rpc {

self.println(&ctx, result);
}
RpcApiOps::GetTransaction => {
if argv.is_empty() {
return Err(Error::custom("Missing transaction id argument"));
}
let transaction_id = argv.remove(0).parse::<TransactionId>()?;

argv.reverse(); // reverse to allow popping arguments in the correct order
let include_unaccepted = argv.pop().unwrap_or("false".to_string()).parse::<bool>().ok().unwrap_or_default();
// parse transaction verbosity: accept named (none|low|high|full) or numeric (0|1|2|3) verbosity levels, default to None if parsing fails or if not provided
let tx_verbosity_token = argv.pop().unwrap_or("none".to_string());
let transaction_verbosity = match tx_verbosity_token.to_lowercase().as_str() {
"none" => Some(RpcDataVerbosityLevel::None),
"low" => Some(RpcDataVerbosityLevel::Low),
"high" => Some(RpcDataVerbosityLevel::High),
"full" => Some(RpcDataVerbosityLevel::Full),
other => {
if let Ok(i) = other.parse::<i32>() {
Some(RpcDataVerbosityLevel::try_from(i)?)
} else {
Some(RpcDataVerbosityLevel::None)
}
}
};
let include_inclusion_data = argv.pop().unwrap_or("false".to_string()).parse::<bool>().ok().unwrap_or_default();
let include_acceptance_data = argv.pop().unwrap_or("false".to_string()).parse::<bool>().ok().unwrap_or_default();
let include_conf_count = argv.pop().unwrap_or("false".to_string()).parse::<bool>().ok().unwrap_or_default();
let result = rpc
.get_transaction_call(
None,
GetTransactionRequest {
transaction_id,
include_unaccepted,
transaction_verbosity,
include_inclusion_data,
include_acceptance_data,
include_conf_count,
},
)
.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
38 changes: 36 additions & 2 deletions consensus/client/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use kaspa_utils::hex::*;
const TS_TRANSACTION: &'static str = r#"
/**
* Interface defining the structure of a transaction.
*
*
* @category Consensus
*/
export interface ITransaction {
Expand All @@ -43,7 +43,7 @@ export interface ITransaction {

/**
* Optional transaction verbose data.
*
*
* @category Node RPC
*/
export interface ITransactionVerboseData {
Expand All @@ -53,6 +53,40 @@ export interface ITransactionVerboseData {
blockHash : HexString;
blockTime : bigint;
}

/**
* Transaction data returned by GetTransaction.
*
* @category Node RPC
*/
export interface ITransactionData {
transactions: ITransaction[];
inclusionData: ITransactionInclusionData[];
acceptanceData?: ITransactionAcceptanceData;
confCount?: bigint;
}

/**
* Transaction inclusion data
*
* @category Node RPC
*/
export interface ITransactionInclusionData {
includingBlockHash: HexString;
includingDaaScore: bigint;
indexWithinBlock: number;
}

/**
* Transaction acceptance data
*
* @category Node RPC
*/
export interface ITransactionAcceptanceData {
acceptingBlockHash: HexString;
acceptingBlueScore: bigint;
mergesetIndex: number;
}
"#;

#[wasm_bindgen]
Expand Down
21 changes: 19 additions & 2 deletions consensus/core/src/acceptance_data.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use kaspa_hashes::Hash;
use serde::{Deserialize, Serialize};

use crate::tx::TransactionId;
use crate::tx::{TransactionId, TransactionIndexType};

// A mergeset currently cannot have more then 512 blocks.
pub type MergesetIndexType = u16;

/// Holds a mergeset acceptance data, a list of all its merged block with their accepted transactions
pub type AcceptanceData = Vec<MergesetBlockAcceptanceData>;
Expand All @@ -16,5 +19,19 @@ pub struct MergesetBlockAcceptanceData {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AcceptedTxEntry {
pub transaction_id: TransactionId,
pub index_within_block: u32,
pub index_within_block: TransactionIndexType,
}

#[cfg(test)]
mod tests {
use super::*;
use crate::config::params::ALL_PARAMS;

#[test]
fn test_mergeset_index_does_not_overflow() {
for param in ALL_PARAMS.iter() {
// make sure that MergesetIdx can hold mergeset_size_limit
MergesetIndexType::try_from(param.mergeset_size_limit()).unwrap();
}
}
}
8 changes: 8 additions & 0 deletions consensus/core/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,14 @@ pub trait ConsensusApi: Send + Sync {
unimplemented!()
}

fn get_block_transaction_iterator(&self) -> Box<dyn Iterator<Item = (Hash, Arc<Vec<Transaction>>)> + Send + Sync + '_> {
unimplemented!()
}

fn get_acceptance_data_iterator(&self) -> Box<dyn Iterator<Item = (Hash, Arc<AcceptanceData>)> + Send + Sync + '_> {
unimplemented!()
}

fn create_virtual_selected_chain_block_locator(&self, low: Option<Hash>, high: Option<Hash>) -> ConsensusResult<Vec<Hash>> {
unimplemented!()
}
Expand Down
4 changes: 4 additions & 0 deletions consensus/core/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub struct Config {
/// Enable the UTXO index
pub utxoindex: bool,

/// Enable the TX index
pub txindex: bool,

/// Enable RPC commands which affect the state of the node
pub unsafe_rpc: bool,

Expand Down Expand Up @@ -86,6 +89,7 @@ impl Config {
is_archival: false,
enable_sanity_checks: false,
utxoindex: false,
txindex: false,
unsafe_rpc: false,
enable_unsynced_mining: false,
enable_mainnet_mining: false,
Expand Down
5 changes: 4 additions & 1 deletion consensus/core/src/config/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ use std::{
ops::{Deref, DerefMut},
};

// All supported params
pub const ALL_PARAMS: [Params; 4] = [MAINNET_PARAMS, TESTNET_PARAMS, DEVNET_PARAMS, SIMNET_PARAMS];

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ForkActivation(u64);

Expand Down Expand Up @@ -53,7 +56,7 @@ impl ForkActivation {
}

/// Checks if the fork is expected to be activated "soon", i.e., in the time frame of the provided range.
/// Returns the distance from activation if so, or `None` otherwise.
/// Returns the distance from activation if so, or `None` otherwise.
pub fn is_within_range_before_activation(self, current_daa_score: u64, range: u64) -> Option<u64> {
if !self.is_active(current_daa_score) && current_daa_score + range > self.0 { Some(self.0 - current_daa_score) } else { None }
}
Expand Down
2 changes: 2 additions & 0 deletions consensus/core/src/errors/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub enum ConsensusError {

#[error("{0}")]
GeneralOwned(String),
//#[error("store error: {0}")]
//StoreError(#[from] kaspa_database::prelude::StoreError),
}

pub type ConsensusResult<T> = std::result::Result<T, ConsensusError>;
48 changes: 36 additions & 12 deletions consensus/notify/src/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub enum Notification {
#[display(fmt = "BlockAdded notification: block hash {}", "_0.block.header.hash")]
BlockAdded(BlockAddedNotification),

#[display(fmt = "VirtualChainChanged notification: {} removed blocks, {} added blocks, {} accepted transactions", "_0.removed_chain_block_hashes.len()", "_0.added_chain_block_hashes.len()", "_0.added_chain_blocks_acceptance_data.len()")]
#[display(fmt = "VirtualChainChanged notification: {} removed blocks, {} added blocks, {} accepted transactions, {} accepting blue scores", "_0.removed_chain_block_hashes.len()", "_0.added_chain_block_hashes.len()", "_0.added_chain_blocks_acceptance_data.len()", "_0.added_accepting_blue_scores.len()")]
VirtualChainChanged(VirtualChainChangedNotification),

#[display(fmt = "FinalityConflict notification: violating block hash {}", "_0.violating_block_hash")]
Expand All @@ -42,8 +42,10 @@ pub enum Notification {

#[display(fmt = "NewBlockTemplate notification")]
NewBlockTemplate(NewBlockTemplateNotification),
}
}

#[display(fmt = "RetentionRootChanged notification: retention root {}", "_0.retention_root")]
RetentionRootChanged(RetentionRootChangedNotification),
}}

impl NotificationTrait for Notification {
fn apply_overall_subscription(&self, subscription: &OverallSubscription, _context: &SubscriptionContext) -> Option<Self> {
Expand All @@ -63,13 +65,20 @@ impl NotificationTrait for Notification {
// If the subscription excludes accepted transaction ids and the notification includes some
// then we must re-create the object and drop the ids, otherwise we can clone it as is.
if let Notification::VirtualChainChanged(payload) = self {
if !subscription.include_accepted_transaction_ids() && !payload.added_chain_blocks_acceptance_data.is_empty() {
return Some(Notification::VirtualChainChanged(VirtualChainChangedNotification {
removed_chain_block_hashes: payload.removed_chain_block_hashes.clone(),
added_chain_block_hashes: payload.added_chain_block_hashes.clone(),
added_chain_blocks_acceptance_data: Arc::new(vec![]),
}));
}
return Some(Notification::VirtualChainChanged(VirtualChainChangedNotification {
removed_chain_block_hashes: payload.removed_chain_block_hashes.clone(),
added_chain_block_hashes: payload.added_chain_block_hashes.clone(),
added_chain_blocks_acceptance_data: if !subscription.include_accepted_transaction_ids() {
Arc::new(Vec::new())
} else {
payload.added_chain_blocks_acceptance_data.clone()
},
added_accepting_blue_scores: if !subscription.include_accepting_blue_scores() {
Arc::new(Vec::new())
} else {
payload.added_accepting_blue_scores.clone()
},
}));
}
Some(self.clone())
}
Expand All @@ -92,7 +101,7 @@ impl NotificationTrait for Notification {
}
}

#[derive(Debug, Clone)]
#[derive(Clone, Debug)]
pub struct BlockAddedNotification {
pub block: Block,
}
Expand All @@ -108,14 +117,16 @@ pub struct VirtualChainChangedNotification {
pub added_chain_block_hashes: Arc<Vec<Hash>>,
pub removed_chain_block_hashes: Arc<Vec<Hash>>,
pub added_chain_blocks_acceptance_data: Arc<Vec<Arc<AcceptanceData>>>,
pub added_accepting_blue_scores: Arc<Vec<u64>>,
}
impl VirtualChainChangedNotification {
pub fn new(
added_chain_block_hashes: Arc<Vec<Hash>>,
removed_chain_block_hashes: Arc<Vec<Hash>>,
added_chain_blocks_acceptance_data: Arc<Vec<Arc<AcceptanceData>>>,
added_accepting_blue_scores: Arc<Vec<u64>>,
) -> Self {
Self { added_chain_block_hashes, removed_chain_block_hashes, added_chain_blocks_acceptance_data }
Self { added_chain_block_hashes, removed_chain_block_hashes, added_chain_blocks_acceptance_data, added_accepting_blue_scores }
}
}

Expand Down Expand Up @@ -181,3 +192,16 @@ pub struct PruningPointUtxoSetOverrideNotification {}

#[derive(Debug, Clone)]
pub struct NewBlockTemplateNotification {}

#[derive(Debug, Clone)]
pub struct RetentionRootChangedNotification {
pub retention_root: Hash,
pub retention_root_blue_score: u64,
pub retention_root_daa_score: u64,
}

impl RetentionRootChangedNotification {
pub fn new(retention_root: Hash, retention_root_blue_score: u64, retention_root_daa_score: u64) -> Self {
Self { retention_root, retention_root_blue_score, retention_root_daa_score }
}
}
Loading