github.com/dominant-strategies/go-quai@v0.28.2/core/headerchain.go (about) 1 package core 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "math/big" 8 "sync" 9 "sync/atomic" 10 "time" 11 12 "github.com/dominant-strategies/go-quai/common" 13 "github.com/dominant-strategies/go-quai/consensus" 14 "github.com/dominant-strategies/go-quai/consensus/misc" 15 "github.com/dominant-strategies/go-quai/core/rawdb" 16 "github.com/dominant-strategies/go-quai/core/state" 17 "github.com/dominant-strategies/go-quai/core/types" 18 "github.com/dominant-strategies/go-quai/core/vm" 19 "github.com/dominant-strategies/go-quai/ethdb" 20 "github.com/dominant-strategies/go-quai/event" 21 "github.com/dominant-strategies/go-quai/log" 22 "github.com/dominant-strategies/go-quai/params" 23 "github.com/dominant-strategies/go-quai/rlp" 24 "github.com/dominant-strategies/go-quai/trie" 25 lru "github.com/hashicorp/golang-lru" 26 ) 27 28 const ( 29 headerCacheLimit = 512 30 numberCacheLimit = 2048 31 c_subRollupCacheSize = 50 32 primeHorizonThreshold = 20 33 ) 34 35 // getPendingEtxsRollup gets the pendingEtxsRollup rollup from appropriate Region 36 type getPendingEtxsRollup func(blockHash common.Hash, hash common.Hash, location common.Location) (types.PendingEtxsRollup, error) 37 38 // getPendingEtxs gets the pendingEtxs from the appropriate Zone 39 type getPendingEtxs func(blockHash common.Hash, hash common.Hash, location common.Location) (types.PendingEtxs, error) 40 41 type HeaderChain struct { 42 config *params.ChainConfig 43 44 bc *BodyDb 45 engine consensus.Engine 46 pool *TxPool 47 48 chainHeadFeed event.Feed 49 chainSideFeed event.Feed 50 scope event.SubscriptionScope 51 52 headerDb ethdb.Database 53 genesisHeader *types.Header 54 55 currentHeader atomic.Value // Current head of the header chain (may be above the block chain!) 56 57 headerCache *lru.Cache // Cache for the most recent block headers 58 numberCache *lru.Cache // Cache for the most recent block numbers 59 60 fetchPEtxRollup getPendingEtxsRollup 61 fetchPEtx getPendingEtxs 62 63 pendingEtxsRollup *lru.Cache 64 pendingEtxs *lru.Cache 65 blooms *lru.Cache 66 subRollupCache *lru.Cache 67 68 wg sync.WaitGroup // chain processing wait group for shutting down 69 running int32 // 0 if chain is running, 1 when stopped 70 procInterrupt int32 // interrupt signaler for block processing 71 72 headermu sync.RWMutex 73 heads []*types.Header 74 slicesRunning []common.Location 75 } 76 77 // NewHeaderChain creates a new HeaderChain structure. ProcInterrupt points 78 // to the parent's interrupt semaphore. 79 func NewHeaderChain(db ethdb.Database, engine consensus.Engine, pEtxsRollupFetcher getPendingEtxsRollup, pEtxsFetcher getPendingEtxs, chainConfig *params.ChainConfig, cacheConfig *CacheConfig, txLookupLimit *uint64, vmConfig vm.Config, slicesRunning []common.Location) (*HeaderChain, error) { 80 headerCache, _ := lru.New(headerCacheLimit) 81 numberCache, _ := lru.New(numberCacheLimit) 82 nodeCtx := common.NodeLocation.Context() 83 84 hc := &HeaderChain{ 85 config: chainConfig, 86 headerDb: db, 87 headerCache: headerCache, 88 numberCache: numberCache, 89 engine: engine, 90 slicesRunning: slicesRunning, 91 fetchPEtxRollup: pEtxsRollupFetcher, 92 fetchPEtx: pEtxsFetcher, 93 } 94 95 pendingEtxsRollup, _ := lru.New(c_maxPendingEtxsRollup) 96 hc.pendingEtxsRollup = pendingEtxsRollup 97 98 if nodeCtx == common.PRIME_CTX { 99 hc.pendingEtxs, _ = lru.New(c_maxPendingEtxBatchesPrime) 100 } else { 101 hc.pendingEtxs, _ = lru.New(c_maxPendingEtxBatchesRegion) 102 } 103 104 blooms, _ := lru.New(c_maxBloomFilters) 105 hc.blooms = blooms 106 107 subRollupCache, _ := lru.New(c_subRollupCacheSize) 108 hc.subRollupCache = subRollupCache 109 110 hc.genesisHeader = hc.GetHeaderByNumber(0) 111 if hc.genesisHeader.Hash() != chainConfig.GenesisHash { 112 return nil, fmt.Errorf("genesis block mismatch: have %x, want %x", hc.genesisHeader.Hash(), chainConfig.GenesisHash) 113 } 114 log.Info("Genesis", "Hash:", hc.genesisHeader.Hash()) 115 if hc.genesisHeader == nil { 116 return nil, ErrNoGenesis 117 } 118 //Load any state that is in our db 119 if err := hc.loadLastState(); err != nil { 120 return nil, err 121 } 122 123 var err error 124 hc.bc, err = NewBodyDb(db, engine, hc, chainConfig, cacheConfig, txLookupLimit, vmConfig, slicesRunning) 125 if err != nil { 126 return nil, err 127 } 128 129 // Initialize the heads slice 130 heads := make([]*types.Header, 0) 131 hc.heads = heads 132 133 return hc, nil 134 } 135 136 // CollectSubRollup collects the rollup of ETXs emitted from the subordinate 137 // chain in the slice which emitted the given block. 138 func (hc *HeaderChain) CollectSubRollup(b *types.Block) (types.Transactions, error) { 139 nodeCtx := common.NodeLocation.Context() 140 subRollup := types.Transactions{} 141 if nodeCtx < common.ZONE_CTX { 142 // Since in prime the pending etxs are stored in 2 parts, pendingEtxsRollup 143 // consists of region header and its sub manifests 144 // Prime independently stores the pending etxs for each of the hashes in 145 // the sub manifests, so it needs the pendingEtxsRollup to do so. 146 for _, hash := range b.SubManifest() { 147 if nodeCtx == common.PRIME_CTX { 148 pEtxRollup, err := hc.GetPendingEtxsRollup(hash) 149 if err == nil { 150 for _, pEtxHash := range pEtxRollup.Manifest { 151 pendingEtxs, err := hc.GetPendingEtxs(pEtxHash) 152 if err != nil { 153 // Get the pendingEtx from the appropriate zone 154 hc.fetchPEtx(b.Hash(), pEtxHash, pEtxRollup.Header.Location()) 155 return nil, ErrPendingEtxNotFound 156 } 157 subRollup = append(subRollup, pendingEtxs.Etxs...) 158 } 159 } else { 160 // Try to get the pending etx from the Regions 161 hc.fetchPEtxRollup(b.Hash(), hash, b.Location()) 162 return nil, ErrPendingEtxNotFound 163 } 164 // Region works normally as before collecting pendingEtxs for each hash in the manifest 165 } else if nodeCtx == common.REGION_CTX { 166 pendingEtxs, err := hc.GetPendingEtxs(hash) 167 if err != nil { 168 // Get the pendingEtx from the appropriate zone 169 hc.fetchPEtx(b.Hash(), hash, b.Header().Location()) 170 return nil, ErrPendingEtxNotFound 171 } 172 subRollup = append(subRollup, pendingEtxs.Etxs...) 173 } 174 } 175 // Rolluphash is specifically for zone rollup, which can only be validated by region 176 if nodeCtx == common.REGION_CTX { 177 if subRollupHash := types.DeriveSha(subRollup, trie.NewStackTrie(nil)); subRollupHash != b.EtxRollupHash() { 178 return nil, errors.New("sub rollup does not match sub rollup hash") 179 } 180 } 181 } 182 return subRollup, nil 183 } 184 185 // GetPendingEtxs gets the pendingEtxs form the 186 func (hc *HeaderChain) GetPendingEtxs(hash common.Hash) (*types.PendingEtxs, error) { 187 var pendingEtxs types.PendingEtxs 188 // Look for pending ETXs first in pending ETX cache, then in database 189 if res, ok := hc.pendingEtxs.Get(hash); ok && res != nil { 190 pendingEtxs = res.(types.PendingEtxs) 191 } else if res := rawdb.ReadPendingEtxs(hc.headerDb, hash); res != nil { 192 pendingEtxs = *res 193 } else { 194 log.Trace("unable to find pending etxs for hash in manifest", "hash:", hash.String()) 195 return nil, ErrPendingEtxNotFound 196 } 197 return &pendingEtxs, nil 198 } 199 200 func (hc *HeaderChain) GetPendingEtxsRollup(hash common.Hash) (*types.PendingEtxsRollup, error) { 201 var rollups types.PendingEtxsRollup 202 // Look for pending ETXs first in pending ETX cache, then in database 203 if res, ok := hc.pendingEtxsRollup.Get(hash); ok && res != nil { 204 rollups = res.(types.PendingEtxsRollup) 205 } else if res := rawdb.ReadPendingEtxsRollup(hc.headerDb, hash); res != nil { 206 rollups = *res 207 } else { 208 log.Trace("unable to find pending etxs rollups for hash in manifest", "hash:", hash.String()) 209 return nil, ErrPendingEtxRollupNotFound 210 } 211 return &rollups, nil 212 } 213 214 // GetBloom gets the bloom from the cache or database 215 func (hc *HeaderChain) GetBloom(hash common.Hash) (*types.Bloom, error) { 216 var bloom types.Bloom 217 // Look for bloom first in bloom cache, then in database 218 if res, ok := hc.blooms.Get(hash); ok && res != nil { 219 bloom = res.(types.Bloom) 220 } else if res := rawdb.ReadBloom(hc.headerDb, hash); res != nil { 221 bloom = *res 222 } else { 223 log.Debug("unable to find bloom for hash in database", "hash:", hash.String()) 224 return nil, ErrBloomNotFound 225 } 226 return &bloom, nil 227 } 228 229 // Collect all emmitted ETXs since the last coincident block, but excluding 230 // those emitted in this block 231 func (hc *HeaderChain) CollectEtxRollup(b *types.Block) (types.Transactions, error) { 232 if b.NumberU64() == 0 && b.Hash() == hc.config.GenesisHash { 233 return b.ExtTransactions(), nil 234 } 235 parent := hc.GetBlock(b.ParentHash(), b.NumberU64()-1) 236 if parent == nil { 237 return nil, errors.New("parent not found") 238 } 239 return hc.collectInclusiveEtxRollup(parent) 240 } 241 242 func (hc *HeaderChain) collectInclusiveEtxRollup(b *types.Block) (types.Transactions, error) { 243 // Initialize the rollup with ETXs emitted by this block 244 newEtxs := b.ExtTransactions() 245 // Terminate the search if we reached genesis 246 if b.NumberU64() == 0 { 247 if b.Hash() != hc.config.GenesisHash { 248 return nil, fmt.Errorf("manifest builds on incorrect genesis, block0 hash: %s", b.Hash().String()) 249 } else { 250 return newEtxs, nil 251 } 252 } 253 // Terminate the search on coincidence with dom chain 254 if hc.engine.IsDomCoincident(hc, b.Header()) { 255 return newEtxs, nil 256 } 257 // Recursively get the ancestor rollup, until a coincident ancestor is found 258 ancestor := hc.GetBlock(b.ParentHash(), b.NumberU64()-1) 259 if ancestor == nil { 260 return nil, errors.New("ancestor not found") 261 } 262 etxRollup, err := hc.collectInclusiveEtxRollup(ancestor) 263 if err != nil { 264 return nil, err 265 } 266 etxRollup = append(etxRollup, newEtxs...) 267 return etxRollup, nil 268 } 269 270 // Append 271 func (hc *HeaderChain) AppendHeader(header *types.Header) error { 272 nodeCtx := common.NodeLocation.Context() 273 log.Debug("HeaderChain Append:", "Header information: Hash:", header.Hash(), "header header hash:", header.Hash(), "Number:", header.NumberU64(), "Location:", header.Location, "Parent:", header.ParentHash()) 274 275 err := hc.engine.VerifyHeader(hc, header) 276 if err != nil { 277 return err 278 } 279 280 // Verify the manifest matches expected 281 // Load the manifest of headers preceding this header 282 // note: prime manifest is non-existent, because a prime header cannot be 283 // coincident with a higher order chain. So, this check is skipped for prime 284 // nodes. 285 if nodeCtx > common.PRIME_CTX { 286 manifest := rawdb.ReadManifest(hc.headerDb, header.ParentHash()) 287 if manifest == nil { 288 return errors.New("manifest not found for parent") 289 } 290 if header.ManifestHash(nodeCtx) != types.DeriveSha(manifest, trie.NewStackTrie(nil)) { 291 return errors.New("manifest does not match hash") 292 } 293 } 294 295 return nil 296 } 297 func (hc *HeaderChain) ProcessingState() bool { 298 return hc.bc.ProcessingState() 299 } 300 301 // Append 302 func (hc *HeaderChain) AppendBlock(block *types.Block, newInboundEtxs types.Transactions) error { 303 blockappend := time.Now() 304 // Append block else revert header append 305 logs, err := hc.bc.Append(block, newInboundEtxs) 306 if err != nil { 307 return err 308 } 309 log.Debug("Time taken to", "Append in bc", common.PrettyDuration(time.Since(blockappend))) 310 311 hc.bc.chainFeed.Send(ChainEvent{Block: block, Hash: block.Hash(), Logs: logs}) 312 if len(logs) > 0 { 313 hc.bc.logsFeed.Send(logs) 314 } 315 316 return nil 317 } 318 319 // SetCurrentHeader sets the current header based on the POEM choice 320 func (hc *HeaderChain) SetCurrentHeader(head *types.Header) error { 321 hc.headermu.Lock() 322 defer hc.headermu.Unlock() 323 324 prevHeader := hc.CurrentHeader() 325 // if trying to set the same header, escape 326 if prevHeader.Hash() == head.Hash() { 327 return nil 328 } 329 330 // write the head block hash to the db 331 rawdb.WriteHeadBlockHash(hc.headerDb, head.Hash()) 332 log.Info("Setting the current header", "Hash", head.Hash(), "Number", head.NumberArray()) 333 hc.currentHeader.Store(head) 334 335 // If head is the normal extension of canonical head, we can return by just wiring the canonical hash. 336 if prevHeader.Hash() == head.ParentHash() { 337 rawdb.WriteCanonicalHash(hc.headerDb, head.Hash(), head.NumberU64()) 338 return nil 339 } 340 341 //Find a common header 342 commonHeader := hc.findCommonAncestor(head) 343 newHeader := types.CopyHeader(head) 344 345 // Delete each header and rollback state processor until common header 346 // Accumulate the hash slice stack 347 var hashStack []*types.Header 348 for { 349 if newHeader.Hash() == commonHeader.Hash() { 350 break 351 } 352 hashStack = append(hashStack, newHeader) 353 newHeader = hc.GetHeader(newHeader.ParentHash(), newHeader.NumberU64()-1) 354 355 // genesis check to not delete the genesis block 356 if newHeader.Hash() == hc.config.GenesisHash { 357 break 358 } 359 } 360 361 for { 362 if prevHeader.Hash() == commonHeader.Hash() { 363 break 364 } 365 rawdb.DeleteCanonicalHash(hc.headerDb, prevHeader.NumberU64()) 366 prevHeader = hc.GetHeader(prevHeader.ParentHash(), prevHeader.NumberU64()-1) 367 368 // genesis check to not delete the genesis block 369 if prevHeader.Hash() == hc.config.GenesisHash { 370 break 371 } 372 } 373 374 // Run through the hash stack to update canonicalHash and forward state processor 375 for i := len(hashStack) - 1; i >= 0; i-- { 376 rawdb.WriteCanonicalHash(hc.headerDb, hashStack[i].Hash(), hashStack[i].NumberU64()) 377 } 378 379 return nil 380 } 381 382 // SetCurrentHeader sets the in-memory head header marker of the canonical chan 383 // as the given header. 384 func (hc *HeaderChain) SetCurrentState(head *types.Header) error { 385 hc.headermu.Lock() 386 defer hc.headermu.Unlock() 387 388 nodeCtx := common.NodeLocation.Context() 389 if nodeCtx != common.ZONE_CTX || !hc.ProcessingState() { 390 return nil 391 } 392 393 current := types.CopyHeader(head) 394 var headersWithoutState []*types.Header 395 for { 396 headersWithoutState = append(headersWithoutState, current) 397 header := hc.GetHeader(current.ParentHash(), current.NumberU64()-1) 398 if header == nil { 399 return ErrSubNotSyncedToDom 400 } 401 // Checking of the Etx set exists makes sure that we have processed the 402 // state of the parent block 403 etxSet := rawdb.ReadEtxSet(hc.headerDb, header.Hash(), header.NumberU64()) 404 if etxSet != nil { 405 break 406 } 407 current = types.CopyHeader(header) 408 } 409 410 // Run through the hash stack to update canonicalHash and forward state processor 411 for i := len(headersWithoutState) - 1; i >= 0; i-- { 412 err := hc.ReadInboundEtxsAndAppendBlock(headersWithoutState[i]) 413 if err != nil { 414 return err 415 } 416 } 417 return nil 418 } 419 420 // ReadInboundEtxsAndAppendBlock reads the inbound etxs from database and appends the block 421 func (hc *HeaderChain) ReadInboundEtxsAndAppendBlock(header *types.Header) error { 422 block := hc.GetBlockOrCandidate(header.Hash(), header.NumberU64()) 423 if block == nil { 424 return errors.New("Could not find block during reorg") 425 } 426 _, order, err := hc.engine.CalcOrder(block.Header()) 427 if err != nil { 428 return err 429 } 430 nodeCtx := common.NodeLocation.Context() 431 var inboundEtxs types.Transactions 432 if order < nodeCtx { 433 inboundEtxs = rawdb.ReadInboundEtxs(hc.headerDb, header.Hash()) 434 } 435 return hc.AppendBlock(block, inboundEtxs) 436 } 437 438 // findCommonAncestor 439 func (hc *HeaderChain) findCommonAncestor(header *types.Header) *types.Header { 440 current := types.CopyHeader(header) 441 for { 442 if current == nil { 443 return nil 444 } 445 canonicalHash := rawdb.ReadCanonicalHash(hc.headerDb, current.NumberU64()) 446 if canonicalHash == current.Hash() { 447 return hc.GetHeaderByHash(canonicalHash) 448 } 449 current = hc.GetHeader(current.ParentHash(), current.NumberU64()-1) 450 } 451 452 } 453 454 func (hc *HeaderChain) AddPendingEtxs(pEtxs types.PendingEtxs) error { 455 if !pEtxs.IsValid(trie.NewStackTrie(nil)) { 456 log.Info("PendingEtx is not valid") 457 return ErrPendingEtxNotValid 458 } 459 log.Debug("Received pending ETXs", "block: ", pEtxs.Header.Hash()) 460 // Only write the pending ETXs if we have not seen them before 461 if !hc.pendingEtxs.Contains(pEtxs.Header.Hash()) { 462 // Write to pending ETX database 463 rawdb.WritePendingEtxs(hc.headerDb, pEtxs) 464 // Also write to cache for faster access 465 hc.pendingEtxs.Add(pEtxs.Header.Hash(), pEtxs) 466 } else { 467 return ErrPendingEtxAlreadyKnown 468 } 469 return nil 470 } 471 472 func (hc *HeaderChain) AddBloom(bloom types.Bloom, hash common.Hash) error { 473 // Only write the bloom if we have not seen it before 474 if !hc.blooms.Contains(hash) { 475 // Write to bloom database 476 rawdb.WriteBloom(hc.headerDb, hash, bloom) 477 // Also write to cache for faster access 478 hc.blooms.Add(hash, bloom) 479 } else { 480 return ErrBloomAlreadyKnown 481 } 482 return nil 483 } 484 485 // loadLastState loads the last known chain state from the database. This method 486 // assumes that the chain manager mutex is held. 487 func (hc *HeaderChain) loadLastState() error { 488 // TODO: create function to find highest block number and fill Head FIFO 489 headsHashes := rawdb.ReadHeadsHashes(hc.headerDb) 490 491 if head := rawdb.ReadHeadBlockHash(hc.headerDb); head != (common.Hash{}) { 492 if chead := hc.GetHeaderByHash(head); chead != nil { 493 hc.currentHeader.Store(chead) 494 } else { 495 // This is only done if during the stop, currenthead hash was not stored 496 // properly and it doesn't crash the nodes 497 hc.currentHeader.Store(hc.genesisHeader) 498 } 499 } else { 500 // Recover the current header 501 log.Warn("Recovering Current Header") 502 recoverdHeader := hc.RecoverCurrentHeader() 503 rawdb.WriteHeadBlockHash(hc.headerDb, recoverdHeader.Hash()) 504 hc.currentHeader.Store(recoverdHeader) 505 } 506 507 heads := make([]*types.Header, 0) 508 for _, hash := range headsHashes { 509 heads = append(heads, hc.GetHeaderByHash(hash)) 510 } 511 hc.heads = heads 512 513 return nil 514 } 515 516 // Stop stops the blockchain service. If any imports are currently in progress 517 // it will abort them using the procInterrupt. 518 func (hc *HeaderChain) Stop() { 519 if !atomic.CompareAndSwapInt32(&hc.running, 0, 1) { 520 return 521 } 522 523 hashes := make([]common.Hash, 0) 524 for i := 0; i < len(hc.heads); i++ { 525 hashes = append(hashes, hc.heads[i].Hash()) 526 } 527 // Save the heads 528 rawdb.WriteHeadsHashes(hc.headerDb, hashes) 529 530 // Unsubscribe all subscriptions registered from blockchain 531 hc.scope.Close() 532 hc.bc.scope.Close() 533 hc.wg.Wait() 534 if common.NodeLocation.Context() == common.ZONE_CTX && hc.ProcessingState() { 535 hc.bc.processor.Stop() 536 } 537 log.Info("headerchain stopped") 538 } 539 540 // Empty checks if the headerchain is empty. 541 func (hc *HeaderChain) Empty() bool { 542 genesis := hc.config.GenesisHash 543 for _, hash := range []common.Hash{rawdb.ReadHeadBlockHash(hc.headerDb)} { 544 if hash != genesis { 545 return false 546 } 547 } 548 return true 549 } 550 551 // GetBlockNumber retrieves the block number belonging to the given hash 552 // from the cache or database 553 func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 { 554 if cached, ok := hc.numberCache.Get(hash); ok { 555 number := cached.(uint64) 556 return &number 557 } 558 number := rawdb.ReadHeaderNumber(hc.headerDb, hash) 559 if number != nil { 560 hc.numberCache.Add(hash, *number) 561 } 562 return number 563 } 564 565 func (hc *HeaderChain) GetTerminiByHash(hash common.Hash) *types.Termini { 566 termini := rawdb.ReadTermini(hc.headerDb, hash) 567 return termini 568 } 569 570 // GetBlockHashesFromHash retrieves a number of block hashes starting at a given 571 // hash, fetching towards the genesis block. 572 func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { 573 // Get the origin header from which to fetch 574 header := hc.GetHeaderByHash(hash) 575 if header == nil { 576 return nil 577 } 578 // Iterate the headers until enough is collected or the genesis reached 579 chain := make([]common.Hash, 0, max) 580 for i := uint64(0); i < max; i++ { 581 next := header.ParentHash() 582 if header = hc.GetHeader(next, header.NumberU64()-1); header == nil { 583 break 584 } 585 chain = append(chain, next) 586 if header.Number().Sign() == 0 { 587 break 588 } 589 } 590 return chain 591 } 592 593 // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or 594 // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the 595 // number of blocks to be individually checked before we reach the canonical chain. 596 // 597 // Note: ancestor == 0 returns the same block, 1 returns its parent and so on. 598 func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { 599 if ancestor > number { 600 return common.Hash{}, 0 601 } 602 if ancestor == 1 { 603 // in this case it is cheaper to just read the header 604 if header := hc.GetHeader(hash, number); header != nil { 605 return header.ParentHash(), number - 1 606 } 607 return common.Hash{}, 0 608 } 609 for ancestor != 0 { 610 if rawdb.ReadCanonicalHash(hc.headerDb, number) == hash { 611 ancestorHash := rawdb.ReadCanonicalHash(hc.headerDb, number-ancestor) 612 if rawdb.ReadCanonicalHash(hc.headerDb, number) == hash { 613 number -= ancestor 614 return ancestorHash, number 615 } 616 } 617 if *maxNonCanonical == 0 { 618 return common.Hash{}, 0 619 } 620 *maxNonCanonical-- 621 ancestor-- 622 header := hc.GetHeader(hash, number) 623 if header == nil { 624 return common.Hash{}, 0 625 } 626 hash = header.ParentHash() 627 number-- 628 } 629 return hash, number 630 } 631 632 func (hc *HeaderChain) WriteBlock(block *types.Block) { 633 hc.bc.WriteBlock(block) 634 } 635 636 // GetHeader retrieves a block header from the database by hash and number, 637 // caching it if found. 638 func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header { 639 termini := hc.GetTerminiByHash(hash) 640 if termini == nil { 641 return nil 642 } 643 // Short circuit if the header's already in the cache, retrieve otherwise 644 if header, ok := hc.headerCache.Get(hash); ok { 645 return header.(*types.Header) 646 } 647 header := rawdb.ReadHeader(hc.headerDb, hash, number) 648 if header == nil { 649 return nil 650 } 651 // Cache the found header for next time and return 652 hc.headerCache.Add(hash, header) 653 return header 654 } 655 656 // GetHeaderByHash retrieves a block header from the database by hash, caching it if 657 // found. 658 func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header { 659 termini := hc.GetTerminiByHash(hash) 660 if termini == nil { 661 return nil 662 } 663 number := hc.GetBlockNumber(hash) 664 if number == nil { 665 return nil 666 } 667 668 return hc.GetHeader(hash, *number) 669 } 670 671 // GetHeaderOrCandidate retrieves a block header from the database by hash and number, 672 // caching it if found. 673 func (hc *HeaderChain) GetHeaderOrCandidate(hash common.Hash, number uint64) *types.Header { 674 // Short circuit if the header's already in the cache, retrieve otherwise 675 if header, ok := hc.headerCache.Get(hash); ok { 676 return header.(*types.Header) 677 } 678 header := rawdb.ReadHeader(hc.headerDb, hash, number) 679 if header == nil { 680 return nil 681 } 682 // Cache the found header for next time and return 683 hc.headerCache.Add(hash, header) 684 return header 685 } 686 687 // RecoverCurrentHeader retrieves the current head header of the canonical chain. The 688 // header is retrieved from the HeaderChain's internal cache 689 func (hc *HeaderChain) RecoverCurrentHeader() *types.Header { 690 // Start logarithmic ascent to find the upper bound 691 high := uint64(1) 692 for hc.GetHeaderByNumber(high) != nil { 693 high *= 2 694 } 695 // Run binary search to find the max header 696 low := high / 2 697 for low <= high { 698 mid := (low + high) / 2 699 if hc.GetHeaderByNumber(mid) != nil { 700 low = mid + 1 701 } else { 702 high = mid - 1 703 } 704 } 705 header := hc.GetHeaderByNumber(high) 706 log.Info("Header Recovered: ", "hash", header.Hash().String()) 707 708 return header 709 } 710 711 // GetHeaderOrCandidateByHash retrieves a block header from the database by hash, caching it if 712 // found. 713 func (hc *HeaderChain) GetHeaderOrCandidateByHash(hash common.Hash) *types.Header { 714 number := hc.GetBlockNumber(hash) 715 if number == nil { 716 return nil 717 } 718 719 return hc.GetHeaderOrCandidate(hash, *number) 720 } 721 722 // HasHeader checks if a block header is present in the database or not. 723 // In theory, if header is present in the database, all relative components 724 // like td and hash->number should be present too. 725 func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool { 726 if hc.numberCache.Contains(hash) || hc.headerCache.Contains(hash) { 727 return true 728 } 729 return rawdb.HasHeader(hc.headerDb, hash, number) 730 } 731 732 // GetHeaderByNumber retrieves a block header from the database by number, 733 // caching it (associated with its hash) if found. 734 func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header { 735 hash := rawdb.ReadCanonicalHash(hc.headerDb, number) 736 if hash == (common.Hash{}) { 737 return nil 738 } 739 return hc.GetHeader(hash, number) 740 } 741 742 func (hc *HeaderChain) GetCanonicalHash(number uint64) common.Hash { 743 hash := rawdb.ReadCanonicalHash(hc.headerDb, number) 744 return hash 745 } 746 747 // CurrentHeader retrieves the current head header of the canonical chain. The 748 // header is retrieved from the HeaderChain's internal cache. 749 func (hc *HeaderChain) CurrentHeader() *types.Header { 750 return hc.currentHeader.Load().(*types.Header) 751 } 752 753 // CurrentBlock returns the block for the current header. 754 func (hc *HeaderChain) CurrentBlock() *types.Block { 755 return hc.GetBlockOrCandidateByHash(hc.CurrentHeader().Hash()) 756 } 757 758 // SetGenesis sets a new genesis block header for the chain 759 func (hc *HeaderChain) SetGenesis(head *types.Header) { 760 hc.genesisHeader = head 761 } 762 763 // Config retrieves the header chain's chain configuration. 764 func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config } 765 766 // GetBlock implements consensus.ChainReader, and returns nil for every input as 767 // a header chain does not have blocks available for retrieval. 768 func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block { 769 return hc.bc.GetBlock(hash, number) 770 } 771 772 // CheckContext checks to make sure the range of a context or order is valid 773 func (hc *HeaderChain) CheckContext(context int) error { 774 if context < 0 || context > common.HierarchyDepth { 775 return errors.New("the provided path is outside the allowable range") 776 } 777 return nil 778 } 779 780 // CheckLocationRange checks to make sure the range of r and z are valid 781 func (hc *HeaderChain) CheckLocationRange(location []byte) error { 782 if int(location[0]) < 1 || int(location[0]) > common.NumRegionsInPrime { 783 return errors.New("the provided location is outside the allowable region range") 784 } 785 if int(location[1]) < 1 || int(location[1]) > common.NumZonesInRegion { 786 return errors.New("the provided location is outside the allowable zone range") 787 } 788 return nil 789 } 790 791 // GasLimit returns the gas limit of the current HEAD block. 792 func (hc *HeaderChain) GasLimit() uint64 { 793 return hc.CurrentHeader().GasLimit() 794 } 795 796 // GetUnclesInChain retrieves all the uncles from a given block backwards until 797 // a specific distance is reached. 798 func (hc *HeaderChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { 799 uncles := []*types.Header{} 800 for i := 0; block != nil && i < length; i++ { 801 uncles = append(uncles, block.Uncles()...) 802 block = hc.GetBlock(block.ParentHash(), block.NumberU64()-1) 803 } 804 return uncles 805 } 806 807 // GetGasUsedInChain retrieves all the gas used from a given block backwards until 808 // a specific distance is reached. 809 func (hc *HeaderChain) GetGasUsedInChain(block *types.Block, length int) int64 { 810 gasUsed := 0 811 for i := 0; block != nil && i < length; i++ { 812 gasUsed += int(block.GasUsed()) 813 block = hc.GetBlock(block.ParentHash(), block.NumberU64()-1) 814 } 815 return int64(gasUsed) 816 } 817 818 // GetGasUsedInChain retrieves all the gas used from a given block backwards until 819 // a specific distance is reached. 820 func (hc *HeaderChain) CalculateBaseFee(header *types.Header) *big.Int { 821 return misc.CalcBaseFee(hc.Config(), header) 822 } 823 824 // Export writes the active chain to the given writer. 825 func (hc *HeaderChain) Export(w io.Writer) error { 826 return hc.ExportN(w, uint64(0), hc.CurrentHeader().NumberU64()) 827 } 828 829 // ExportN writes a subset of the active chain to the given writer. 830 func (hc *HeaderChain) ExportN(w io.Writer, first uint64, last uint64) error { 831 hc.headermu.RLock() 832 defer hc.headermu.RUnlock() 833 834 if first > last { 835 return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) 836 } 837 log.Info("Exporting batch of blocks", "count", last-first+1) 838 839 start, reported := time.Now(), time.Now() 840 for nr := first; nr <= last; nr++ { 841 block := hc.GetBlockByNumber(nr) 842 if block == nil { 843 return fmt.Errorf("export failed on #%d: not found", nr) 844 } 845 if err := block.EncodeRLP(w); err != nil { 846 return err 847 } 848 if time.Since(reported) >= statsReportLimit { 849 log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start))) 850 reported = time.Now() 851 } 852 } 853 return nil 854 } 855 856 // GetBlockFromCacheOrDb looks up the body cache first and then checks the db 857 func (hc *HeaderChain) GetBlockFromCacheOrDb(hash common.Hash, number uint64) *types.Block { 858 // Short circuit if the block's already in the cache, retrieve otherwise 859 if cached, ok := hc.bc.blockCache.Get(hash); ok { 860 block := cached.(*types.Block) 861 return block 862 } 863 return hc.GetBlock(hash, number) 864 } 865 866 // GetBlockByHash retrieves a block from the database by hash, caching it if found. 867 func (hc *HeaderChain) GetBlockByHash(hash common.Hash) *types.Block { 868 number := hc.GetBlockNumber(hash) 869 if number == nil { 870 return nil 871 } 872 return hc.GetBlock(hash, *number) 873 } 874 875 func (hc *HeaderChain) GetBlockOrCandidate(hash common.Hash, number uint64) *types.Block { 876 return hc.bc.GetBlockOrCandidate(hash, number) 877 } 878 879 // GetBlockOrCandidateByHash retrieves any block from the database by hash, caching it if found. 880 func (hc *HeaderChain) GetBlockOrCandidateByHash(hash common.Hash) *types.Block { 881 number := hc.GetBlockNumber(hash) 882 if number == nil { 883 return nil 884 } 885 return hc.bc.GetBlockOrCandidate(hash, *number) 886 } 887 888 // GetBlockByNumber retrieves a block from the database by number, caching it 889 // (associated with its hash) if found. 890 func (hc *HeaderChain) GetBlockByNumber(number uint64) *types.Block { 891 hash := rawdb.ReadCanonicalHash(hc.headerDb, number) 892 if hash == (common.Hash{}) { 893 return nil 894 } 895 return hc.GetBlock(hash, number) 896 } 897 898 // GetBody retrieves a block body (transactions and uncles) from the database by 899 // hash, caching it if found. 900 func (hc *HeaderChain) GetBody(hash common.Hash) *types.Body { 901 // Short circuit if the body's already in the cache, retrieve otherwise 902 if cached, ok := hc.bc.bodyCache.Get(hash); ok { 903 body := cached.(*types.Body) 904 return body 905 } 906 number := hc.GetBlockNumber(hash) 907 if number == nil { 908 return nil 909 } 910 body := rawdb.ReadBody(hc.headerDb, hash, *number) 911 if body == nil { 912 return nil 913 } 914 // Cache the found body for next time and return 915 hc.bc.bodyCache.Add(hash, body) 916 return body 917 } 918 919 // GetBodyRLP retrieves a block body in RLP encoding from the database by hash, 920 // caching it if found. 921 func (hc *HeaderChain) GetBodyRLP(hash common.Hash) rlp.RawValue { 922 // Short circuit if the body's already in the cache, retrieve otherwise 923 if cached, ok := hc.bc.bodyRLPCache.Get(hash); ok { 924 return cached.(rlp.RawValue) 925 } 926 number := hc.GetBlockNumber(hash) 927 if number == nil { 928 return nil 929 } 930 body := rawdb.ReadBodyRLP(hc.headerDb, hash, *number) 931 if len(body) == 0 { 932 return nil 933 } 934 // Cache the found body for next time and return 935 hc.bc.bodyRLPCache.Add(hash, body) 936 return body 937 } 938 939 // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. 940 // [deprecated by eth/62] 941 func (hc *HeaderChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { 942 number := hc.GetBlockNumber(hash) 943 if number == nil { 944 return nil 945 } 946 for i := 0; i < n; i++ { 947 block := hc.GetBlock(hash, *number) 948 if block == nil { 949 break 950 } 951 blocks = append(blocks, block) 952 hash = block.ParentHash() 953 *number-- 954 } 955 return 956 } 957 958 // Engine reterives the consensus engine. 959 func (hc *HeaderChain) Engine() consensus.Engine { 960 return hc.engine 961 } 962 963 // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. 964 func (hc *HeaderChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 965 return hc.scope.Track(hc.chainHeadFeed.Subscribe(ch)) 966 } 967 968 // SubscribeChainSideEvent registers a subscription of ChainSideEvent. 969 func (hc *HeaderChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription { 970 return hc.scope.Track(hc.chainSideFeed.Subscribe(ch)) 971 } 972 973 func (hc *HeaderChain) StateAt(root common.Hash) (*state.StateDB, error) { 974 return hc.bc.processor.StateAt(root) 975 }