Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement new mechanism for updating UTXO Diffs #1671

Merged
merged 33 commits into from
Apr 20, 2021

Conversation

svarogg
Copy link
Collaborator

@svarogg svarogg commented Apr 11, 2021

This PR implements a mechanism described in the following document: https://github.com/kaspanet/docs/blob/main/Specs/Updates%20to%20UTXO%20Diffs.md

Among other things, this enables a re-org of finalityWindow blocks, without a crashing node or a node stuck forever.
Nevertheless, it still takes around 2 hours to re-org a whole finalityWindow.

This fixes #1516

@codecov
Copy link

codecov bot commented Apr 11, 2021

Codecov Report

Merging #1671 (d4e4516) into v0.10.0-dev (28bfc0f) will increase coverage by 0.17%.
The diff coverage is 66.29%.

Impacted file tree graph

@@               Coverage Diff               @@
##           v0.10.0-dev    #1671      +/-   ##
===============================================
+ Coverage        59.35%   59.53%   +0.17%     
===============================================
  Files              550      551       +1     
  Lines            21838    21930      +92     
===============================================
+ Hits             12962    13056      +94     
+ Misses            6817     6793      -24     
- Partials          2059     2081      +22     
Impacted Files Coverage Δ
...us/datastructures/utxodiffstore/utxo_diff_store.go 64.00% <ø> (ø)
domain/consensus/test_consensus_render_to_dot.go 0.00% <0.00%> (ø)
domain/consensus/utils/utxo/immutable_utxo_diff.go 50.00% <25.00%> (+3.12%) ⬆️
...sses/consensusstatemanager/add_block_to_virtual.go 76.74% <50.00%> (+0.55%) ⬆️
...cesses/consensusstatemanager/reverse_utxo_diffs.go 65.85% <65.85%> (ø)
...processes/blockprocessor/validateandinsertblock.go 70.58% <66.66%> (-0.33%) ⬇️
...sses/consensusstatemanager/resolve_block_status.go 72.88% <67.90%> (+0.21%) ⬆️
...esses/consensusstatemanager/calculate_past_utxo.go 67.91% <86.66%> (-2.26%) ⬇️
...sensusstatemanager/test_consensus_state_manager.go 100.00% <100.00%> (ø)
domain/consensus/utils/utxo/diff_algebra.go 100.00% <100.00%> (+13.25%) ⬆️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 28bfc0f...d4e4516. Read the comment docs.

@svarogg svarogg linked an issue Apr 11, 2021 that may be closed by this pull request
@@ -66,7 +78,7 @@ func (csm *consensusStateManager) CalculatePastUTXOAndAcceptanceData(stagingArea
}

func (csm *consensusStateManager) restorePastUTXO(
stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (externalapi.MutableUTXODiff, error) {
stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (externalapi.UTXODiff, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you convert it to immutable? Doesn't it add extra clone?

Copy link
Collaborator Author

@svarogg svarogg Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it is later being passed to a place that expects immutable.
Also, because you shouldn't mutate it outside restorePastUTXO.

ToImmutable doesn't add a clone.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but you add an extra clone in applyMergeSetBlocks. I suspect that it was there on purpose because of performance reasons.

domain/consensus/utils/utxo/immutable_utxo_diff.go Outdated Show resolved Hide resolved
domain/consensus/utils/utxo/immutable_utxo_diff.go Outdated Show resolved Hide resolved
@@ -19,6 +19,7 @@ import (
func testReorg(cfg *configFlags) {
params := dagconfig.DevnetParams
params.SkipProofOfWork = true
params.DisableDifficultyAdjustment = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? If it's a bug please open an issue

Copy link
Collaborator Author

@svarogg svarogg Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SkipProofOfWork without difficulty adjustment creates a ton of blocks with the same timestamp, which kills some assumption in the difficulty adjustment algorithm.
It can't really happen in a real DAG.

// During resolveSingleBlockStatus, all unverifiedBlocks (excluding the tip) were assigned their selectedParent
// as their UTXODiffChild.
// Now that the whole chain has been resolved - we can reverse the UTXODiffs, to create shorter UTXODiffChild paths.
err = csm.reverseUTXODiffs(stagingArea, unverifiedBlocks, tipUTXOSet, oneBlockBeforeCurrentUTXOSet, useSeparateStagingAreaPerBlock)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we crash in the middle/after reverseUTXODiffs, but before we committed the main stagingArea, we are going to be left with UTXODiffs to nothing.

@@ -19,6 +19,7 @@ import (
func testReorg(cfg *configFlags) {
params := dagconfig.DevnetParams
params.SkipProofOfWork = true
params.DisableDifficultyAdjustment = true
Copy link
Collaborator Author

@svarogg svarogg Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SkipProofOfWork without difficulty adjustment creates a ton of blocks with the same timestamp, which kills some assumption in the difficulty adjustment algorithm.
It can't really happen in a real DAG.


log.Debugf("Reversing utxoDiffs")

// Set previousUTXODiff and previousBlock to oneBlockBeforeTip before we start touching them,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oneBlockBeforeTip doesn't exist anymore

onEnd := logger.LogAndMeasureExecutionTime(log, "reverseUTXODiffs")
defer onEnd()

readStagingArea := model.NewStagingArea()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename it to emptyStagingArea?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer "readStagingArea" because it's only used for reads (and the writes happen in a separate staging area).

return err
}

// oneBlockBeforeTip is special in the sense that we don't have it's diff available in reverse, however, we
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oneBlockBeforeTip doesn't exist anymore

@someone235 someone235 merged commit dfd8b34 into v0.10.0-dev Apr 20, 2021
@someone235 someone235 deleted the utxo-diff-updates branch April 20, 2021 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Big reorgs take a lot of memory
2 participants