mirror of
https://github.com/kaspanet/kaspad.git
synced 2026-02-23 20:03:16 +00:00
[#1126] Use WALK function in tests & cosmetic changes.
This commit is contained in:
@@ -13,15 +13,6 @@ type ghostdagHelper struct {
|
||||
dagTopologyManager model.DAGTopologyManager
|
||||
}
|
||||
|
||||
func (gh *ghostdagHelper) ChooseSelectedParent(blockHashes ...*externalapi.DomainHash) (*externalapi.DomainHash, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (gh *ghostdagHelper) Less(blockHashA *externalapi.DomainHash, ghostdagDataA *model.BlockGHOSTDAGData, blockHashB *externalapi.DomainHash, ghostdagDataB *model.BlockGHOSTDAGData) bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// New instantiates a new GHOSTDAGHelper -like a factory
|
||||
func New(
|
||||
databaseContext model.DBReader,
|
||||
dagTopologyManager model.DAGTopologyManager,
|
||||
@@ -37,7 +28,7 @@ func New(
|
||||
}
|
||||
|
||||
/* --------------------------------------------- */
|
||||
//K, GHOSTDAGDataStore
|
||||
|
||||
func (gh *ghostdagHelper) GHOSTDAG(blockCandidate *externalapi.DomainHash) error {
|
||||
var maxNum uint64 = 0
|
||||
var myScore uint64 = 0
|
||||
@@ -46,7 +37,7 @@ func (gh *ghostdagHelper) GHOSTDAG(blockCandidate *externalapi.DomainHash) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var selectedParent *externalapi.DomainHash = blockParents[0]
|
||||
var selectedParent = blockParents[0]
|
||||
for _, parent := range blockParents {
|
||||
blockData, err := gh.dataStore.Get(gh.dbAccess, parent)
|
||||
if err != nil {
|
||||
@@ -63,20 +54,16 @@ func (gh *ghostdagHelper) GHOSTDAG(blockCandidate *externalapi.DomainHash) error
|
||||
}
|
||||
myScore = maxNum
|
||||
|
||||
/* Goal: iterate h's past and divide it to : blue, blues, reds.
|
||||
Notes:
|
||||
1. If block A is in B's reds group (for block B that belong to the blue group) it will never be in blue(or blues).
|
||||
*/
|
||||
|
||||
var blues = make([]*externalapi.DomainHash, 0)
|
||||
var reds = make([]*externalapi.DomainHash, 0)
|
||||
/* Goal: iterate blockCandidate's mergeSet and divide it to : blue, blues, reds. */
|
||||
var mergeSetBlues = make([]*externalapi.DomainHash, 0)
|
||||
var mergeSetReds = make([]*externalapi.DomainHash, 0)
|
||||
var blueSet = make([]*externalapi.DomainHash, 0)
|
||||
|
||||
mergeSetArr, err := gh.findMergeSet(blockParents, selectedParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//STOP HERE
|
||||
|
||||
err = gh.sortByBlueScore(mergeSetArr)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -86,45 +73,39 @@ func (gh *ghostdagHelper) GHOSTDAG(blockCandidate *externalapi.DomainHash) error
|
||||
return err
|
||||
}
|
||||
|
||||
for _, d := range mergeSetArr {
|
||||
if *d == *selectedParent {
|
||||
if !contains(selectedParent, blues) {
|
||||
blues = append(blues, selectedParent)
|
||||
for _, mergeSetBlock := range mergeSetArr {
|
||||
if *mergeSetBlock == *selectedParent {
|
||||
if !contains(selectedParent, mergeSetBlues) {
|
||||
mergeSetBlues = append(mergeSetBlues, selectedParent)
|
||||
blueSet = append(blueSet, selectedParent)
|
||||
}
|
||||
continue
|
||||
}
|
||||
err := gh.divideBlueRed(selectedParent, d, &blues, &reds, &blueSet)
|
||||
err := gh.divideBlueRed(selectedParent, mergeSetBlock, &mergeSetBlues, &mergeSetReds, &blueSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
myScore += uint64(len(blues))
|
||||
/* Finial Data:
|
||||
1. BlueScore => myScore
|
||||
2. blues
|
||||
3. reds
|
||||
4. selectedParent
|
||||
myScore += uint64(len(mergeSetBlues))
|
||||
|
||||
*/
|
||||
e := model.BlockGHOSTDAGData{
|
||||
BlueScore: myScore,
|
||||
SelectedParent: selectedParent,
|
||||
MergeSetBlues: blues,
|
||||
MergeSetReds: reds,
|
||||
MergeSetBlues: mergeSetBlues,
|
||||
MergeSetReds: mergeSetReds,
|
||||
}
|
||||
gh.dataStore.Stage(blockCandidate, &e)
|
||||
return nil
|
||||
}
|
||||
|
||||
/* --------isMoreHash(w, selectedParent)----------------*/
|
||||
func ismoreHash(w *externalapi.DomainHash, selectedParent *externalapi.DomainHash) bool {
|
||||
//Check if w is more then selectedParent
|
||||
for i := len(w) - 1; i >= 0; i-- {
|
||||
func ismoreHash(parent *externalapi.DomainHash, selectedParent *externalapi.DomainHash) bool {
|
||||
//Check if parentHash is more then selectedParentHash
|
||||
for i := len(parent) - 1; i >= 0; i-- {
|
||||
switch {
|
||||
case w[i] < selectedParent[i]:
|
||||
case parent[i] < selectedParent[i]:
|
||||
return false
|
||||
case w[i] > selectedParent[i]:
|
||||
case parent[i] > selectedParent[i]:
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -132,7 +113,7 @@ func ismoreHash(w *externalapi.DomainHash, selectedParent *externalapi.DomainHas
|
||||
}
|
||||
|
||||
/* 1. blue = selectedParent.blue + blues
|
||||
2. h is not connected to at most K blocks (from the blue group)
|
||||
2. not connected to at most K blocks (from the blue group)
|
||||
3. for each block at blue , check if not destroy
|
||||
*/
|
||||
|
||||
@@ -141,16 +122,16 @@ func (gh *ghostdagHelper) divideBlueRed(selectedParent *externalapi.DomainHash,
|
||||
blues *[]*externalapi.DomainHash, reds *[]*externalapi.DomainHash, blueSet *[]*externalapi.DomainHash) error {
|
||||
var k = int(gh.k)
|
||||
counter := 0
|
||||
// check if anticone with desiredBlock.
|
||||
|
||||
var suspectsBlues = make([]*externalapi.DomainHash, 0)
|
||||
var isMergeBlue = true
|
||||
isMergeBlue := true
|
||||
//check that not-connected to at most k.
|
||||
for _, block := range *blueSet {
|
||||
isAnt, err := gh.isAnticone(block, desiredBlock)
|
||||
isAnticone, err := gh.isAnticone(block, desiredBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isAnt {
|
||||
if isAnticone {
|
||||
counter++
|
||||
suspectsBlues = append(suspectsBlues, block)
|
||||
}
|
||||
@@ -192,128 +173,51 @@ func (gh *ghostdagHelper) divideBlueRed(selectedParent *externalapi.DomainHash,
|
||||
return nil
|
||||
}
|
||||
|
||||
// OldisAnticone
|
||||
//var chain = selectedParent
|
||||
//var stop = false
|
||||
//for chain != nil { /*nil -> after genesis*/
|
||||
// // iterate on the selected parent chain, for each node in the chain i check also for his mergeSet.
|
||||
// isValid, err := gh.validateKCluster(chain, desiredBlock, &counter, blueSet)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if !isValid {
|
||||
// stop = true
|
||||
// break
|
||||
// }
|
||||
// /* Check valid for the blues of the chain */
|
||||
// blockData, err := gh.dataStore.Get(gh.dbAccess, chain)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// for _, b := range blockData.MergeSetBlues {
|
||||
// isValid2, err := gh.validateKCluster(b, desiredBlock, &counter, blueSet)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if !isValid2 {
|
||||
// stop = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if stop {
|
||||
// break
|
||||
// }
|
||||
// //chain = gh.dataStore.Get(gh.dbAccess, chain).SelectedParent
|
||||
// blockData2, err := gh.dataStore.Get(gh.dbAccess, chain)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// chain = blockData2.SelectedParent
|
||||
//}
|
||||
//if stop {
|
||||
// if !contains(desiredBlock, *reds) {
|
||||
// *reds = append(*reds, desiredBlock)
|
||||
// }
|
||||
//} else {
|
||||
// var isBlue bool = true
|
||||
//
|
||||
// for _, e := range *blues {
|
||||
// isDestroyed, err := gh.checkIfDestroy(e, blues)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if isDestroyed {
|
||||
// isBlue = false
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// if !isBlue {
|
||||
// if !contains(desiredBlock, *reds) {
|
||||
// *reds = append(*reds, desiredBlock)
|
||||
// }
|
||||
// } else {
|
||||
// if !contains(desiredBlock, *blues) {
|
||||
// *blues = append(*blues, desiredBlock)
|
||||
// }
|
||||
// if !contains(desiredBlock, *blueSet) {
|
||||
// *blueSet = append(*blueSet, desiredBlock)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
/* ---------------isAnticone-------------------------- */
|
||||
func (gh *ghostdagHelper) isAnticone(h1, h2 *externalapi.DomainHash) (bool, error) {
|
||||
//return !isInPast(h1, h2) && !isInPast(h1,h2)
|
||||
//return !gh.dagTopologyManager.IsAncestorOf(h1, h2) && !gh.dagTopologyManager.IsAncestorOf(h2, h1)
|
||||
isAB, err := gh.dagTopologyManager.IsAncestorOf(h1, h2)
|
||||
func (gh *ghostdagHelper) isAnticone(blockA, blockB *externalapi.DomainHash) (bool, error) {
|
||||
isAAncestorOfAB, err := gh.dagTopologyManager.IsAncestorOf(blockA, blockB)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
isBA, err := gh.dagTopologyManager.IsAncestorOf(h2, h1)
|
||||
isBAncestorOfA, err := gh.dagTopologyManager.IsAncestorOf(blockB, blockA)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !isAB && !isBA, nil
|
||||
return !isAAncestorOfAB && !isBAncestorOfA, nil
|
||||
|
||||
}
|
||||
|
||||
/* ----------------validateKCluster------------------- */
|
||||
func (gh *ghostdagHelper) validateKCluster(chain *externalapi.DomainHash, checkedBlock *externalapi.DomainHash, counter *int, blueSet *[]*externalapi.DomainHash) (bool, error) {
|
||||
var k int = int(gh.k)
|
||||
isAnt, err := gh.isAnticone(chain, checkedBlock)
|
||||
var k = int(gh.k)
|
||||
isAnticone, err := gh.isAnticone(chain, checkedBlock)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if isAnt {
|
||||
//if n := gh.isAnticone(chain, checkedBlock); n {
|
||||
if isAnticone {
|
||||
if *counter > k {
|
||||
return false, nil
|
||||
}
|
||||
//if gh.checkIfDestroy(chain, blueSet) {
|
||||
ifDes, err := gh.checkIfDestroy(chain, blueSet)
|
||||
ifDestroy, err := gh.checkIfDestroy(chain, blueSet)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if ifDes {
|
||||
if ifDestroy {
|
||||
return false, nil
|
||||
}
|
||||
*counter++
|
||||
return true, nil
|
||||
}
|
||||
isAnt2, err := gh.dagTopologyManager.IsAncestorOf(checkedBlock, chain)
|
||||
isAncestorOf, err := gh.dagTopologyManager.IsAncestorOf(checkedBlock, chain)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
//if gh.dagTopologyManager.IsAncestorOf(checkedBlock, chain) {
|
||||
if isAnt2 {
|
||||
if isAncestorOf {
|
||||
dataStore, err := gh.BlockData(chain)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if g := dataStore.MergeSetReds; contains(checkedBlock, g) {
|
||||
//if g := gh.dataStore.Get(gh.dbAccess, chain).MergeSetReds; contains(checkedBlock, g) {
|
||||
if mergeSetReds := dataStore.MergeSetReds; contains(checkedBlock, mergeSetReds) {
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
@@ -324,9 +228,9 @@ func (gh *ghostdagHelper) validateKCluster(chain *externalapi.DomainHash, checke
|
||||
}
|
||||
|
||||
/*----------------contains-------------------------- */
|
||||
func contains(s *externalapi.DomainHash, g []*externalapi.DomainHash) bool {
|
||||
for _, r := range g {
|
||||
if *r == *s {
|
||||
func contains(item *externalapi.DomainHash, items []*externalapi.DomainHash) bool {
|
||||
for _, r := range items {
|
||||
if *r == *item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -335,17 +239,16 @@ func contains(s *externalapi.DomainHash, g []*externalapi.DomainHash) bool {
|
||||
|
||||
/* ----------------checkIfDestroy------------------- */
|
||||
/* find number of not-connected in his blue*/
|
||||
func (gh *ghostdagHelper) checkIfDestroy(block_blue *externalapi.DomainHash, blueSet *[]*externalapi.DomainHash) (bool, error) {
|
||||
func (gh *ghostdagHelper) checkIfDestroy(blockBlue *externalapi.DomainHash, blueSet *[]*externalapi.DomainHash) (bool, error) {
|
||||
// Goal: check that the K-cluster of each block in the blueSet is not destroyed when adding the block to the mergeSet.
|
||||
var k int = int(gh.k)
|
||||
var k = int(gh.k)
|
||||
counter := 0
|
||||
for _, blue := range *blueSet {
|
||||
//if gh.isAnticone(s2, chain) {
|
||||
isAnt, err := gh.isAnticone(blue, block_blue)
|
||||
isAnticone, err := gh.isAnticone(blue, blockBlue)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if isAnt {
|
||||
if isAnticone {
|
||||
counter++
|
||||
}
|
||||
if counter > k {
|
||||
@@ -356,38 +259,36 @@ func (gh *ghostdagHelper) checkIfDestroy(block_blue *externalapi.DomainHash, blu
|
||||
}
|
||||
|
||||
/* ----------------findMergeSet------------------- */
|
||||
func (gh *ghostdagHelper) findMergeSet(h []*externalapi.DomainHash, selectedParent *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
func (gh *ghostdagHelper) findMergeSet(parents []*externalapi.DomainHash, selectedParent *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
|
||||
allMergeSet := make([]*externalapi.DomainHash, 0)
|
||||
var nodeQueue = make([]*externalapi.DomainHash, 0)
|
||||
for _, g := range h {
|
||||
if !contains(g, nodeQueue) {
|
||||
nodeQueue = append(nodeQueue, g)
|
||||
blockQueue := make([]*externalapi.DomainHash, 0)
|
||||
for _, parent := range parents {
|
||||
if !contains(parent, blockQueue) {
|
||||
blockQueue = append(blockQueue, parent)
|
||||
}
|
||||
|
||||
}
|
||||
for len(nodeQueue) > 0 { /*return boolean */
|
||||
ha := nodeQueue[0]
|
||||
nodeQueue = nodeQueue[1:]
|
||||
if *selectedParent == *ha {
|
||||
if !contains(ha, allMergeSet) {
|
||||
allMergeSet = append(allMergeSet, ha)
|
||||
for len(blockQueue) > 0 {
|
||||
block := blockQueue[0]
|
||||
blockQueue = blockQueue[1:]
|
||||
if *selectedParent == *block {
|
||||
if !contains(block, allMergeSet) {
|
||||
allMergeSet = append(allMergeSet, block)
|
||||
}
|
||||
continue
|
||||
}
|
||||
//if isInPast(ha, selectedParent){
|
||||
//if gh.dagTopologyManager.IsAncestorOf(ha, selectedParent) {
|
||||
isanc, err := gh.dagTopologyManager.IsAncestorOf(ha, selectedParent)
|
||||
isancestorOf, err := gh.dagTopologyManager.IsAncestorOf(block, selectedParent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isanc {
|
||||
if isancestorOf {
|
||||
continue
|
||||
}
|
||||
if !contains(ha, allMergeSet) {
|
||||
allMergeSet = append(allMergeSet, ha)
|
||||
if !contains(block, allMergeSet) {
|
||||
allMergeSet = append(allMergeSet, block)
|
||||
}
|
||||
err = gh.insertParent(ha, &nodeQueue)
|
||||
err = gh.insertParent(block, &blockQueue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -398,41 +299,38 @@ func (gh *ghostdagHelper) findMergeSet(h []*externalapi.DomainHash, selectedPare
|
||||
|
||||
/* ----------------insertParent------------------- */
|
||||
/* Insert all parents to the queue*/
|
||||
func (gh *ghostdagHelper) insertParent(h *externalapi.DomainHash, q1 *[]*externalapi.DomainHash) error {
|
||||
parents, err := gh.dagTopologyManager.Parents(h)
|
||||
func (gh *ghostdagHelper) insertParent(child *externalapi.DomainHash, queue *[]*externalapi.DomainHash) error {
|
||||
parents, err := gh.dagTopologyManager.Parents(child)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range parents {
|
||||
if contains(v, *q1) {
|
||||
for _, parent := range parents {
|
||||
if contains(parent, *queue) {
|
||||
continue
|
||||
}
|
||||
*q1 = append(*q1, v)
|
||||
*queue = append(*queue, parent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/* ----------------findBlueSet------------------- */
|
||||
func (gh *ghostdagHelper) findBlueSet(blueSet *[]*externalapi.DomainHash, h *externalapi.DomainHash) error {
|
||||
for h != nil {
|
||||
if !contains(h, *blueSet) {
|
||||
*blueSet = append(*blueSet, h)
|
||||
func (gh *ghostdagHelper) findBlueSet(blueSet *[]*externalapi.DomainHash, selectedParent *externalapi.DomainHash) error {
|
||||
for selectedParent != nil {
|
||||
if !contains(selectedParent, *blueSet) {
|
||||
*blueSet = append(*blueSet, selectedParent)
|
||||
}
|
||||
//blueSet = append(gh.dataStore.Get(gh.dbAccess, h).MergeSetBlues, blueSet) //change
|
||||
//for _, v := range gh.dataStore.Get(gh.dbAccess, h).MergeSetBlues {
|
||||
blockData, err := gh.dataStore.Get(gh.dbAccess, h)
|
||||
blockData, err := gh.dataStore.Get(gh.dbAccess, selectedParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mergeSetBlue := blockData.MergeSetBlues
|
||||
for _, v := range mergeSetBlue {
|
||||
if contains(v, *blueSet) {
|
||||
for _, blue := range mergeSetBlue {
|
||||
if contains(blue, *blueSet) {
|
||||
continue
|
||||
}
|
||||
*blueSet = append(*blueSet, v)
|
||||
*blueSet = append(*blueSet, blue)
|
||||
}
|
||||
//h = gh.dataStore.Get(gh.dbAccess, h).SelectedParent
|
||||
h = blockData.SelectedParent
|
||||
selectedParent = blockData.SelectedParent
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -441,7 +339,7 @@ func (gh *ghostdagHelper) findBlueSet(blueSet *[]*externalapi.DomainHash, h *ext
|
||||
func (gh *ghostdagHelper) sortByBlueScore(arr []*externalapi.DomainHash) error {
|
||||
|
||||
var err error = nil
|
||||
sort.SliceStable(arr, func(i, j int) bool {
|
||||
sort.Slice(arr, func(i, j int) bool {
|
||||
|
||||
blockRight, error := gh.dataStore.Get(gh.dbAccess, arr[i])
|
||||
if error != nil {
|
||||
@@ -471,5 +369,11 @@ func (gh *ghostdagHelper) sortByBlueScore(arr []*externalapi.DomainHash) error {
|
||||
|
||||
func (gh *ghostdagHelper) BlockData(blockHash *externalapi.DomainHash) (*model.BlockGHOSTDAGData, error) {
|
||||
return gh.dataStore.Get(gh.dbAccess, blockHash)
|
||||
//last
|
||||
}
|
||||
func (gh *ghostdagHelper) ChooseSelectedParent(blockHashes ...*externalapi.DomainHash) (*externalapi.DomainHash, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (gh *ghostdagHelper) Less(blockHashA *externalapi.DomainHash, ghostdagDataA *model.BlockGHOSTDAGData, blockHashB *externalapi.DomainHash, ghostdagDataB *model.BlockGHOSTDAGData) bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -6,31 +6,10 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/processes/ghostdag2"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
/*----------------contains-------------------------- */
|
||||
func contains(s *externalapi.DomainHash, g []*externalapi.DomainHash) bool {
|
||||
for _, r := range g {
|
||||
if *r == *s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func DeepEqualHashArrays(runtime, expected []*externalapi.DomainHash) bool {
|
||||
if len(runtime) != len(expected) {
|
||||
return false
|
||||
}
|
||||
for _, hash := range runtime {
|
||||
if !contains(hash, expected) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func TestGHOSTDA(t *testing.T) {
|
||||
|
||||
type implManager struct {
|
||||
@@ -443,34 +422,22 @@ func TestGHOSTDA(t *testing.T) {
|
||||
t.Fatalf("Test #%d failed: expected selected parent %v but got %v.", testNum+1, testBlockData.expectedSelectedParent, ghostdagData.SelectedParent)
|
||||
}
|
||||
|
||||
if !DeepEqualHashArrays(testBlockData.expectedMergeSetBlues, ghostdagData.MergeSetBlues) {
|
||||
if !reflect.DeepEqual(testBlockData.expectedMergeSetBlues, ghostdagData.MergeSetBlues) {
|
||||
t.Fatalf("Test #%d failed: expected merge set blues %v but got %v.", testNum+1, testBlockData.expectedMergeSetBlues, ghostdagData.MergeSetBlues)
|
||||
}
|
||||
|
||||
if !DeepEqualHashArrays(testBlockData.expectedMergeSetReds, ghostdagData.MergeSetReds) {
|
||||
if !reflect.DeepEqual(testBlockData.expectedMergeSetReds, ghostdagData.MergeSetReds) {
|
||||
t.Fatalf("Test #%d failed: expected merge set reds %v but got %v.", testNum+1, testBlockData.expectedMergeSetReds, ghostdagData.MergeSetReds)
|
||||
}
|
||||
|
||||
}
|
||||
fmt.Printf(" Test success!\n\n")
|
||||
|
||||
//fmt.Printf("Test %d successfully finished. \n", testStruct.testNum+1)
|
||||
|
||||
dagTopology := &DAGTopologyManagerImpl{
|
||||
parentsMap: make(map[externalapi.DomainHash][]*externalapi.DomainHash),
|
||||
}
|
||||
dagTopology.parentsMap = make(map[externalapi.DomainHash][]*externalapi.DomainHash)
|
||||
dagTopology.parentsMap[*genesisHash] = nil
|
||||
|
||||
ghostdagDataStore := &GHOSTDAGDataStoreImpl{
|
||||
dagMap: make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData),
|
||||
}
|
||||
ghostdagDataStore.dagMap[*genesisHash] = &model.BlockGHOSTDAGData{
|
||||
BlueScore: 1,
|
||||
SelectedParent: nil,
|
||||
MergeSetBlues: nil,
|
||||
MergeSetReds: nil,
|
||||
BluesAnticoneSizes: nil,
|
||||
}
|
||||
blockGHOSTDAGDataGenesis := ghostdagDataStore.dagMap[*genesisHash]
|
||||
ghostdagDataStore.dagMap = make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData)
|
||||
ghostdagDataStore.dagMap[*genesisHash] = blockGHOSTDAGDataGenesis
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,16 +469,14 @@ func (ds *GHOSTDAGDataStoreImpl) Commit(dbTx model.DBTransaction) error {
|
||||
// return nil
|
||||
//}
|
||||
func (ds *GHOSTDAGDataStoreImpl) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (*model.BlockGHOSTDAGData, error) {
|
||||
v, ok := ds.dagMap[*blockHash]
|
||||
if ok {
|
||||
return v, nil
|
||||
blockData, isExist := ds.dagMap[*blockHash]
|
||||
if isExist {
|
||||
return blockData, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
//candidateBluesAnticoneSizes = make(map[externalapi.DomainHash]model.KType, gm.k)
|
||||
type DAGTopologyManagerImpl struct {
|
||||
//dagMap map[*externalapi.DomainHash] *model.BlockGHOSTDAGData
|
||||
parentsMap map[externalapi.DomainHash][]*externalapi.DomainHash
|
||||
}
|
||||
|
||||
@@ -525,12 +490,11 @@ func (dt *DAGTopologyManagerImpl) AddTip(tipHash *externalapi.DomainHash) error
|
||||
|
||||
//Implemented//
|
||||
func (dt *DAGTopologyManagerImpl) Parents(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
v, ok := dt.parentsMap[*blockHash]
|
||||
if !ok {
|
||||
return make([]*externalapi.DomainHash, 0), nil
|
||||
blockData, isExist := dt.parentsMap[*blockHash]
|
||||
if !isExist {
|
||||
return []*externalapi.DomainHash{}, nil
|
||||
}
|
||||
|
||||
return v, nil
|
||||
return blockData, nil
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) Children(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
@@ -546,22 +510,24 @@ func (dt *DAGTopologyManagerImpl) IsChildOf(blockHashA *externalapi.DomainHash,
|
||||
}
|
||||
|
||||
//Implemented//
|
||||
func (dt *DAGTopologyManagerImpl) IsAncestorOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
bParents, ok := dt.parentsMap[*blockHashB]
|
||||
if !ok {
|
||||
func (dt *DAGTopologyManagerImpl) IsAncestorOf(hashBlockA *externalapi.DomainHash, hashBlockB *externalapi.DomainHash) (bool, error) {
|
||||
blockBParents, isOk := dt.parentsMap[*hashBlockB]
|
||||
if !isOk {
|
||||
return false, nil
|
||||
}
|
||||
for _, parent := range bParents {
|
||||
if *parent == *blockHashA {
|
||||
|
||||
for _, parentOfB := range blockBParents {
|
||||
if *parentOfB == *hashBlockA {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
for _, y := range bParents {
|
||||
isAnc, err := dt.IsAncestorOf(blockHashA, y)
|
||||
|
||||
for _, parentOfB := range blockBParents {
|
||||
isAncestorOf, err := dt.IsAncestorOf(hashBlockA, parentOfB)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if isAnc {
|
||||
if isAncestorOf {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
package ghostdagmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/processes/ghostdag2"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestGHOSTDAG iterates over several dag simulations, and checks
|
||||
// that the blue score, blue set and selected parent of each
|
||||
// block are calculated as expected.
|
||||
func TestGHOSTDAG(t *testing.T) {
|
||||
|
||||
type block struct {
|
||||
ID string `json:"ID"`
|
||||
Score uint64 `json:"ExpectedScore"`
|
||||
SelectedParent string `json:"ExpectedSelectedParent"`
|
||||
MergeSetReds []string `json:"ExpectedReds"`
|
||||
MergeSetBlues []string `json:"ExpectedBlues"`
|
||||
Parents []string `json:"Parents"`
|
||||
}
|
||||
|
||||
// json struct:
|
||||
type testDag struct {
|
||||
K model.KType `json:"K"`
|
||||
GenesisID string `json:"GenesisID"`
|
||||
ExpectedMergeSetReds []string `json:"ExpectedReds"`
|
||||
Blocks []block `json:"Blocks"`
|
||||
}
|
||||
|
||||
type implManager struct {
|
||||
function func(
|
||||
databaseContext model.DBReader,
|
||||
dagTopologyManager model.DAGTopologyManager,
|
||||
ghostdagDataStore model.GHOSTDAGDataStore,
|
||||
k model.KType) model.GHOSTDAGManager
|
||||
implName string
|
||||
}
|
||||
|
||||
dagTopology := &DAGTopologyManagerImpl{
|
||||
parentsMap: make(map[externalapi.DomainHash][]*externalapi.DomainHash),
|
||||
}
|
||||
|
||||
ghostdagDataStore := &GHOSTDAGDataStoreImpl{
|
||||
dagMap: make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData),
|
||||
}
|
||||
var blockGHOSTDAGDataGenesis = &model.BlockGHOSTDAGData{
|
||||
BlueScore: 0,
|
||||
SelectedParent: nil,
|
||||
MergeSetBlues: nil,
|
||||
MergeSetReds: nil,
|
||||
BluesAnticoneSizes: nil,
|
||||
}
|
||||
|
||||
err := filepath.Walk("../../testdata/dags", func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
jsonFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
t.Fatalf("TestGHOSTDAG : failed opening the json file %s: %v", info.Name(), err)
|
||||
}
|
||||
defer jsonFile.Close()
|
||||
var test testDag
|
||||
decoder := json.NewDecoder(jsonFile)
|
||||
decoder.DisallowUnknownFields()
|
||||
err = decoder.Decode(&test)
|
||||
if err != nil {
|
||||
t.Fatalf("TestGHOSTDAG:failed decoding json: %v", err)
|
||||
}
|
||||
|
||||
var genesisHash externalapi.DomainHash
|
||||
copy(genesisHash[:], test.GenesisID)
|
||||
|
||||
dagTopology.parentsMap[genesisHash] = nil
|
||||
|
||||
ghostdagDataStore.dagMap[genesisHash] = blockGHOSTDAGDataGenesis
|
||||
|
||||
//NOTE: FOR ADDING/REMOVING AN IMPLEMENTATION CHANGE BELOW:
|
||||
implementationFactories := []implManager{
|
||||
{New, "Original"},
|
||||
{ghostdag2.New, "Tal's impl"},
|
||||
}
|
||||
|
||||
for _, factory := range implementationFactories {
|
||||
|
||||
g := factory.function(nil, dagTopology, ghostdagDataStore, model.KType(test.K))
|
||||
for _, testBlockData := range test.Blocks {
|
||||
|
||||
blockID := StringToByte(testBlockData.ID)
|
||||
dagTopology.parentsMap[*blockID] = StringToByteArray(testBlockData.Parents)
|
||||
|
||||
err := g.GHOSTDAG(blockID)
|
||||
if err != nil {
|
||||
t.Fatalf("Test failed: \n Impl: %s,FileName: %s \n error on GHOSTDAG - block %s: %s.",
|
||||
factory.implName, info.Name(), testBlockData.ID, err)
|
||||
}
|
||||
ghostdagData, err := ghostdagDataStore.Get(nil, blockID)
|
||||
if err != nil {
|
||||
t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: ghostdagDataStore error: %v.",
|
||||
factory.implName, info.Name(), testBlockData.ID, err)
|
||||
}
|
||||
|
||||
if testBlockData.Score != (ghostdagData.BlueScore) {
|
||||
t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected blue score %d but got %d.",
|
||||
factory.implName, info.Name(), testBlockData.ID, testBlockData.Score, ghostdagData.BlueScore)
|
||||
}
|
||||
|
||||
if *StringToByte(testBlockData.SelectedParent) != *ghostdagData.SelectedParent {
|
||||
t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected selected parent %v but got %v.",
|
||||
factory.implName, info.Name(), testBlockData.ID, testBlockData.SelectedParent, string(ghostdagData.SelectedParent[:]))
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetBlues), ghostdagData.MergeSetBlues) {
|
||||
t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected merge set blues %v but got %v.",
|
||||
factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetBlues, hashesToStrings(ghostdagData.MergeSetBlues))
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetReds), ghostdagData.MergeSetReds) {
|
||||
t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected merge set reds %v but got %v.",
|
||||
factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetReds, hashesToStrings(ghostdagData.MergeSetReds))
|
||||
}
|
||||
|
||||
}
|
||||
dagTopology.parentsMap = make(map[externalapi.DomainHash][]*externalapi.DomainHash)
|
||||
dagTopology.parentsMap[genesisHash] = nil
|
||||
ghostdagDataStore.dagMap = make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData)
|
||||
ghostdagDataStore.dagMap[genesisHash] = blockGHOSTDAGDataGenesis
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func hashesToStrings(arr []*externalapi.DomainHash) []string {
|
||||
var strArr = make([]string, len(arr))
|
||||
for i, hash := range arr {
|
||||
strArr[i] = string(hash[:])
|
||||
}
|
||||
return strArr
|
||||
}
|
||||
|
||||
func StringToByte(strID string) *externalapi.DomainHash {
|
||||
var domainHash externalapi.DomainHash
|
||||
copy(domainHash[:], strID)
|
||||
return &domainHash
|
||||
}
|
||||
|
||||
func StringToByteArray(stringIDArr []string) []*externalapi.DomainHash {
|
||||
domainHashArr := make([]*externalapi.DomainHash, len(stringIDArr))
|
||||
for i, strID := range stringIDArr {
|
||||
domainHashArr[i] = StringToByte(strID)
|
||||
}
|
||||
return domainHashArr
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
type GHOSTDAGDataStoreImpl struct {
|
||||
dagMap map[externalapi.DomainHash]*model.BlockGHOSTDAGData
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) error {
|
||||
ds.dagMap[*blockHash] = blockGHOSTDAGData
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) IsStaged() bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Discard() {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Commit(dbTx model.DBTransaction) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (*model.BlockGHOSTDAGData, error) {
|
||||
v, ok := ds.dagMap[*blockHash]
|
||||
if ok {
|
||||
return v, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type DAGTopologyManagerImpl struct {
|
||||
parentsMap map[externalapi.DomainHash][]*externalapi.DomainHash
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) Tips() ([]*externalapi.DomainHash, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) AddTip(tipHash *externalapi.DomainHash) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) Parents(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
v, ok := dt.parentsMap[*blockHash]
|
||||
if !ok {
|
||||
return []*externalapi.DomainHash{}, nil
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) Children(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsParentOf(hashBlockA *externalapi.DomainHash, hashBlockB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsChildOf(hashBlockA *externalapi.DomainHash, hashBlockB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsAncestorOf(hashBlockA *externalapi.DomainHash, hashBlockB *externalapi.DomainHash) (bool, error) {
|
||||
blockBParents, isOk := dt.parentsMap[*hashBlockB]
|
||||
if !isOk {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, parentOfB := range blockBParents {
|
||||
if *parentOfB == *hashBlockA {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
for _, parentOfB := range blockBParents {
|
||||
isAncestorOf, err := dt.IsAncestorOf(hashBlockA, parentOfB)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if isAncestorOf {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsDescendantOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsAncestorOfAny(blockHash *externalapi.DomainHash, potentialDescendants []*externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
func (dt *DAGTopologyManagerImpl) IsInSelectedParentChainOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) SetParents(blockHash *externalapi.DomainHash, parentHashes []*externalapi.DomainHash) error {
|
||||
panic("unimplemented")
|
||||
}
|
||||
301
domain/consensus/testdata/ghostdagWithJson_test.go
vendored
301
domain/consensus/testdata/ghostdagWithJson_test.go
vendored
@@ -1,301 +0,0 @@
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/processes/ghostdag2"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager"
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestGHOSTDAG iterates over several dag simulations, and checks
|
||||
// that the blue score, blue set and selected parent of each
|
||||
// block are calculated as expected.
|
||||
func TestGHOSTDAG(t *testing.T) {
|
||||
|
||||
type block struct {
|
||||
ID string `json:"ID"`
|
||||
Score uint64 `json:"ExpectedScore"`
|
||||
SelectedParent string `json:"ExpectedSelectedParent"`
|
||||
MergeSetReds []string `json:"ExpectedReds"`
|
||||
MergeSetBlues []string `json:"ExpectedBlues"`
|
||||
Parents []string `json:"Parents"`
|
||||
}
|
||||
|
||||
// json struct:
|
||||
type testDag struct {
|
||||
K dagconfig.KType `json:"K"`
|
||||
GenesisID string `json:"GenesisID"`
|
||||
ExpectedMergeSetReds []string `json:"ExpectedReds"`
|
||||
Blocks []block `json:"Blocks"`
|
||||
}
|
||||
|
||||
type implManager struct {
|
||||
function func(
|
||||
databaseContext model.DBReader,
|
||||
dagTopologyManager model.DAGTopologyManager,
|
||||
ghostdagDataStore model.GHOSTDAGDataStore,
|
||||
k model.KType) model.GHOSTDAGManager
|
||||
implName string
|
||||
}
|
||||
|
||||
dagTopology := &DAGTopologyManagerImpl{
|
||||
parentsMap: make(map[externalapi.DomainHash][]*externalapi.DomainHash),
|
||||
}
|
||||
|
||||
ghostdagDataStore := &GHOSTDAGDataStoreImpl{
|
||||
dagMap: make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData),
|
||||
}
|
||||
var dirName = "./dags"
|
||||
items, err := ioutil.ReadDir(dirName)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed read dir %s: %v.", dirName, err)
|
||||
}
|
||||
for _, item := range items {
|
||||
if item.IsDir() {
|
||||
fmt.Printf("Please change path above. you are now on: %s./n", item.Name())
|
||||
} else {
|
||||
jsonFile, err := os.Open(dirName + "/" + item.Name())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed opening the json file %s: %v", item.Name(), err)
|
||||
}
|
||||
defer jsonFile.Close()
|
||||
var test testDag
|
||||
decoder := json.NewDecoder(jsonFile)
|
||||
decoder.DisallowUnknownFields()
|
||||
err = decoder.Decode(&test)
|
||||
if err != nil {
|
||||
t.Fatalf("TestGHOSTDAG:failed decoding json: %v", err)
|
||||
}
|
||||
|
||||
var genesisHash externalapi.DomainHash //change genesis ID from type string to type []byte
|
||||
copy(genesisHash[:], test.GenesisID)
|
||||
|
||||
dagTopology.parentsMap[genesisHash] = nil
|
||||
ghostdagDataStore.dagMap[genesisHash] = &model.BlockGHOSTDAGData{
|
||||
BlueScore: 0,
|
||||
SelectedParent: nil,
|
||||
MergeSetBlues: nil,
|
||||
MergeSetReds: nil,
|
||||
BluesAnticoneSizes: nil,
|
||||
}
|
||||
|
||||
//NOTE: FOR ADDING/REMOVING AN IMPLEMENTATION CHANGE BELOW:
|
||||
implementationFactories := []implManager{
|
||||
{ghostdagmanager.New, "Original"},
|
||||
{ghostdag2.New, "Tal's impl"},
|
||||
}
|
||||
|
||||
for _, factory := range implementationFactories {
|
||||
|
||||
g := factory.function(nil, dagTopology, ghostdagDataStore, model.KType(test.K))
|
||||
for _, testBlockData := range test.Blocks {
|
||||
|
||||
blockID := infoStrToByte(testBlockData.ID)
|
||||
dagTopology.parentsMap[*blockID] = infoStrToByteArray(testBlockData.Parents)
|
||||
|
||||
err := g.GHOSTDAG(blockID)
|
||||
if err != nil {
|
||||
t.Fatalf("Test failed: Impl: %s, error on GHOSTDAG - block %s: %s.",
|
||||
factory.implName, testBlockData.ID, err)
|
||||
}
|
||||
ghostdagData, err := ghostdagDataStore.Get(nil, blockID)
|
||||
if err != nil {
|
||||
t.Fatalf("\nTEST FAILED: Impl: %s, \nBlock: %s, \nError: ghostdagDataStore error: %v.",
|
||||
factory.implName, testBlockData.ID, err)
|
||||
}
|
||||
|
||||
if testBlockData.Score != (ghostdagData.BlueScore) {
|
||||
t.Fatalf("\nTEST FAILED: Impl: %s, \nBlock: %s, \nError: expected blue score %d but got %d.",
|
||||
factory.implName, testBlockData.ID, testBlockData.Score, ghostdagData.BlueScore)
|
||||
}
|
||||
|
||||
if *infoStrToByte(testBlockData.SelectedParent) != *ghostdagData.SelectedParent {
|
||||
t.Fatalf("\nTEST FAILED: Impl: %s, \nBlock: %s, \nError: expected selected parent %v but got %v.",
|
||||
factory.implName, testBlockData.ID, testBlockData.SelectedParent, string(ghostdagData.SelectedParent[:]))
|
||||
}
|
||||
|
||||
if !DeepEqualHashArrays(infoStrToByteArray(testBlockData.MergeSetBlues), ghostdagData.MergeSetBlues) {
|
||||
t.Fatalf("\nTEST FAILED: Impl: %s, \nBlock: %s, \nError: expected merge set blues %v but got %v.",
|
||||
factory.implName, testBlockData.ID, testBlockData.MergeSetBlues, hashToString(ghostdagData.MergeSetBlues))
|
||||
}
|
||||
|
||||
if !DeepEqualHashArrays(infoStrToByteArray(testBlockData.MergeSetReds), ghostdagData.MergeSetReds) {
|
||||
t.Fatalf("\nTEST FAILED: Impl: %s, \nBlock: %s, \nError: expected merge set reds %v but got %v.",
|
||||
factory.implName, testBlockData.ID, testBlockData.MergeSetReds, hashToString(ghostdagData.MergeSetReds))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dagTopology := &DAGTopologyManagerImpl{
|
||||
parentsMap: make(map[externalapi.DomainHash][]*externalapi.DomainHash),
|
||||
}
|
||||
dagTopology.parentsMap[genesisHash] = nil
|
||||
|
||||
ghostdagDataStore := &GHOSTDAGDataStoreImpl{
|
||||
dagMap: make(map[externalapi.DomainHash]*model.BlockGHOSTDAGData),
|
||||
}
|
||||
ghostdagDataStore.dagMap[genesisHash] = &model.BlockGHOSTDAGData{
|
||||
BlueScore: 1,
|
||||
SelectedParent: nil,
|
||||
MergeSetBlues: nil,
|
||||
MergeSetReds: nil,
|
||||
BluesAnticoneSizes: nil,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Printf("All tests passed!\n")
|
||||
}
|
||||
|
||||
func hashToString(arr []*externalapi.DomainHash) []string {
|
||||
var strArr = make([]string, len(arr))
|
||||
if len(arr) == 0 {
|
||||
return strArr
|
||||
}
|
||||
for i, hash := range arr {
|
||||
strArr[i] = string(hash[:])
|
||||
}
|
||||
return strArr
|
||||
}
|
||||
|
||||
func infoStrToByte(strID string) *externalapi.DomainHash {
|
||||
var domainHash externalapi.DomainHash
|
||||
copy(domainHash[:], strID)
|
||||
return &domainHash
|
||||
}
|
||||
|
||||
func infoStrToByteArray(strIDArr []string) []*externalapi.DomainHash {
|
||||
var domainHashArr []*externalapi.DomainHash
|
||||
for _, strID := range strIDArr {
|
||||
domainHashArr = append(domainHashArr, infoStrToByte(strID))
|
||||
}
|
||||
return domainHashArr
|
||||
}
|
||||
|
||||
func contains(hash *externalapi.DomainHash, hashArr []*externalapi.DomainHash) bool {
|
||||
for _, item := range hashArr {
|
||||
if *item == *hash {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func DeepEqualHashArrays(runtime, expected []*externalapi.DomainHash) bool {
|
||||
if len(runtime) != len(expected) {
|
||||
return false
|
||||
}
|
||||
for _, hash := range runtime {
|
||||
if !contains(hash, expected) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
type GHOSTDAGDataStoreImpl struct {
|
||||
dagMap map[externalapi.DomainHash]*model.BlockGHOSTDAGData
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) error {
|
||||
ds.dagMap[*blockHash] = blockGHOSTDAGData
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) IsStaged() bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Discard() {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Commit(dbTx model.DBTransaction) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (ds *GHOSTDAGDataStoreImpl) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (*model.BlockGHOSTDAGData, error) {
|
||||
v, ok := ds.dagMap[*blockHash]
|
||||
if ok {
|
||||
return v, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type DAGTopologyManagerImpl struct {
|
||||
parentsMap map[externalapi.DomainHash][]*externalapi.DomainHash
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) Tips() ([]*externalapi.DomainHash, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) AddTip(tipHash *externalapi.DomainHash) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) Parents(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
v, ok := dt.parentsMap[*blockHash]
|
||||
if !ok {
|
||||
return make([]*externalapi.DomainHash, 0), nil
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) Children(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsParentOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsChildOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsAncestorOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
bParents, ok := dt.parentsMap[*blockHashB]
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
for _, parent := range bParents {
|
||||
if *parent == *blockHashA {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
for _, y := range bParents {
|
||||
isAnc, err := dt.IsAncestorOf(blockHashA, y)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if isAnc {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsDescendantOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) IsAncestorOfAny(blockHash *externalapi.DomainHash, potentialDescendants []*externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
func (dt *DAGTopologyManagerImpl) IsInSelectedParentChainOf(blockHashA *externalapi.DomainHash, blockHashB *externalapi.DomainHash) (bool, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (dt *DAGTopologyManagerImpl) SetParents(blockHash *externalapi.DomainHash, parentHashes []*externalapi.DomainHash) error {
|
||||
panic("unimplemented")
|
||||
}
|
||||
Reference in New Issue
Block a user