feat(consensus): implement kip-15 ( DONT MERGE before refactoring a description .... ) #1
feat(consensus): implement kip-15 ( DONT MERGE before refactoring a description .... ) #1
Conversation
| let hash_merkle_root = calc_hash_merkle_root(txs.iter(), storage_mass_activated); | ||
|
|
||
| let accepted_id_merkle_root = kaspa_merkle::calc_merkle_root(virtual_state.accepted_tx_ids.iter().copied()); | ||
| let accepted_id_merkle_root = if self.accepted_id_merkle_root.is_active(virtual_state.daa_score) { |
| // NOTE: when subnetworks will be enabled, the sort should consider them in order to allow grouping under a merkle subtree | ||
| ctx.accepted_tx_ids.sort(); | ||
| // Preserve canonical order of accepted transactions after hard-fork | ||
| if !self.accepted_id_merkle_root.is_active(pov_daa_score) { |
There was a problem hiding this comment.
Hera POV_DAA_SCORE is equal to header.daa_score of the caller
|
|
||
| // Verify header accepted_id_merkle_root | ||
| let expected_accepted_id_merkle_root = kaspa_merkle::calc_merkle_root(ctx.accepted_tx_ids.iter().copied()); | ||
| let expected_accepted_id_merkle_root = if self.accepted_id_merkle_root.is_active(header.daa_score) { |
| // Verify header accepted_id_merkle_root | ||
| let expected_accepted_id_merkle_root = kaspa_merkle::calc_merkle_root(ctx.accepted_tx_ids.iter().copied()); | ||
| let expected_accepted_id_merkle_root = if self.accepted_id_merkle_root.is_active(header.daa_score) { | ||
| kaspa_merkle::merkle_hash( |
There was a problem hiding this comment.
@svarogg - No sure if it better to have new function that computes it....
There was a problem hiding this comment.
Here is my 2 cents. 😃
I am not sure If applicable, should we add a task to write boundary tests around the splits:
-
Boundary block validation to verify that the last pre-activation block enforces sorting, while the first post-activation block uses chained merkle roots
-
Test chain reorganizations across the activation boundary to prevent invalid blocks
consensus/core/src/config/params.rs
Outdated
| pub runtime_sig_op_counting: ForkActivation, | ||
|
|
||
| /// Canonical transaction ordering | ||
| pub accepted_id_merkle_root: ForkActivation, |
There was a problem hiding this comment.
I would add documentaion referene:
/// KIP-15 activation: When enabled, uses chained merkle roots with canonical tx ordering
pub accepted_id_merkle_root: ForkActivation,There was a problem hiding this comment.
@pycckuu - I am not sure about the name in general - maybe ForkChoice should be kip15_activation or something like this.
| let accepted_id_merkle_root = kaspa_merkle::calc_merkle_root(virtual_state.accepted_tx_ids.iter().copied()); | ||
| let accepted_id_merkle_root = if self.accepted_id_merkle_root.is_active(virtual_state.daa_score) { | ||
| kaspa_merkle::merkle_hash( | ||
| self.headers_store.get_header(virtual_state.ghostdag_data.selected_parent).unwrap().accepted_id_merkle_root, |
There was a problem hiding this comment.
I noticed a potential issue in the code where we're using unwrap() on the parent header retrieval. This could cause panics if the header is missing. I suggest replacing it with proper error handling:
let parent_header = self.headers_store.get_header(...)
.map_err(|_| RuleError::MissingParentHeader(selected_parent))?;This change adds explicit error handling for header validation and prevents node crashes.
There was a problem hiding this comment.
Thank you. Good point.... I will check if this situation is possible in general. Looks like from POV of virtual selected-parent should exist. Always. But I will check with core-team, if we should handle this error explicitly ( maybe it is implicitly assumed in this context ). @svarogg ? what do think ?
There was a problem hiding this comment.
@pycckuu - I asked kaspa core-team, and indeed in this context it is safe to call unwrap without error handling. S.P header is there ( specifically in this context )
| ctx.accepted_tx_ids.sort(); | ||
| // Preserve canonical order of accepted transactions after hard-fork | ||
| if !self.accepted_id_merkle_root.is_active(pov_daa_score) { | ||
| ctx.accepted_tx_ids.sort(); |
There was a problem hiding this comment.
May we sort_unstable() instead?
| ctx.accepted_tx_ids.sort(); | |
| ctx.accepted_tx_ids.sort_unstable(); |
It's faster than regular sort, though it won't preserve order of equal elements. It is not important as we shouldn't have duplicates.
There was a problem hiding this comment.
It was originally sorted this way, so I should preserve past behaviour, otherwise network will split ....
…ion tests to calc storage mass correctly
1d90b63 to
58290f7
Compare
* kip13 * inline tracking per mass unit * various small fixes * docs
…d not pov daa score
* implement storage mass plurality * move plurality calculation to mass module and add a useful trait for accessing it * utxo cell * consume outputs iterator only once, fix theoretic overflow * add sanity check for plurality limits, align comments * optimize input iterator consumption * extended comment rewrite * fix doc build * inline the relaxed formula conditions * test_storage_mass_pluralities
kaspanet#642) * change expected pruning point check from header validity to chain qualification * adjust `pruning points valid chain` verification to the new rule change
1. Accepted-ID-MR = Hash ( SP.Accepted-ID-MR, MR of Accepted-TXs )
58290f7 to
7909a97
Compare
Accepted-ID-MR = Hash ( SP.Accepted-ID-MR, MR of Accepted-TXs ) as described in https://github.com/svarogg/kips/blob/kip-0015.md/kip-0015.md
Will be happy for a review. 2 things to pay attention to:
I am not 100% about DAA for HF activation. I mean I am not 100% sure I took the right value in both places. Please double check me.
The Hash computation, maybe it worth moving the computation code to some place under new function name ?