Skip to content

Commit fd741c8

Browse files
author
supr
authored
Merge branch 'kaspanet:master' into master
2 parents f62e31b + ac677a0 commit fd741c8

File tree

21 files changed

+523
-220
lines changed

21 files changed

+523
-220
lines changed

Cargo.lock

Lines changed: 58 additions & 58 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ members = [
6363

6464
[workspace.package]
6565
rust-version = "1.82.0"
66-
version = "0.17.0"
66+
version = "0.17.1"
6767
authors = ["Kaspa developers"]
6868
license = "ISC"
6969
repository = "https://github.com/kaspanet/rusty-kaspa"
@@ -80,61 +80,61 @@ include = [
8080
]
8181

8282
[workspace.dependencies]
83-
# kaspa-testing-integration = { version = "0.17.0", path = "testing/integration" }
84-
kaspa-addresses = { version = "0.17.0", path = "crypto/addresses" }
85-
kaspa-addressmanager = { version = "0.17.0", path = "components/addressmanager" }
86-
kaspa-bip32 = { version = "0.17.0", path = "wallet/bip32" }
87-
kaspa-cli = { version = "0.17.0", path = "cli" }
88-
kaspa-connectionmanager = { version = "0.17.0", path = "components/connectionmanager" }
89-
kaspa-consensus = { version = "0.17.0", path = "consensus" }
90-
kaspa-consensus-core = { version = "0.17.0", path = "consensus/core" }
91-
kaspa-consensus-client = { version = "0.17.0", path = "consensus/client" }
92-
kaspa-consensus-notify = { version = "0.17.0", path = "consensus/notify" }
93-
kaspa-consensus-wasm = { version = "0.17.0", path = "consensus/wasm" }
94-
kaspa-consensusmanager = { version = "0.17.0", path = "components/consensusmanager" }
95-
kaspa-core = { version = "0.17.0", path = "core" }
96-
kaspa-daemon = { version = "0.17.0", path = "daemon" }
97-
kaspa-database = { version = "0.17.0", path = "database" }
98-
kaspa-grpc-client = { version = "0.17.0", path = "rpc/grpc/client" }
99-
kaspa-grpc-core = { version = "0.17.0", path = "rpc/grpc/core" }
100-
kaspa-grpc-server = { version = "0.17.0", path = "rpc/grpc/server" }
101-
kaspa-hashes = { version = "0.17.0", path = "crypto/hashes" }
102-
kaspa-index-core = { version = "0.17.0", path = "indexes/core" }
103-
kaspa-index-processor = { version = "0.17.0", path = "indexes/processor" }
104-
kaspa-math = { version = "0.17.0", path = "math" }
105-
kaspa-merkle = { version = "0.17.0", path = "crypto/merkle" }
106-
kaspa-metrics-core = { version = "0.17.0", path = "metrics/core" }
107-
kaspa-mining = { version = "0.17.0", path = "mining" }
108-
kaspa-mining-errors = { version = "0.17.0", path = "mining/errors" }
109-
kaspa-muhash = { version = "0.17.0", path = "crypto/muhash" }
110-
kaspa-notify = { version = "0.17.0", path = "notify" }
111-
kaspa-p2p-flows = { version = "0.17.0", path = "protocol/flows" }
112-
kaspa-p2p-lib = { version = "0.17.0", path = "protocol/p2p" }
113-
kaspa-perf-monitor = { version = "0.17.0", path = "metrics/perf_monitor" }
114-
kaspa-pow = { version = "0.17.0", path = "consensus/pow" }
115-
kaspa-rpc-core = { version = "0.17.0", path = "rpc/core" }
116-
kaspa-rpc-macros = { version = "0.17.0", path = "rpc/macros" }
117-
kaspa-rpc-service = { version = "0.17.0", path = "rpc/service" }
118-
kaspa-txscript = { version = "0.17.0", path = "crypto/txscript" }
119-
kaspa-txscript-errors = { version = "0.17.0", path = "crypto/txscript/errors" }
120-
kaspa-utils = { version = "0.17.0", path = "utils" }
121-
kaspa-utils-tower = { version = "0.17.0", path = "utils/tower" }
122-
kaspa-utxoindex = { version = "0.17.0", path = "indexes/utxoindex" }
123-
kaspa-wallet = { version = "0.17.0", path = "wallet/native" }
124-
kaspa-wallet-cli-wasm = { version = "0.17.0", path = "wallet/wasm" }
125-
kaspa-wallet-keys = { version = "0.17.0", path = "wallet/keys" }
126-
kaspa-wallet-pskt = { version = "0.17.0", path = "wallet/pskt" }
127-
kaspa-wallet-core = { version = "0.17.0", path = "wallet/core" }
128-
kaspa-wallet-macros = { version = "0.17.0", path = "wallet/macros" }
129-
kaspa-wasm = { version = "0.17.0", path = "wasm" }
130-
kaspa-wasm-core = { version = "0.17.0", path = "wasm/core" }
131-
kaspa-wrpc-client = { version = "0.17.0", path = "rpc/wrpc/client" }
132-
kaspa-wrpc-proxy = { version = "0.17.0", path = "rpc/wrpc/proxy" }
133-
kaspa-wrpc-server = { version = "0.17.0", path = "rpc/wrpc/server" }
134-
kaspa-wrpc-wasm = { version = "0.17.0", path = "rpc/wrpc/wasm" }
135-
kaspa-wrpc-example-subscriber = { version = "0.17.0", path = "rpc/wrpc/examples/subscriber" }
136-
kaspad = { version = "0.17.0", path = "kaspad" }
137-
kaspa-alloc = { version = "0.17.0", path = "utils/alloc" }
83+
# kaspa-testing-integration = { version = "0.17.1", path = "testing/integration" }
84+
kaspa-addresses = { version = "0.17.1", path = "crypto/addresses" }
85+
kaspa-addressmanager = { version = "0.17.1", path = "components/addressmanager" }
86+
kaspa-bip32 = { version = "0.17.1", path = "wallet/bip32" }
87+
kaspa-cli = { version = "0.17.1", path = "cli" }
88+
kaspa-connectionmanager = { version = "0.17.1", path = "components/connectionmanager" }
89+
kaspa-consensus = { version = "0.17.1", path = "consensus" }
90+
kaspa-consensus-core = { version = "0.17.1", path = "consensus/core" }
91+
kaspa-consensus-client = { version = "0.17.1", path = "consensus/client" }
92+
kaspa-consensus-notify = { version = "0.17.1", path = "consensus/notify" }
93+
kaspa-consensus-wasm = { version = "0.17.1", path = "consensus/wasm" }
94+
kaspa-consensusmanager = { version = "0.17.1", path = "components/consensusmanager" }
95+
kaspa-core = { version = "0.17.1", path = "core" }
96+
kaspa-daemon = { version = "0.17.1", path = "daemon" }
97+
kaspa-database = { version = "0.17.1", path = "database" }
98+
kaspa-grpc-client = { version = "0.17.1", path = "rpc/grpc/client" }
99+
kaspa-grpc-core = { version = "0.17.1", path = "rpc/grpc/core" }
100+
kaspa-grpc-server = { version = "0.17.1", path = "rpc/grpc/server" }
101+
kaspa-hashes = { version = "0.17.1", path = "crypto/hashes" }
102+
kaspa-index-core = { version = "0.17.1", path = "indexes/core" }
103+
kaspa-index-processor = { version = "0.17.1", path = "indexes/processor" }
104+
kaspa-math = { version = "0.17.1", path = "math" }
105+
kaspa-merkle = { version = "0.17.1", path = "crypto/merkle" }
106+
kaspa-metrics-core = { version = "0.17.1", path = "metrics/core" }
107+
kaspa-mining = { version = "0.17.1", path = "mining" }
108+
kaspa-mining-errors = { version = "0.17.1", path = "mining/errors" }
109+
kaspa-muhash = { version = "0.17.1", path = "crypto/muhash" }
110+
kaspa-notify = { version = "0.17.1", path = "notify" }
111+
kaspa-p2p-flows = { version = "0.17.1", path = "protocol/flows" }
112+
kaspa-p2p-lib = { version = "0.17.1", path = "protocol/p2p" }
113+
kaspa-perf-monitor = { version = "0.17.1", path = "metrics/perf_monitor" }
114+
kaspa-pow = { version = "0.17.1", path = "consensus/pow" }
115+
kaspa-rpc-core = { version = "0.17.1", path = "rpc/core" }
116+
kaspa-rpc-macros = { version = "0.17.1", path = "rpc/macros" }
117+
kaspa-rpc-service = { version = "0.17.1", path = "rpc/service" }
118+
kaspa-txscript = { version = "0.17.1", path = "crypto/txscript" }
119+
kaspa-txscript-errors = { version = "0.17.1", path = "crypto/txscript/errors" }
120+
kaspa-utils = { version = "0.17.1", path = "utils" }
121+
kaspa-utils-tower = { version = "0.17.1", path = "utils/tower" }
122+
kaspa-utxoindex = { version = "0.17.1", path = "indexes/utxoindex" }
123+
kaspa-wallet = { version = "0.17.1", path = "wallet/native" }
124+
kaspa-wallet-cli-wasm = { version = "0.17.1", path = "wallet/wasm" }
125+
kaspa-wallet-keys = { version = "0.17.1", path = "wallet/keys" }
126+
kaspa-wallet-pskt = { version = "0.17.1", path = "wallet/pskt" }
127+
kaspa-wallet-core = { version = "0.17.1", path = "wallet/core" }
128+
kaspa-wallet-macros = { version = "0.17.1", path = "wallet/macros" }
129+
kaspa-wasm = { version = "0.17.1", path = "wasm" }
130+
kaspa-wasm-core = { version = "0.17.1", path = "wasm/core" }
131+
kaspa-wrpc-client = { version = "0.17.1", path = "rpc/wrpc/client" }
132+
kaspa-wrpc-proxy = { version = "0.17.1", path = "rpc/wrpc/proxy" }
133+
kaspa-wrpc-server = { version = "0.17.1", path = "rpc/wrpc/server" }
134+
kaspa-wrpc-wasm = { version = "0.17.1", path = "rpc/wrpc/wasm" }
135+
kaspa-wrpc-example-subscriber = { version = "0.17.1", path = "rpc/wrpc/examples/subscriber" }
136+
kaspad = { version = "0.17.1", path = "kaspad" }
137+
kaspa-alloc = { version = "0.17.1", path = "utils/alloc" }
138138

139139
# external
140140
aes = "0.8.3"

components/consensusmanager/src/session.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ impl ConsensusSessionOwned {
254254
self.clone().spawn_blocking(move |c| c.get_current_block_color(hash)).await
255255
}
256256

257-
/// source refers to the earliest block from which the current node has full header & block data
258-
pub async fn async_get_source(&self) -> Hash {
259-
self.clone().spawn_blocking(|c| c.get_source()).await
257+
/// retention period root refers to the earliest block from which the current node has full header & block data
258+
pub async fn async_get_retention_period_root(&self) -> Hash {
259+
self.clone().spawn_blocking(|c| c.get_retention_period_root()).await
260260
}
261261

262262
pub async fn async_estimate_block_count(&self) -> BlockCount {

consensus/core/src/api/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ pub trait ConsensusApi: Send + Sync {
143143
unimplemented!()
144144
}
145145

146-
/// source refers to the earliest block from which the current node has full header & block data
147-
fn get_source(&self) -> Hash {
146+
/// retention period root refers to the earliest block from which the current node has full header & block data
147+
fn get_retention_period_root(&self) -> Hash {
148148
unimplemented!()
149149
}
150150

consensus/core/src/config/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ pub struct Config {
6868

6969
/// A scale factor to apply to memory allocation bounds
7070
pub ram_scale: f64,
71+
72+
/// The number of days to keep data for
73+
pub retention_period_days: Option<f64>,
7174
}
7275

7376
impl Config {
@@ -95,6 +98,7 @@ impl Config {
9598
initial_utxo_set: Default::default(),
9699
disable_upnp: false,
97100
ram_scale: 1.0,
101+
retention_period_days: None,
98102
}
99103
}
100104

consensus/src/consensus/mod.rs

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,39 @@ impl Consensus {
307307
is_consensus_exiting,
308308
};
309309

310-
// TODO (post HF): remove the upgrade
311-
// Database upgrade to include pruning samples
312-
this.pruning_samples_database_upgrade();
310+
// Run database upgrades if any
311+
this.run_database_upgrades();
313312

314313
this
315314
}
316315

316+
/// A procedure for calling database upgrades which are self-contained (i.e., do not require knowing the DB version)
317+
fn run_database_upgrades(&self) {
318+
// Upgrade to initialize the new retention root field correctly
319+
self.retention_root_database_upgrade();
320+
321+
// TODO (post HF): remove this upgrade
322+
// Database upgrade to include pruning samples
323+
self.pruning_samples_database_upgrade();
324+
}
325+
326+
fn retention_root_database_upgrade(&self) {
327+
let mut pruning_point_store = self.pruning_point_store.write();
328+
if pruning_point_store.retention_period_root().unwrap_option().is_none() {
329+
let mut batch = rocksdb::WriteBatch::default();
330+
if self.config.is_archival {
331+
// The retention checkpoint is what was previously known as history root
332+
let retention_checkpoint = pruning_point_store.retention_checkpoint().unwrap();
333+
pruning_point_store.set_retention_period_root(&mut batch, retention_checkpoint).unwrap();
334+
} else {
335+
// For non-archival nodes the retention root was the pruning point
336+
let pruning_point = pruning_point_store.get().unwrap().pruning_point;
337+
pruning_point_store.set_retention_period_root(&mut batch, pruning_point).unwrap();
338+
}
339+
self.db.write(batch).unwrap();
340+
}
341+
}
342+
317343
fn pruning_samples_database_upgrade(&self) {
318344
//
319345
// For the first time this version runs, make sure we populate pruning samples
@@ -565,8 +591,8 @@ impl ConsensusApi for Consensus {
565591
// Verify the block exists and can be assumed to have relations and reachability data
566592
self.validate_block_exists(hash).ok()?;
567593

568-
// Verify that the block is in future(source), where Ghostdag data is complete
569-
self.services.reachability_service.is_dag_ancestor_of(self.get_source(), hash).then_some(())?;
594+
// Verify that the block is in future(retention root), where Ghostdag data is complete
595+
self.services.reachability_service.is_dag_ancestor_of(self.get_retention_period_root(), hash).then_some(())?;
570596

571597
let sink = self.get_sink();
572598

@@ -621,31 +647,26 @@ impl ConsensusApi for Consensus {
621647
self.lkg_virtual_state.load().to_virtual_state_approx_id()
622648
}
623649

624-
fn get_source(&self) -> Hash {
625-
if self.config.is_archival {
626-
// we use the history root in archival cases.
627-
return self.pruning_point_store.read().history_root().unwrap();
628-
}
629-
self.pruning_point_store.read().pruning_point().unwrap()
650+
fn get_retention_period_root(&self) -> Hash {
651+
self.pruning_point_store.read().retention_period_root().unwrap()
630652
}
631653

632-
/// Estimates number of blocks and headers stored in the node
654+
/// Estimates the number of blocks and headers stored in the node database.
633655
///
634-
/// This is an estimation based on the daa score difference between the node's `source` and `sink`'s daa score,
656+
/// This is an estimation based on the DAA score difference between the node's `retention root` and `virtual`'s DAA score,
635657
/// as such, it does not include non-daa blocks, and does not include headers stored as part of the pruning proof.
636658
fn estimate_block_count(&self) -> BlockCount {
637-
// PRUNE SAFETY: node is either archival or source is the pruning point which its header is kept permanently
638-
let source_score = self.headers_store.get_compact_header_data(self.get_source()).unwrap().daa_score;
659+
// PRUNE SAFETY: retention root is always a current or past pruning point which its header is kept permanently
660+
let retention_period_root_score = self.headers_store.get_daa_score(self.get_retention_period_root()).unwrap();
639661
let virtual_score = self.get_virtual_daa_score();
640662
let header_count = self
641663
.headers_store
642-
.get_compact_header_data(self.get_headers_selected_tip())
664+
.get_daa_score(self.get_headers_selected_tip())
643665
.unwrap_option()
644-
.map(|h| h.daa_score)
645666
.unwrap_or(virtual_score)
646667
.max(virtual_score)
647-
- source_score;
648-
let block_count = virtual_score - source_score;
668+
- retention_period_root_score;
669+
let block_count = virtual_score - retention_period_root_score;
649670
BlockCount { header_count, block_count }
650671
}
651672

@@ -668,12 +689,12 @@ impl ConsensusApi for Consensus {
668689
// Verify that the block exists
669690
self.validate_block_exists(low)?;
670691

671-
// Verify that source is on chain(block)
692+
// Verify that retention root is on chain(block)
672693
self.services
673694
.reachability_service
674-
.is_chain_ancestor_of(self.get_source(), low)
695+
.is_chain_ancestor_of(self.get_retention_period_root(), low)
675696
.then_some(())
676-
.ok_or(ConsensusError::General("the queried hash does not have source on its chain"))?;
697+
.ok_or(ConsensusError::General("the queried hash does not have retention root on its chain"))?;
677698

678699
Ok(self.services.dag_traversal_manager.calculate_chain_path(low, self.get_sink(), chain_path_added_limit))
679700
}
@@ -748,7 +769,7 @@ impl ConsensusApi for Consensus {
748769
fn get_populated_transaction(&self, txid: Hash, accepting_block_daa_score: u64) -> Result<SignableTransaction, UtxoInquirerError> {
749770
// We need consistency between the pruning_point_store, utxo_diffs_store, block_transactions_store, selected chain and headers store reads
750771
let _guard = self.pruning_lock.blocking_read();
751-
self.virtual_processor.get_populated_transaction(txid, accepting_block_daa_score, self.get_source())
772+
self.virtual_processor.get_populated_transaction(txid, accepting_block_daa_score, self.get_retention_period_root())
752773
}
753774

754775
fn get_virtual_parents(&self) -> BlockHashSet {

consensus/src/model/stores/pruning.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,16 @@ pub trait PruningStoreReader {
3939
fn get(&self) -> StoreResult<PruningPointInfo>;
4040

4141
/// Represent the point after which data is fully held (i.e., history is consecutive from this point and up to virtual).
42-
/// This is usually the pruning point, though it might lag a bit behind until data prune completes (and for archival
43-
/// nodes it will remain the initial syncing point or the last pruning point before turning to an archive)
44-
fn history_root(&self) -> StoreResult<Hash>;
42+
/// This is usually a pruning point that is at or below the retention period requirement (and for archival
43+
/// nodes it will remain the initial syncing point or the last pruning point before turning to an archive).
44+
/// At every pruning point movement, this is adjusted to the next pruning point sample that satisfies the required
45+
/// retention period.
46+
fn retention_period_root(&self) -> StoreResult<Hash>;
47+
48+
// During pruning, this is a reference to the retention root before the pruning point move.
49+
// After pruning, this is updated to point to the retention period root.
50+
// This checkpoint is used to determine if pruning has successfully completed.
51+
fn retention_checkpoint(&self) -> StoreResult<Hash>;
4552
}
4653

4754
pub trait PruningStore: PruningStoreReader {
@@ -53,15 +60,17 @@ pub trait PruningStore: PruningStoreReader {
5360
pub struct DbPruningStore {
5461
db: Arc<DB>,
5562
access: CachedDbItem<PruningPointInfo>,
56-
history_root_access: CachedDbItem<Hash>,
63+
retention_checkpoint_access: CachedDbItem<Hash>,
64+
retention_period_root_access: CachedDbItem<Hash>,
5765
}
5866

5967
impl DbPruningStore {
6068
pub fn new(db: Arc<DB>) -> Self {
6169
Self {
6270
db: Arc::clone(&db),
6371
access: CachedDbItem::new(db.clone(), DatabaseStorePrefixes::PruningPoint.into()),
64-
history_root_access: CachedDbItem::new(db, DatabaseStorePrefixes::HistoryRoot.into()),
72+
retention_checkpoint_access: CachedDbItem::new(db.clone(), DatabaseStorePrefixes::RetentionCheckpoint.into()),
73+
retention_period_root_access: CachedDbItem::new(db, DatabaseStorePrefixes::RetentionPeriodRoot.into()),
6574
}
6675
}
6776

@@ -73,8 +82,12 @@ impl DbPruningStore {
7382
self.access.write(BatchDbWriter::new(batch), &PruningPointInfo { pruning_point, candidate, index })
7483
}
7584

76-
pub fn set_history_root(&mut self, batch: &mut WriteBatch, history_root: Hash) -> StoreResult<()> {
77-
self.history_root_access.write(BatchDbWriter::new(batch), &history_root)
85+
pub fn set_retention_checkpoint(&mut self, batch: &mut WriteBatch, retention_checkpoint: Hash) -> StoreResult<()> {
86+
self.retention_checkpoint_access.write(BatchDbWriter::new(batch), &retention_checkpoint)
87+
}
88+
89+
pub fn set_retention_period_root(&mut self, batch: &mut WriteBatch, retention_period_root: Hash) -> StoreResult<()> {
90+
self.retention_period_root_access.write(BatchDbWriter::new(batch), &retention_period_root)
7891
}
7992
}
8093

@@ -95,8 +108,12 @@ impl PruningStoreReader for DbPruningStore {
95108
self.access.read()
96109
}
97110

98-
fn history_root(&self) -> StoreResult<Hash> {
99-
self.history_root_access.read()
111+
fn retention_checkpoint(&self) -> StoreResult<Hash> {
112+
self.retention_checkpoint_access.read()
113+
}
114+
115+
fn retention_period_root(&self) -> StoreResult<Hash> {
116+
self.retention_period_root_access.read()
100117
}
101118
}
102119

0 commit comments

Comments
 (0)