Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfixes from the garden tests related to the slice logic #1099

Merged
merged 8 commits into from
Sep 12, 2023
9 changes: 5 additions & 4 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const (
c_primeRetryThreshold = 1800 // Number of times a block is retry to be appended before eviction from append queue in Prime
c_regionRetryThreshold = 1200 // Number of times a block is retry to be appended before eviction from append queue in Region
c_zoneRetryThreshold = 600 // Number of times a block is retry to be appended before eviction from append queue in Zone
c_maxFutureBlocks = 15 // Number of blocks ahead of the current block to be put in the hashNumberList
c_maxFutureBlocks = 100 // Number of blocks ahead of the current block to be put in the hashNumberList
c_appendQueueRetryPriorityThreshold = 5 // If retry counter for a block is less than this number, then its put in the special list that is tried first to be appended
c_appendQueueRemoveThreshold = 10 // Number of blocks behind the block should be from the current header to be eligble for removal from the append queue
)
Expand Down Expand Up @@ -359,11 +359,12 @@ func (c *Core) WriteBlock(block *types.Block) {
}
nodeCtx := common.NodeLocation.Context()
if order == nodeCtx {
c.addToAppendQueue(block)
parentHeader := c.GetHeader(block.ParentHash(), block.NumberU64()-1)
if parentHeader != nil {
c.sl.WriteBlock(block)
c.InsertChain([]*types.Block{block})
}
c.addToAppendQueue(block)
// If a dom block comes in and we havent appended it yet
} else if order < nodeCtx && c.GetHeaderByHash(block.Hash()) == nil {
if c.sl.domClient != nil {
Expand Down Expand Up @@ -395,8 +396,8 @@ func (c *Core) SubRelayPendingHeader(slPendingHeader types.PendingHeader, newEnt
c.sl.SubRelayPendingHeader(slPendingHeader, newEntropy, location, subReorg)
}

func (c *Core) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) {
c.sl.UpdateDom(oldTerminus, newTerminus, newEntropy, location)
func (c *Core) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) {
c.sl.UpdateDom(oldTerminus, newTerminus, pendingHeader, location)
}

func (c *Core) NewGenesisPendigHeader(pendingHeader *types.Header) {
Expand Down
83 changes: 44 additions & 39 deletions core/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do

time7 := common.PrettyDuration(time.Since(start))

sl.phCacheMu.Lock()
defer sl.phCacheMu.Unlock()

var time8, time9 common.PrettyDuration
var bestPh types.PendingHeader
var exist bool
Expand All @@ -255,7 +258,12 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do

time8 = common.PrettyDuration(time.Since(start))

subReorg = sl.miningStrategy(bestPh, block)
tempPendingHeader, err := sl.generateSlicePendingHeader(block, newTermini, domPendingHeader, domOrigin, false, false)
if err != nil {
return nil, false, err
}

subReorg = sl.miningStrategy(bestPh, tempPendingHeader)

if order < nodeCtx {
// Store the inbound etxs for dom blocks that did not get picked and use
Expand All @@ -279,8 +287,6 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do
time9 = common.PrettyDuration(time.Since(start))

}
sl.phCacheMu.Lock()
defer sl.phCacheMu.Unlock()
sl.updatePhCache(pendingHeaderWithTermini, true, nil, subReorg)

var updateDom bool
Expand Down Expand Up @@ -319,25 +325,26 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do
"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "etxs", len(block.ExtTransactions()), "gas", block.GasUsed(),
"root", block.Root(),
"order", order,
"location", block.Header().Location(),
"elapsed", common.PrettyDuration(time.Since(start)))

if nodeCtx == common.ZONE_CTX {
if updateDom {
log.Info("Append updateDom", "oldTermini():", bestPh.Termini().DomTerminus(), "newTermini():", pendingHeaderWithTermini.Termini().DomTerminus(), "location:", common.NodeLocation)
if sl.domClient != nil {
go sl.domClient.UpdateDom(context.Background(), bestPh.Termini().DomTerminus(), pendingHeaderWithTermini.Termini().DomTerminus(), pendingHeaderWithTermini.Header().ParentEntropy(), common.NodeLocation)
go sl.domClient.UpdateDom(context.Background(), bestPh.Termini().DomTerminus(), pendingHeaderWithTermini.Termini().DomTerminus(), pendingHeaderWithTermini.Header(), common.NodeLocation)
}
}
return block.ExtTransactions(), subReorg, nil
} else {
return subPendingEtxs, subReorg, nil
}
}
func (sl *Slice) miningStrategy(bestPh types.PendingHeader, block *types.Block) bool {
func (sl *Slice) miningStrategy(bestPh types.PendingHeader, pendingHeader types.PendingHeader) bool {
if bestPh.Header() == nil { // This is the case where we try to append the block before we have not initialized the bestPh
return true
}
subReorg := sl.poem(sl.engine.TotalLogS(block.Header()), bestPh.Header().ParentEntropy())
subReorg := sl.poem(sl.engine.TotalLogPhS(pendingHeader.Header()), sl.engine.TotalLogPhS(bestPh.Header()))
return subReorg
}

Expand All @@ -359,7 +366,7 @@ func (sl *Slice) relayPh(block *types.Block, pendingHeaderWithTermini types.Pend
} else {
log.Warn("Pending Header for Best ph key does not exist", "best ph key", sl.bestPhKey)
}
} else if !domOrigin {
} else if !domOrigin && subReorg {
for _, i := range sl.randomRelayArray() {
if sl.subClients[i] != nil {
sl.subClients[i].SubRelayPendingHeader(context.Background(), pendingHeaderWithTermini, pendingHeaderWithTermini.Header().ParentEntropy(), location, subReorg)
Expand All @@ -370,7 +377,7 @@ func (sl *Slice) relayPh(block *types.Block, pendingHeaderWithTermini types.Pend

// If a zone changes its best ph key on a dom block, it sends a signal to the
// dom and we can relay that information to the coords, to build on the right dom header
func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) {
func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) {
nodeCtx := common.NodeLocation.Context()
sl.phCacheMu.Lock()
defer sl.phCacheMu.Unlock()
Expand All @@ -384,40 +391,28 @@ func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, new
log.Info("UpdateDom:", "oldTerminus:", oldTerminus, "newTerminus:", newTerminus, "oldDomTerminus:", oldDomTermini.DomTerminus(), "newDomTerminus:", newDomTermini.DomTerminus())
if nodeCtx == common.REGION_CTX && oldDomTermini.DomTerminus() == newDomTermini.DomTerminus() {
// Can update
block := sl.hc.GetBlockByHash(newTerminus)
newPh := types.NewPendingHeader(pendingHeader, *newDomTermini)
sl.bestPhKey = newTerminus
if block != nil {
pendingHeaderWithTermini, err := sl.generateSlicePendingHeader(block, *newDomTermini, types.EmptyHeader(), false, true, false)
if err != nil {
return
}
log.Info("pendingHeaderWithTermini:", "parent Hash:", pendingHeaderWithTermini.Header().ParentHash(), "Number", pendingHeaderWithTermini.Header().NumberArray())
for _, i := range sl.randomRelayArray() {
if sl.subClients[i] != nil {
sl.subClients[i].SubRelayPendingHeader(context.Background(), pendingHeaderWithTermini, newEntropy, common.Location{}, true)
}
log.Info("newPh:", "parent Hash:", newPh.Header().ParentHash(), "Number", newPh.Header().NumberArray())
for _, i := range sl.randomRelayArray() {
if sl.subClients[i] != nil {
sl.subClients[i].SubRelayPendingHeader(context.Background(), newPh, pendingHeader.ParentEntropy(common.ZONE_CTX), common.Location{}, true)
}
}
return
} else {
// need to update dom
log.Info("Append need to updateDom", "oldDomTermini:", oldDomTermini, "newDomTermini:", newDomTermini, "location:", common.NodeLocation)
if sl.domClient != nil {
go sl.domClient.UpdateDom(context.Background(), oldDomTermini.DomTerminus(), newDomTermini.DomTerminus(), newEntropy, location)
go sl.domClient.UpdateDom(context.Background(), oldDomTermini.DomTerminus(), newDomTermini.DomTerminus(), pendingHeader, location)
} else {
// Can update
block := sl.hc.GetBlockByHash(newTerminus)
newPh := types.NewPendingHeader(pendingHeader, *newDomTermini)
sl.bestPhKey = newTerminus
if block != nil {
pendingHeaderWithTermini, err := sl.generateSlicePendingHeader(block, *newDomTermini, types.EmptyHeader(), false, true, false)
if err != nil {
return
}
log.Info("pendingHeaderWithTermini:", "parent Hash:", pendingHeaderWithTermini.Header().ParentHash(), "Number", pendingHeaderWithTermini.Header().NumberArray())
for _, i := range sl.randomRelayArray() {
if sl.subClients[i] != nil {
go sl.subClients[i].SubRelayPendingHeader(context.Background(), pendingHeaderWithTermini, newEntropy, location, true)
}
log.Info("newPh:", "parent Hash:", newPh.Header().ParentHash(), "Number", newPh.Header().NumberArray())
for _, i := range sl.randomRelayArray() {
if sl.subClients[i] != nil {
sl.subClients[i].SubRelayPendingHeader(context.Background(), newPh, pendingHeader.ParentEntropy(common.ZONE_CTX), common.Location{}, true)
}
}
return
Expand Down Expand Up @@ -498,6 +493,14 @@ func (sl *Slice) generateSlicePendingHeader(block *types.Block, newTermini types
localPendingHeader = types.EmptyHeader()
localPendingHeader.SetParentHash(block.Hash(), nodeCtx)
localPendingHeader.SetNumber(big.NewInt(int64(block.NumberU64()) + 1))
localPendingHeader.SetParentEntropy(sl.engine.TotalLogS(block.Header()))
if nodeCtx != common.PRIME_CTX {
if domOrigin {
localPendingHeader.SetParentDeltaS(big.NewInt(0), nodeCtx)
} else {
localPendingHeader.SetParentDeltaS(sl.engine.DeltaLogS(block.Header()), nodeCtx)
}
}

manifestHash := sl.miner.worker.ComputeManifestHash(block.Header())
localPendingHeader.SetManifestHash(manifestHash)
Expand Down Expand Up @@ -705,6 +708,10 @@ func (sl *Slice) computePendingHeader(localPendingHeaderWithTermini types.Pendin
var newPh *types.Header

if exists {
if domOrigin {
newPh = sl.combinePendingHeader(localPendingHeaderWithTermini.Header(), domPendingHeader, nodeCtx, true)
return types.NewPendingHeader(types.CopyHeader(newPh), localPendingHeaderWithTermini.Termini())
}
newPh = sl.combinePendingHeader(localPendingHeaderWithTermini.Header(), cachedPendingHeaderWithTermini.Header(), nodeCtx, true)
return types.NewPendingHeader(types.CopyHeader(newPh), localPendingHeaderWithTermini.Termini())
} else {
Expand All @@ -718,6 +725,8 @@ func (sl *Slice) computePendingHeader(localPendingHeaderWithTermini types.Pendin

// updatePhCacheFromDom combines the recieved pending header with the pending header stored locally at a given terminus for specified context
func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, terminiIndex int, indices []int, newEntropy *big.Int, subReorg bool) error {
sl.phCacheMu.Lock()
defer sl.phCacheMu.Unlock()
hash := pendingHeader.Termini().SubTerminiAtIndex(terminiIndex)
localPendingHeader, exists := sl.readPhCache(hash)

Expand All @@ -730,11 +739,9 @@ func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, termini
bestPh, exists := sl.readPhCache(sl.bestPhKey)
nodeCtx := common.NodeLocation.Context()
if nodeCtx == common.ZONE_CTX && exists && sl.bestPhKey != localPendingHeader.Termini().DomTerminus() && !sl.poem(newEntropy, bestPh.Header().ParentEntropy()) {
log.Info("subrelay rejected", "local dom terminus", localPendingHeader.Termini().DomTerminus(), "Number", localPendingHeader.Header().NumberArray(), "best ph key", sl.bestPhKey, "number", bestPh.Header().NumberArray(), "newentropy", newEntropy)
sl.phCacheMu.Lock()
log.Info("subrelay rejected", "local dom terminus", localPendingHeader.Termini().DomTerminus(), "Number", combinedPendingHeader.NumberArray(), "best ph key", sl.bestPhKey, "number", bestPh.Header().NumberArray(), "newentropy", newEntropy)
sl.updatePhCache(types.NewPendingHeader(combinedPendingHeader, localPendingHeader.Termini()), false, nil, sl.poem(newEntropy, localPendingHeader.Header().ParentEntropy()))
sl.phCacheMu.Unlock()
go sl.domClient.UpdateDom(context.Background(), localPendingHeader.Termini().DomTerminus(), sl.bestPhKey, bestPh.Header().ParentEntropy(), common.NodeLocation)
go sl.domClient.UpdateDom(context.Background(), localPendingHeader.Termini().DomTerminus(), sl.bestPhKey, bestPh.Header(), common.NodeLocation)
return nil
}
// Pick the head
Expand All @@ -747,7 +754,7 @@ func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, termini
log.Error("Error setting current header", "err", err, "Hash", block.Hash())
return err
}
log.Info("Choosing phHeader pickPhHead:", "NumberArray:", localPendingHeader.Header().NumberArray(), "Number:", localPendingHeader.Header().Number(), "ParentHash:", localPendingHeader.Header().ParentHash(), "Terminus:", localPendingHeader.Termini().DomTerminus())
log.Info("Choosing phHeader pickPhHead:", "NumberArray:", combinedPendingHeader.NumberArray(), "Number:", combinedPendingHeader.Number(), "ParentHash:", combinedPendingHeader.ParentHash(), "Terminus:", localPendingHeader.Termini().DomTerminus())
sl.bestPhKey = localPendingHeader.Termini().DomTerminus()
if block.Hash() != sl.hc.CurrentHeader().Hash() {
sl.hc.chainHeadFeed.Send(ChainHeadEvent{block})
Expand Down Expand Up @@ -780,9 +787,7 @@ func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, termini
}
}

sl.phCacheMu.Lock()
sl.updatePhCache(types.NewPendingHeader(combinedPendingHeader, localPendingHeader.Termini()), false, nil, subReorg)
sl.phCacheMu.Unlock()

return nil
}
Expand All @@ -806,7 +811,7 @@ func (sl *Slice) updatePhCache(pendingHeaderWithTermini types.PendingHeader, inS
if !exists {
return
}
if !sl.poem(pendingHeaderWithTermini.Header().ParentEntropy(), bestPh.Header().ParentEntropy()) {
if !sl.miningStrategy(bestPh, pendingHeaderWithTermini) {
return
}
}
Expand Down
4 changes: 2 additions & 2 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,8 @@ func (b *QuaiAPIBackend) SubRelayPendingHeader(pendingHeader types.PendingHeader
b.eth.core.SubRelayPendingHeader(pendingHeader, newEntropy, location, subReorg)
}

func (b *QuaiAPIBackend) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) {
b.eth.core.UpdateDom(oldTerminus, newTerminus, newEntropy, location)
func (b *QuaiAPIBackend) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) {
b.eth.core.UpdateDom(oldTerminus, newTerminus, pendingHeader, location)
}

func (b *QuaiAPIBackend) RequestDomToAppendOrFetch(hash common.Hash, order int) {
Expand Down
2 changes: 1 addition & 1 deletion internal/quaiapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type Backend interface {
InsertBlock(ctx context.Context, block *types.Block) (int, error)
PendingBlock() *types.Block
SubRelayPendingHeader(pendingHeader types.PendingHeader, newEntropy *big.Int, location common.Location, subReorg bool)
UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location)
UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location)
RequestDomToAppendOrFetch(hash common.Hash, order int)
NewGenesisPendingHeader(pendingHeader *types.Header)
GetPendingHeader() (*types.Header, error)
Expand Down
4 changes: 2 additions & 2 deletions internal/quaiapi/quai_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ type DomUpdate struct {
OldTerminus common.Hash
NewTerminus common.Hash
Location common.Location
NewEntropy *big.Int
Header *types.Header
}

func (s *PublicBlockChainQuaiAPI) UpdateDom(ctx context.Context, raw json.RawMessage) {
Expand All @@ -677,7 +677,7 @@ func (s *PublicBlockChainQuaiAPI) UpdateDom(ctx context.Context, raw json.RawMes
return
}

s.b.UpdateDom(domUpdate.OldTerminus, domUpdate.NewTerminus, domUpdate.NewEntropy, domUpdate.Location)
s.b.UpdateDom(domUpdate.OldTerminus, domUpdate.NewTerminus, domUpdate.Header, domUpdate.Location)
}

type RequestDomToAppendOrFetchArgs struct {
Expand Down
4 changes: 2 additions & 2 deletions quaiclient/quaiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ func (ec *Client) SubRelayPendingHeader(ctx context.Context, pendingHeader types
ec.c.CallContext(ctx, nil, "quai_subRelayPendingHeader", data)
}

func (ec *Client) UpdateDom(ctx context.Context, oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) {
func (ec *Client) UpdateDom(ctx context.Context, oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) {
data := map[string]interface{}{"OldTerminus": oldTerminus}
data["NewTerminus"] = newTerminus
data["Location"] = location
data["NewEntropy"] = newEntropy
data["Header"] = pendingHeader.RPCMarshalHeader()

ec.c.CallContext(ctx, nil, "quai_updateDom", data)
}
Expand Down