diff --git a/core/core.go b/core/core.go index 597d8a4606..dbb9234a1b 100644 --- a/core/core.go +++ b/core/core.go @@ -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 ) @@ -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 { @@ -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) { diff --git a/core/slice.go b/core/slice.go index fdbc7eae59..8978bfa08c 100644 --- a/core/slice.go +++ b/core/slice.go @@ -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 @@ -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 @@ -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 @@ -319,13 +325,14 @@ 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 @@ -333,11 +340,11 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do 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 } @@ -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) @@ -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() @@ -384,18 +391,12 @@ 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 @@ -403,21 +404,15 @@ func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, new // 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 @@ -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) @@ -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 { @@ -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) @@ -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 @@ -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}) @@ -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 } @@ -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 } } diff --git a/eth/api_backend.go b/eth/api_backend.go index 69a91fd6d1..0b51d952a1 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -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) { diff --git a/internal/quaiapi/backend.go b/internal/quaiapi/backend.go index 58f56177bb..563c17a487 100644 --- a/internal/quaiapi/backend.go +++ b/internal/quaiapi/backend.go @@ -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) diff --git a/internal/quaiapi/quai_api.go b/internal/quaiapi/quai_api.go index c1466ef801..26192e34d8 100644 --- a/internal/quaiapi/quai_api.go +++ b/internal/quaiapi/quai_api.go @@ -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) { @@ -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 { diff --git a/quaiclient/quaiclient.go b/quaiclient/quaiclient.go index 40d9850c29..8f66a65891 100644 --- a/quaiclient/quaiclient.go +++ b/quaiclient/quaiclient.go @@ -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) }