kaspad/blockdag/virtualblock_test.go
stasatdaglabs 37cd482db3 [DEV-75] Update UTXO model to work with Diffs (#53)
* [DEV-75] Removed fetchEntryByHash, which was no longer used.

* [DEV-75] Removed a few functions in manager.go that weren't used by anything.

* [DEV-75] checkConnectBlock will soon not accept a utxoViewpoint, so removed the call to view.Tip() so that it could be deleted.

* [DEV-75] Got rid of tips in UtxoViewpoint.

* [DEV-75] Added the full UTXO set to the virtual block.

* [DEV-75] Implemented UTXO-wrangling when adding a new block.

* [DEV-75] Added isCoinbase to utxoEntry creation.

* [DEV-75] Added blockHeight to utxoEntry creation.

* Implemented fetching the fullUTXOSet from the database.

* [DEV-75] Simplified DAGState because almost all of the state in it was unnecessary. Also got rid of dbDAGState.

* [DEV-75] Made the process around adding a new block, UTXO-wise, much safer.

* [DEV-75] Implemented melding the virtual UTXO diff to the database.

* [DEV-75] Fixed utxoSet loading from the wrong bucket.

* [DEV-75] Began pruning utxoviewpoint.go. Replaced FetchUtxoEntry with a fullUTXOSet-based GetUTXOEntry.

* [DEV-75] Removed fetchUtxos.

* [DEV-75] Moved GetUTXOEntry into the virtual block.

* [DEV-75] Updated IndexManager to not use utxoViewpoints.

* [DEV-75] Fixed some bad login in restoreUTXO involving nodeDiffs.

* [DEV-75] Got rid of the UTXO spend journal, which wasn't used anywhere.

* [DEV-75] Moved some STXO-related validation logic out of connectToDAG and into checkConnectBlock.

* [DEV-75] Renamed UtxoXxx to UTXOXxx. Removed a bunch of methods that were no longer used by anything.

* [DEV-75] Another Utxo -> UTXO rename.

* [DEV-75] Removed IsModified from UTXOView, which was not used anywhere.

* [DEV-75] Renamed nodeDiff to provisionalNode. Added a bunch of comments.

* [DEV-75] Removed the test for genesis in pastUTXO, since it can never happen.

* [DEV-75] Wrote tests for errors in pastUTXO.

* [DEV-75] Wrote tests for errors in restoreUTXO.

* [DEV-75] Improved testErrorThroughPatching.

* [DEV-75] Wrote tests for errors in verifyAndBuildUTXO.

* [DEV-75] Used TipHashes instead of tips().hashes(), fixed comments in a few places, and brought back an error return that I erroneously removed.

* [DEV-75] Removed UTXO set logs.

* [DEV-75] Recreated add/remove/contains functions for utxoCollection.

* [DEV-75] Changed newUTXOEntry to use an object initializer.

* [DEV-75] Changed the UTXO bucket version to 1.

* Added a comment that clarifies that the index is not initialized before initDAGState is called.

* [DEV-75] Renamed GetVirtualBlock to VirtualBlock.

* [DEV-75] Removed superfluous variables.

* [DEV-75] Combined connectBlockToParents with updateParentsDiffs.

* [DEV-75] Removed another superfluous variable.

* [DEV-75] In pastUTXO, first fetch transactions from the database and only then add them.

* [DEV-75] Reworded the comment for commit().

* [DEV-75] Made all the connectUTXO subfunctions not BlockDAG methods.

* [DEV-75] Updated the comment for connectUTXO.

* [DEV-75] Updated the comment explaining why we're creating provisionalNodes.

* [DEV-75] Removed a couple of unnecessary calls to toProvisionalNode.

* [DEV-75] Renamed connectUTXO to applyUTXOChanges.

* [DEV-75] Replaced allProvisionalNodes with provisionalNodeSet, an object that holds provisionalNodes for this particular call to applyUTXOChanges.

* [DEV-75] Changed createProvisionalNode to accept a boolean "withParents" instead of relying on the caller to supply the node's parents or an empty set.

* [DEV-75] Made most applyUTXOChanges subfunctions be methods on provisionalNode.

* [DEV-75] Fixed a couple of bad comments.

* [DEV-75] Added descriptive error messages to callers of applyUTXOChanges.

* [DEV-75] Fixed weird English.

* [DEV-75] Replaced DAGState with a slice of DAG tip hashes.

* [DEV-75] In createProvisionalNode, changed withParents to withRelatives to avoid certain kinds of attacks.

* [DEV-75] Renamed createdProvisionalNode to newProvisionalNode.

* [DEV-75] Added precalculating the amount of transactions inside a new block's blue set.

* [DEV-75] Pruned unnecessary variable.
2018-08-30 16:00:03 +03:00

110 lines
3.4 KiB
Go

// Copyright (c) 2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package blockdag
import (
"testing"
"reflect"
"github.com/daglabs/btcd/dagconfig/daghash"
)
// TestVirtualBlock ensures that VirtualBlock works as expected.
func TestVirtualBlock(t *testing.T) {
// For the purposes of this test, we'll create blockNodes whose hashes are a
// series of numbers from 0 to n.
phantomK := uint32(1)
hashCounter := byte(0)
buildNode := func(parents blockSet) *blockNode {
block := newBlockNode(nil, parents, phantomK)
block.hash = daghash.Hash{hashCounter}
hashCounter++
return block
}
// Create a DAG as follows:
// 0 <- 1 <- 2
// \
// <- 3 <- 5
// \ X
// <- 4 <- 6
node0 := buildNode(setFromSlice())
node1 := buildNode(setFromSlice(node0))
node2 := buildNode(setFromSlice(node1))
node3 := buildNode(setFromSlice(node0))
node4 := buildNode(setFromSlice(node0))
node5 := buildNode(setFromSlice(node3, node4))
node6 := buildNode(setFromSlice(node3, node4))
// Given an empty VirtualBlock, each of the following test cases will:
// Set its tips to tipsToSet
// Add to it all the tips in tipsToAdd, one after the other
// Call .Tips() on it and compare the result to expectedTips
// Call .SelectedTip() on it and compare the result to expectedSelectedTip
tests := []struct {
name string
tipsToSet []*blockNode
tipsToAdd []*blockNode
expectedTips blockSet
expectedSelectedTip *blockNode
}{
{
name: "empty virtual",
tipsToSet: []*blockNode{},
tipsToAdd: []*blockNode{},
expectedTips: newSet(),
expectedSelectedTip: nil,
},
{
name: "virtual with genesis tip",
tipsToSet: []*blockNode{node0},
tipsToAdd: []*blockNode{},
expectedTips: setFromSlice(node0),
expectedSelectedTip: node0,
},
{
name: "virtual with genesis tip, add child of genesis",
tipsToSet: []*blockNode{node0},
tipsToAdd: []*blockNode{node1},
expectedTips: setFromSlice(node1),
expectedSelectedTip: node1,
},
{
name: "empty virtual, add a full DAG",
tipsToSet: []*blockNode{},
tipsToAdd: []*blockNode{node0, node1, node2, node3, node4, node5, node6},
expectedTips: setFromSlice(node2, node5, node6),
expectedSelectedTip: node5,
},
}
for _, test := range tests {
// Create an empty VirtualBlock
virtual := newVirtualBlock(nil, phantomK)
// Set the tips. This will be the initial state
virtual.SetTips(setFromSlice(test.tipsToSet...))
// Add all blockNodes in tipsToAdd in order
for _, tipToAdd := range test.tipsToAdd {
virtual.AddTip(tipToAdd)
}
// Ensure that the virtual block's tips are now equal to expectedTips
resultTips := virtual.tips()
if !reflect.DeepEqual(resultTips, test.expectedTips) {
t.Errorf("unexpected tips in test \"%s\". "+
"Expected: %v, got: %v.", test.name, test.expectedTips, resultTips)
}
// Ensure that the virtual block's selectedTip is now equal to expectedSelectedTip
resultSelectedTip := virtual.SelectedTip()
if !reflect.DeepEqual(resultSelectedTip, test.expectedSelectedTip) {
t.Errorf("unexpected selected tip in test \"%s\". "+
"Expected: %v, got: %v.", test.name, test.expectedSelectedTip, resultSelectedTip)
}
}
}