mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-778] Optimize RestoreUTXO (#652)
* [NOD-778] Add WithDiffInPlace * [NOD-778] Fix bug in WithDiffInPlace * [NOD-778] Add comment to WithDiffInPlace * [NOD-778] Add double dag.restoreUTXO to benchmark, to remove time for hard-disk loading * [NOD-778] Also test WithDiffInPlace in TestUTXODiffRules * [NOD-778] Add tests for all cases possible in TestUTXODiffRules * [NOD-778] Fix test-case 'first in toAdd in this, second in toRemove in this and toAdd in other' * [NOD-778] Fixed in WithDiffInPlace * [NOD-778] Update error messages when diffFrom(withDiffResult) fails in TestUTXODiffRules * [NOD-778] diffFrom: disallow utxos both in d.toAdd, other.toAdd, and only one of d.toRemove and other.toRemove * [NOD-778] Fix expected value in 'first in toRemove in this, second in toRemove in other' * [NOD-778] diffFrom: Disallow situations where utxo both in d.toRemove and other.toRemove with different blue scores and no corresponding utxo in d.toAdd * [NOD-778] WithDiff: Fix faulty logic that allows updates to blue scores * [NOD-778] Fix WithDiffInPlace to pass all tests * [NOD-778] Deleted temporary prints * [NOD-778] Sorted TestUTXODiffRules tests according to spreadsheet * [NOD-778] Delete deeputxo_test.go * [NOD-778] Updated comments * [NOD-778] Re-order * [NOD-778] Re-order test-cases to be according to spreadsheet * [NOD-778] Simplified case when both d.toRemove and other.toRemove have the same outpoint in diffFrom * [NOD-778] Change a few error messages that say 'transaction' instead of 'outpoint' * [NOD-778] Rename: utxoToAdd/Remove -> entryToAdd/Remove * [NOD-788] Remove redundant else * [NOD-778] Rename: existingUTXO -> existingEntry + remove redundant else * [NOD-778] Correct test name
This commit is contained in:
parent
4dfc8cf5b0
commit
b8a00f7519
@ -1189,6 +1189,8 @@ func (node *blockNode) acceptSelectedParentTransactions(selectedParent *util.Blo
|
||||
func (dag *BlockDAG) restoreUTXO(node *blockNode) (UTXOSet, error) {
|
||||
stack := []*blockNode{}
|
||||
|
||||
// Iterate over the chain of diff-childs from node till virtual and add them
|
||||
// all into a stack
|
||||
for current := node; current != nil; {
|
||||
stack = append(stack, current)
|
||||
var err error
|
||||
@ -1198,20 +1200,28 @@ func (dag *BlockDAG) restoreUTXO(node *blockNode) (UTXOSet, error) {
|
||||
}
|
||||
}
|
||||
|
||||
utxo := UTXOSet(dag.virtual.utxoSet)
|
||||
// Start with the top item in the stack, going over it top-to-bottom,
|
||||
// applying the UTXO-diff one-by-one.
|
||||
topNode, stack := stack[len(stack)-1], stack[:len(stack)-1] // pop the top item in the stack
|
||||
topNodeDiff, err := dag.utxoDiffStore.diffByNode(topNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
accumulatedDiff := topNodeDiff.clone()
|
||||
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
diff, err := dag.utxoDiffStore.diffByNode(stack[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
utxo, err = utxo.WithDiff(diff)
|
||||
// Use WithDiffInPlace, otherwise copying the diffs again and again create a polynomial overhead
|
||||
err = accumulatedDiff.WithDiffInPlace(diff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return utxo, nil
|
||||
return NewDiffUTXOSet(dag.virtual.utxoSet, accumulatedDiff), nil
|
||||
}
|
||||
|
||||
// updateTipsUTXO builds and applies new diff UTXOs for all the DAG's tips
|
||||
|
@ -2,11 +2,12 @@ package blockdag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/ecc"
|
||||
"github.com/kaspanet/kaspad/wire"
|
||||
)
|
||||
@ -224,6 +225,10 @@ func (d *UTXODiff) diffFrom(other *UTXODiff) (*UTXODiff, error) {
|
||||
for outpoint, utxoEntry := range d.toAdd {
|
||||
if !other.toAdd.containsWithBlueScore(outpoint, utxoEntry.blockBlueScore) {
|
||||
result.toRemove.add(outpoint, utxoEntry)
|
||||
} else if (d.toRemove.contains(outpoint) && !other.toRemove.contains(outpoint)) ||
|
||||
(!d.toRemove.contains(outpoint) && other.toRemove.contains(outpoint)) {
|
||||
return nil, errors.New(
|
||||
"diffFrom: outpoint both in d.toAdd, other.toAdd, and only one of d.toRemove and other.toRemove")
|
||||
}
|
||||
if diffEntry, ok := other.toRemove.get(outpoint); ok {
|
||||
// An exception is made for entries with unequal blue scores
|
||||
@ -243,6 +248,18 @@ func (d *UTXODiff) diffFrom(other *UTXODiff) (*UTXODiff, error) {
|
||||
// If they are not in other.toRemove - should be added in result.toAdd
|
||||
// If they are in other.toAdd - base utxoSet is not the same
|
||||
for outpoint, utxoEntry := range d.toRemove {
|
||||
diffEntry, ok := other.toRemove.get(outpoint)
|
||||
if ok {
|
||||
// if have the same entry in d.toRemove - simply don't copy.
|
||||
// unless existing entry is with different blue score, in this case - this is an error
|
||||
if utxoEntry.blockBlueScore != diffEntry.blockBlueScore {
|
||||
return nil, errors.New("diffFrom: outpoint both in d.toRemove and other.toRemove with different " +
|
||||
"blue scores, with no corresponding entry in d.toAdd")
|
||||
}
|
||||
} else { // if no existing entry - add to result.toAdd
|
||||
result.toAdd.add(outpoint, utxoEntry)
|
||||
}
|
||||
|
||||
if !other.toRemove.containsWithBlueScore(outpoint, utxoEntry.blockBlueScore) {
|
||||
result.toAdd.add(outpoint, utxoEntry)
|
||||
}
|
||||
@ -256,7 +273,7 @@ func (d *UTXODiff) diffFrom(other *UTXODiff) (*UTXODiff, error) {
|
||||
other.toRemove.containsWithBlueScore(outpoint, utxoEntry.blockBlueScore)) {
|
||||
continue
|
||||
}
|
||||
return nil, errors.New("diffFrom: transaction both in d.toRemove and in other.toAdd")
|
||||
return nil, errors.New("diffFrom: outpoint both in d.toRemove and in other.toAdd")
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,6 +301,56 @@ func (d *UTXODiff) diffFrom(other *UTXODiff) (*UTXODiff, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// WithDiffInPlace applies provided diff to this diff in-place, that would be the result if
|
||||
// first d, and than diff were applied to the same base
|
||||
func (d *UTXODiff) WithDiffInPlace(diff *UTXODiff) error {
|
||||
for outpoint, entryToRemove := range diff.toRemove {
|
||||
if d.toAdd.containsWithBlueScore(outpoint, entryToRemove.blockBlueScore) {
|
||||
// If already exists in toAdd with the same blueScore - remove from toAdd
|
||||
d.toAdd.remove(outpoint)
|
||||
continue
|
||||
}
|
||||
if d.toRemove.contains(outpoint) {
|
||||
// If already exists - this is an error
|
||||
return ruleError(ErrWithDiff, fmt.Sprintf(
|
||||
"WithDiffInPlace: outpoint %s both in d.toRemove and in diff.toRemove", outpoint))
|
||||
}
|
||||
|
||||
// If not exists neither in toAdd nor in toRemove - add to toRemove
|
||||
d.toRemove.add(outpoint, entryToRemove)
|
||||
}
|
||||
|
||||
for outpoint, entryToAdd := range diff.toAdd {
|
||||
if d.toRemove.containsWithBlueScore(outpoint, entryToAdd.blockBlueScore) {
|
||||
// If already exists in toRemove with the same blueScore - remove from toRemove
|
||||
if d.toAdd.contains(outpoint) && !diff.toRemove.contains(outpoint) {
|
||||
return ruleError(ErrWithDiff, fmt.Sprintf(
|
||||
"WithDiffInPlace: outpoint %s both in d.toAdd and in diff.toAdd with no "+
|
||||
"corresponding entry in diff.toRemove", outpoint))
|
||||
}
|
||||
d.toRemove.remove(outpoint)
|
||||
continue
|
||||
}
|
||||
if existingEntry, ok := d.toAdd.get(outpoint); ok &&
|
||||
(existingEntry.blockBlueScore == entryToAdd.blockBlueScore ||
|
||||
!diff.toRemove.containsWithBlueScore(outpoint, existingEntry.blockBlueScore)) {
|
||||
// If already exists - this is an error
|
||||
return ruleError(ErrWithDiff, fmt.Sprintf(
|
||||
"WithDiffInPlace: outpoint %s both in d.toAdd and in diff.toAdd", outpoint))
|
||||
}
|
||||
|
||||
// If not exists neither in toAdd nor in toRemove, or exists in toRemove with different blueScore - add to toAdd
|
||||
d.toAdd.add(outpoint, entryToAdd)
|
||||
}
|
||||
|
||||
// Apply diff.diffMultiset to d.diffMultiset
|
||||
if d.useMultiset {
|
||||
d.diffMultiset = d.diffMultiset.Union(diff.diffMultiset)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithDiff applies provided diff to this diff, creating a new utxoDiff, that would be the result if
|
||||
// first d, and than diff were applied to the same base
|
||||
//
|
||||
@ -331,8 +398,7 @@ func (d *UTXODiff) WithDiff(diff *UTXODiff) (*UTXODiff, error) {
|
||||
// or diff.toRemove.
|
||||
// These are just "updates" to accepted blue score
|
||||
if diffEntry.blockBlueScore != utxoEntry.blockBlueScore &&
|
||||
(d.toRemove.containsWithBlueScore(outpoint, diffEntry.blockBlueScore) ||
|
||||
diff.toRemove.containsWithBlueScore(outpoint, utxoEntry.blockBlueScore)) {
|
||||
diff.toRemove.containsWithBlueScore(outpoint, utxoEntry.blockBlueScore) {
|
||||
continue
|
||||
}
|
||||
return nil, ruleError(ErrWithDiff, fmt.Sprintf("WithDiff: outpoint %s both in d.toAdd and in other.toAdd", outpoint))
|
||||
@ -353,11 +419,10 @@ func (d *UTXODiff) WithDiff(diff *UTXODiff) (*UTXODiff, error) {
|
||||
// or diff.toAdd.
|
||||
// These are just "updates" to accepted blue score
|
||||
if diffEntry.blockBlueScore != utxoEntry.blockBlueScore &&
|
||||
(d.toAdd.containsWithBlueScore(outpoint, diffEntry.blockBlueScore) ||
|
||||
diff.toAdd.containsWithBlueScore(outpoint, utxoEntry.blockBlueScore)) {
|
||||
d.toAdd.containsWithBlueScore(outpoint, diffEntry.blockBlueScore) {
|
||||
continue
|
||||
}
|
||||
return nil, ruleError(ErrWithDiff, "WithDiff: transaction both in d.toRemove and in other.toRemove")
|
||||
return nil, ruleError(ErrWithDiff, "WithDiff: outpoint both in d.toRemove and in other.toRemove")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
package blockdag
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/util/subnetworkid"
|
||||
"math"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/util/subnetworkid"
|
||||
|
||||
"github.com/kaspanet/kaspad/ecc"
|
||||
"github.com/kaspanet/kaspad/util/daghash"
|
||||
"github.com/kaspanet/kaspad/wire"
|
||||
@ -136,8 +137,11 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
// For each of the following test cases, we will:
|
||||
// this.diffFrom(other) and compare it to expectedDiffFromResult
|
||||
// this.WithDiff(other) and compare it to expectedWithDiffResult
|
||||
// this.WithDiffInPlace(other) and compare it to expectedWithDiffResult
|
||||
//
|
||||
// Note: an expected nil result means that we expect the respective operation to fail
|
||||
// See the following spreadsheet for a summary of all test-cases:
|
||||
// https://docs.google.com/spreadsheets/d/1E8G3mp5y1-yifouwLLXRLueSRfXdDRwRKFieYE07buY/edit?usp=sharing
|
||||
tests := []struct {
|
||||
name string
|
||||
this *UTXODiff
|
||||
@ -146,7 +150,7 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
expectedWithDiffResult *UTXODiff
|
||||
}{
|
||||
{
|
||||
name: "one toAdd in this, one toAdd in other",
|
||||
name: "first toAdd in this, first toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
@ -162,7 +166,23 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "one toAdd in this, one toRemove in other",
|
||||
name: "first in toAdd in this, second in toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toAdd in this, second in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
@ -178,7 +198,36 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one toAdd in this, empty other",
|
||||
name: "first in toAdd in this and other, second in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toAdd in this and toRemove in other, second in toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "first in toAdd in this, empty other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
@ -197,7 +246,7 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one toRemove in this, one toAdd in other",
|
||||
name: "first in toRemove in this and in toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
@ -213,7 +262,23 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one toRemove in this, one toRemove in other",
|
||||
name: "first in toRemove in this, second in toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "first in toRemove in this and other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
@ -229,7 +294,49 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "one toRemove in this, empty other",
|
||||
name: "first in toRemove in this, second in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toRemove in this and toAdd in other, second in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toRemove in this and other, second in toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toRemove in this, empty other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
@ -248,7 +355,116 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty this, one toAdd in other",
|
||||
name: "first in toAdd in this and other, second in toRemove in this",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toAdd in this, second in toRemove in this and toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toAdd in this and toRemove in other, second in toRemove in this",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "first in toAdd in this, second in toRemove in this and in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toAdd and second in toRemove in both this and other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "first in toAdd in this and toRemove in other, second in toRemove in this and toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "first in toAdd and second in toRemove in this, empty other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty this, first in toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
@ -267,7 +483,7 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty this, one toRemove in other",
|
||||
name: "empty this, first in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
@ -285,6 +501,25 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty this, first in toAdd and second in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty this, empty other",
|
||||
this: &UTXODiff{
|
||||
@ -304,108 +539,6 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "equal outpoints different blue scores: first in toAdd in this, second in toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "equal outpoints different blue scores: first in toRemove in this, second in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "equal outpoints different blue scores: first in toAdd and second in toRemove in this, empty other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "equal outpoints different blue scores: empty this, first in toAdd and second in toRemove in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "equal outpoints different blue scores: first in toAdd and second in toRemove in both this and other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
expectedDiffFromResult: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
expectedWithDiffResult: nil,
|
||||
},
|
||||
{
|
||||
name: "equal outpoints different blue scores: first in toAdd in this and toRemove in other, second in toRemove in this and toAdd in other",
|
||||
this: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry1},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry2},
|
||||
},
|
||||
other: &UTXODiff{
|
||||
toAdd: utxoCollection{outpoint0: utxoEntry2},
|
||||
toRemove: utxoCollection{outpoint0: utxoEntry1},
|
||||
},
|
||||
expectedDiffFromResult: nil,
|
||||
expectedWithDiffResult: &UTXODiff{
|
||||
toAdd: utxoCollection{},
|
||||
toRemove: utxoCollection{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@ -460,6 +593,24 @@ func TestUTXODiffRules(t *testing.T) {
|
||||
"Expected: \"%v\", got: \"%v\".", test.name, expectedWithDiffResult, withDiffResult)
|
||||
}
|
||||
|
||||
// Repeat WithDiff check this time using WithDiffInPlace
|
||||
thisClone := this.clone()
|
||||
err = thisClone.WithDiffInPlace(other)
|
||||
|
||||
// Test whether WithDiffInPlace returned an error
|
||||
isWithDiffInPlaceOk := err == nil
|
||||
expectedIsWithDiffInPlaceOk := expectedWithDiffResult != nil
|
||||
if isWithDiffInPlaceOk != expectedIsWithDiffInPlaceOk {
|
||||
t.Errorf("unexpected WithDiffInPlace error in test \"%s\". "+
|
||||
"Expected: \"%t\", got: \"%t\".", test.name, expectedIsWithDiffInPlaceOk, isWithDiffInPlaceOk)
|
||||
}
|
||||
|
||||
// If not error, test the WithDiffInPlace result
|
||||
if isWithDiffInPlaceOk && !thisClone.equal(expectedWithDiffResult) {
|
||||
t.Errorf("unexpected WithDiffInPlace result in test \"%s\". "+
|
||||
"Expected: \"%v\", got: \"%v\".", test.name, expectedWithDiffResult, thisClone)
|
||||
}
|
||||
|
||||
// Make sure that diffFrom after WithDiff results in the original other
|
||||
if isWithDiffOk {
|
||||
otherResult, err := this.diffFrom(withDiffResult)
|
||||
|
Loading…
x
Reference in New Issue
Block a user