mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
Remove the sorting requirement from BlueWindow (#1266)
* Remove the requirement for sorting in BlueWindow * Sort the BlueWindow in window_test
This commit is contained in:
parent
90d4dbcba1
commit
43c00f5e7f
@ -1,13 +1,11 @@
|
||||
package dagtraversalmanager
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// blueBlockWindow returns a blockWindow of the given size that contains the
|
||||
// blues in the past of startindNode, sorted by GHOSTDAG order.
|
||||
// blues in the past of startindNode, the sorting is unspecified.
|
||||
// If the number of blues in the past of startingNode is less then windowSize,
|
||||
// the window will be padded by genesis blocks to achieve a size of windowSize.
|
||||
func (dtm *dagTraversalManager) BlueWindow(startingBlock *externalapi.DomainHash, windowSize int) ([]*externalapi.DomainHash, error) {
|
||||
@ -63,11 +61,6 @@ func (dtm *dagTraversalManager) BlueWindow(startingBlock *externalapi.DomainHash
|
||||
}
|
||||
}
|
||||
|
||||
// a heap is not a sorted list, and the interface promises to be sorted so we now need to sort this
|
||||
sort.Slice(windowHeap.impl.slice, func(i, j int) bool {
|
||||
return windowHeap.impl.slice[j].less(windowHeap.impl.slice[i], dtm.ghostdagManager)
|
||||
})
|
||||
|
||||
window := make([]*externalapi.DomainHash, 0, windowSize)
|
||||
for _, b := range windowHeap.impl.slice {
|
||||
window = append(window, b.hash)
|
||||
|
@ -1,7 +1,9 @@
|
||||
package dagtraversalmanager_test
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/testapi"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus"
|
||||
@ -343,6 +345,7 @@ func TestBlueBlockWindow(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("BlueWindow: %s", err)
|
||||
}
|
||||
sortWindow(t, tc, window)
|
||||
if err := checkWindowIDs(window, blockData.expectedWindowWithGenesisPadding, idByBlockMap); err != nil {
|
||||
t.Errorf("Unexpected values for window for block %s: %s", blockData.id, err)
|
||||
}
|
||||
@ -350,6 +353,20 @@ func TestBlueBlockWindow(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func sortWindow(t *testing.T, tc testapi.TestConsensus, window []*externalapi.DomainHash) {
|
||||
sort.Slice(window, func(i, j int) bool {
|
||||
ghostdagDataI, err := tc.GHOSTDAGDataStore().Get(tc.DatabaseContext(), window[i])
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting ghostdag data for %s", err)
|
||||
}
|
||||
ghostdagDataJ, err := tc.GHOSTDAGDataStore().Get(tc.DatabaseContext(), window[j])
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting ghostdag data for %s", err)
|
||||
}
|
||||
return !tc.GHOSTDAGManager().Less(window[i], ghostdagDataI, window[j], ghostdagDataJ)
|
||||
})
|
||||
}
|
||||
|
||||
func checkWindowIDs(window []*externalapi.DomainHash, expectedIDs []string, idByBlockMap map[externalapi.DomainHash]string) error {
|
||||
ids := make([]string, len(window))
|
||||
for i, node := range window {
|
||||
|
@ -29,7 +29,7 @@ func (dm *difficultyManager) getDifficultyBlock(blockHash *externalapi.DomainHas
|
||||
}
|
||||
|
||||
// blueBlockWindow returns a blockWindow of the given size that contains the
|
||||
// blues in the past of startindNode, sorted by GHOSTDAG order.
|
||||
// blues in the past of startindNode, the sorting is unspecified.
|
||||
// If the number of blues in the past of startingNode is less then windowSize,
|
||||
// the window will be padded by genesis blocks to achieve a size of windowSize.
|
||||
func (dm *difficultyManager) blueBlockWindow(startingNode *externalapi.DomainHash, windowSize int) (blockWindow, error) {
|
||||
@ -49,20 +49,29 @@ func (dm *difficultyManager) blueBlockWindow(startingNode *externalapi.DomainHas
|
||||
return window, nil
|
||||
}
|
||||
|
||||
func (window blockWindow) minMaxTimestamps() (min, max int64) {
|
||||
func (window blockWindow) minMaxTimestamps() (min, max int64, minIndex, maxIndex int) {
|
||||
min = math.MaxInt64
|
||||
minIndex = math.MaxInt64
|
||||
max = 0
|
||||
for _, block := range window {
|
||||
maxIndex = 0
|
||||
for i, block := range window {
|
||||
if block.timeInMilliseconds < min {
|
||||
min = block.timeInMilliseconds
|
||||
minIndex = i
|
||||
}
|
||||
if block.timeInMilliseconds > max {
|
||||
max = block.timeInMilliseconds
|
||||
maxIndex = i
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (window *blockWindow) remove(n int) {
|
||||
(*window)[n] = (*window)[len(*window)-1]
|
||||
*window = (*window)[:len(*window)-1]
|
||||
}
|
||||
|
||||
func (window blockWindow) averageTarget(averageTarget *big.Int) {
|
||||
averageTarget.SetInt64(0)
|
||||
|
||||
|
@ -100,14 +100,14 @@ func (dm *difficultyManager) RequiredDifficulty(blockHash *externalapi.DomainHas
|
||||
}
|
||||
|
||||
// Fetch window of dag.difficultyAdjustmentWindowSize + 1 so we can have dag.difficultyAdjustmentWindowSize block intervals
|
||||
timestampsWindow, err := dm.blueBlockWindow(bluestParent, dm.difficultyAdjustmentWindowSize+1)
|
||||
targetsWindow, err := dm.blueBlockWindow(bluestParent, dm.difficultyAdjustmentWindowSize+1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
windowMinTimestamp, windowMaxTimeStamp := timestampsWindow.minMaxTimestamps()
|
||||
windowMinTimestamp, windowMaxTimeStamp, windowsMinIndex, _ := targetsWindow.minMaxTimestamps()
|
||||
|
||||
// Remove the last block from the window so to calculate the average target of dag.difficultyAdjustmentWindowSize blocks
|
||||
targetsWindow := timestampsWindow[:dm.difficultyAdjustmentWindowSize]
|
||||
targetsWindow.remove(windowsMinIndex)
|
||||
|
||||
// Calculate new target difficulty as:
|
||||
// averageWindowTarget * (windowMinTimestamp / (targetTimePerBlock * windowSize))
|
||||
|
Loading…
x
Reference in New Issue
Block a user