Speedup iteration of blocks in sidechain using iterationCache
This commit is contained in:
parent
5c24136e45
commit
b57226c7ed
|
@ -495,15 +495,23 @@ func (c *SideChain) verifyLoop(blockToVerify *PoolBlock) (err error) {
|
|||
// This block is now verified
|
||||
|
||||
// Fill cache here
|
||||
block.iterationCache = &IterationCache{
|
||||
Parent: c.getParent(block),
|
||||
Uncles: nil,
|
||||
}
|
||||
|
||||
if len(block.Side.Uncles) > 0 {
|
||||
block.iterationCache.Uncles = make([]*PoolBlock, 0, len(block.Side.Uncles))
|
||||
for _, uncleId := range block.Side.Uncles {
|
||||
block.iterationCache.Uncles = append(block.iterationCache.Uncles, c.getPoolBlockByTemplateId(uncleId))
|
||||
if parent := c.getParent(block); parent != nil {
|
||||
block.iterationCache = &IterationCache{
|
||||
Parent: parent,
|
||||
Uncles: nil,
|
||||
}
|
||||
|
||||
if len(block.Side.Uncles) > 0 {
|
||||
block.iterationCache.Uncles = make([]*PoolBlock, 0, len(block.Side.Uncles))
|
||||
for _, uncleId := range block.Side.Uncles {
|
||||
if uncle := c.getPoolBlockByTemplateId(uncleId); uncle == nil {
|
||||
block.iterationCache = nil
|
||||
break
|
||||
} else {
|
||||
block.iterationCache.Uncles = append(block.iterationCache.Uncles, uncle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,7 +774,7 @@ func (c *SideChain) updateDepths(block *PoolBlock) {
|
|||
for i := uint64(1); i <= UncleBlockDepth; i++ {
|
||||
blocksAtHeight, _ := c.blocksByHeight.Get(block.Side.Height + i)
|
||||
for _, child := range blocksAtHeight {
|
||||
if child.Side.Parent.Equals(block.SideTemplateId(c.Consensus())) {
|
||||
if child.Side.Parent == block.SideTemplateId(c.Consensus()) {
|
||||
if i != 1 {
|
||||
log.Printf("[SideChain] Block %s side height %d is inconsistent with parent's side_height %d", block.SideTemplateId(c.Consensus()), block.Side.Height, child.Side.Height)
|
||||
return
|
||||
|
@ -794,7 +802,7 @@ func (c *SideChain) updateDepths(block *PoolBlock) {
|
|||
_ = c.verifyLoop(block)
|
||||
}
|
||||
|
||||
if parent := c.getParent(block); parent != nil {
|
||||
if parent := block.iteratorGetParent(c.getPoolBlockByTemplateId); parent != nil {
|
||||
if parent.Side.Height+1 != block.Side.Height {
|
||||
log.Printf("[SideChain] Block %s side height %d is inconsistent with parent's side_height %d", block.SideTemplateId(c.Consensus()), block.Side.Height, parent.Side.Height)
|
||||
return
|
||||
|
@ -806,19 +814,23 @@ func (c *SideChain) updateDepths(block *PoolBlock) {
|
|||
}
|
||||
}
|
||||
|
||||
for _, uncleId := range block.Side.Uncles {
|
||||
if uncle := c.getPoolBlockByTemplateId(uncleId); uncle != nil {
|
||||
if uncle.Side.Height >= block.Side.Height || (uncle.Side.Height+UncleBlockDepth < block.Side.Height) {
|
||||
log.Printf("[SideChain] Block %s side height %d is inconsistent with uncle's side_height %d", block.SideTemplateId(c.Consensus()), block.Side.Height, uncle.Side.Height)
|
||||
return
|
||||
}
|
||||
var returnFromUncles bool
|
||||
|
||||
d := block.Side.Height - uncle.Side.Height
|
||||
if uncle.Depth.Load() < blockDepth+d {
|
||||
uncle.Depth.Store(blockDepth + d)
|
||||
blocksToUpdate = append(blocksToUpdate, uncle)
|
||||
}
|
||||
_ = block.iteratorUncles(c.getPoolBlockByTemplateId, func(uncle *PoolBlock) {
|
||||
if uncle.Side.Height >= block.Side.Height || (uncle.Side.Height+UncleBlockDepth < block.Side.Height) {
|
||||
log.Printf("[SideChain] Block %s side height %d is inconsistent with uncle's side_height %d", block.SideTemplateId(c.Consensus()), block.Side.Height, uncle.Side.Height)
|
||||
returnFromUncles = true
|
||||
return
|
||||
}
|
||||
|
||||
d := block.Side.Height - uncle.Side.Height
|
||||
if uncle.Depth.Load() < blockDepth+d {
|
||||
uncle.Depth.Store(blockDepth + d)
|
||||
blocksToUpdate = append(blocksToUpdate, uncle)
|
||||
}
|
||||
})
|
||||
if returnFromUncles {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -967,14 +979,14 @@ func (c *SideChain) GetMissingBlocks() []types.Hash {
|
|||
return false
|
||||
}
|
||||
|
||||
if !b.Side.Parent.Equals(types.ZeroHash) && c.getPoolBlockByTemplateId(b.Side.Parent) == nil {
|
||||
if b.Side.Parent != types.ZeroHash && c.getPoolBlockByTemplateId(b.Side.Parent) == nil {
|
||||
missingBlocks = append(missingBlocks, b.Side.Parent)
|
||||
}
|
||||
|
||||
missingUncles := 0
|
||||
|
||||
for _, uncleId := range b.Side.Uncles {
|
||||
if !uncleId.Equals(types.ZeroHash) && c.getPoolBlockByTemplateId(uncleId) == nil {
|
||||
if uncleId != types.ZeroHash && c.getPoolBlockByTemplateId(uncleId) == nil {
|
||||
missingBlocks = append(missingBlocks, uncleId)
|
||||
missingUncles++
|
||||
|
||||
|
|
|
@ -290,3 +290,21 @@ func BenchmarkSideChainDefault_GetShares(b *testing.B) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSideChainDefault_BlocksInPPLNSWindow(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
tip := benchLoadedSideChain.GetChainTip()
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var err error
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err = BlocksInPPLNSWindow(tip, benchLoadedSideChain.Consensus(), benchLoadedSideChain.server.GetDifficultyByHeight, benchLoadedSideChain.getPoolBlockByTemplateId, func(b *PoolBlock, weight types.Difficulty) {
|
||||
|
||||
})
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,23 +503,23 @@ func IsLongerChain(block, candidate *PoolBlock, consensus *Consensus, getByTempl
|
|||
|
||||
blockAncestor := block
|
||||
for blockAncestor != nil && blockAncestor.Side.Height > candidate.Side.Height {
|
||||
blockAncestor = getByTemplateId(blockAncestor.Side.Parent)
|
||||
blockAncestor = blockAncestor.iteratorGetParent(getByTemplateId)
|
||||
//TODO: err on blockAncestor nil
|
||||
}
|
||||
|
||||
if blockAncestor != nil {
|
||||
candidateAncestor := candidate
|
||||
for candidateAncestor != nil && candidateAncestor.Side.Height > blockAncestor.Side.Height {
|
||||
candidateAncestor = getByTemplateId(candidateAncestor.Side.Parent)
|
||||
candidateAncestor = candidateAncestor.iteratorGetParent(getByTemplateId)
|
||||
//TODO: err on candidateAncestor nil
|
||||
}
|
||||
|
||||
for blockAncestor != nil && candidateAncestor != nil {
|
||||
if blockAncestor.Side.Parent.Equals(candidateAncestor.Side.Parent) {
|
||||
if blockAncestor.Side.Parent == candidateAncestor.Side.Parent {
|
||||
return block.Side.CumulativeDifficulty.Cmp(candidate.Side.CumulativeDifficulty) < 0, false
|
||||
}
|
||||
blockAncestor = getByTemplateId(blockAncestor.Side.Parent)
|
||||
candidateAncestor = getByTemplateId(candidateAncestor.Side.Parent)
|
||||
blockAncestor = blockAncestor.iteratorGetParent(getByTemplateId)
|
||||
candidateAncestor = candidateAncestor.iteratorGetParent(getByTemplateId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,15 +538,13 @@ func IsLongerChain(block, candidate *PoolBlock, consensus *Consensus, getByTempl
|
|||
for i := uint64(0); i < consensus.ChainWindowSize && (oldChain != nil || newChain != nil); i++ {
|
||||
if oldChain != nil {
|
||||
blockTotalDiff = blockTotalDiff.Add(oldChain.Side.Difficulty)
|
||||
for _, uncle := range oldChain.Side.Uncles {
|
||||
if u := getByTemplateId(uncle); u != nil {
|
||||
blockTotalDiff = blockTotalDiff.Add(u.Side.Difficulty)
|
||||
}
|
||||
}
|
||||
_ = oldChain.iteratorUncles(getByTemplateId, func(uncle *PoolBlock) {
|
||||
blockTotalDiff = blockTotalDiff.Add(uncle.Side.Difficulty)
|
||||
})
|
||||
if !slices.Contains(currentChainMoneroBlocks, oldChain.Main.PreviousId) && getChainMainByHash(oldChain.Main.PreviousId) != nil {
|
||||
currentChainMoneroBlocks = append(currentChainMoneroBlocks, oldChain.Main.PreviousId)
|
||||
}
|
||||
oldChain = getByTemplateId(oldChain.Side.Parent)
|
||||
oldChain = oldChain.iteratorGetParent(getByTemplateId)
|
||||
}
|
||||
|
||||
if newChain != nil {
|
||||
|
@ -556,11 +554,9 @@ func IsLongerChain(block, candidate *PoolBlock, consensus *Consensus, getByTempl
|
|||
candidateMainchainMinHeight = newChain.Main.Coinbase.GenHeight
|
||||
}
|
||||
candidateTotalDiff = candidateTotalDiff.Add(newChain.Side.Difficulty)
|
||||
for _, uncle := range newChain.Side.Uncles {
|
||||
if u := getByTemplateId(uncle); u != nil {
|
||||
candidateTotalDiff = candidateTotalDiff.Add(u.Side.Difficulty)
|
||||
}
|
||||
}
|
||||
_ = newChain.iteratorUncles(getByTemplateId, func(uncle *PoolBlock) {
|
||||
candidateTotalDiff = candidateTotalDiff.Add(uncle.Side.Difficulty)
|
||||
})
|
||||
if !slices.Contains(candidateChainMoneroBlocks, newChain.Main.PreviousId) {
|
||||
if data := getChainMainByHash(newChain.Main.PreviousId); data != nil {
|
||||
candidateChainMoneroBlocks = append(candidateChainMoneroBlocks, newChain.Main.PreviousId)
|
||||
|
@ -568,7 +564,7 @@ func IsLongerChain(block, candidate *PoolBlock, consensus *Consensus, getByTempl
|
|||
}
|
||||
}
|
||||
|
||||
newChain = getByTemplateId(newChain.Side.Parent)
|
||||
newChain = newChain.iteratorGetParent(getByTemplateId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
@ -92,10 +91,6 @@ func (h Hash) Compare(other Hash) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (h Hash) Equals(o Hash) bool {
|
||||
return bytes.Compare(h[:], o[:]) == 0
|
||||
}
|
||||
|
||||
func (h Hash) String() string {
|
||||
return hex.EncodeToString(h[:])
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue