GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the number of blocks to be individually checked before we reach the canonical chain. Note: ancestor == 0 ret
(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64)
| 308 | // |
| 309 | // Note: ancestor == 0 returns the same block, 1 returns its parent and so on. |
| 310 | func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { |
| 311 | if ancestor > number { |
| 312 | return common.Hash{}, 0 |
| 313 | } |
| 314 | if ancestor == 1 { |
| 315 | // in this case it is cheaper to just read the header |
| 316 | if header := hc.GetHeader(hash, number); header != nil { |
| 317 | return header.ParentHash, number - 1 |
| 318 | } else { |
| 319 | return common.Hash{}, 0 |
| 320 | } |
| 321 | } |
| 322 | for ancestor != 0 { |
| 323 | if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash { |
| 324 | number -= ancestor |
| 325 | return rawdb.ReadCanonicalHash(hc.chainDb, number), number |
| 326 | } |
| 327 | if *maxNonCanonical == 0 { |
| 328 | return common.Hash{}, 0 |
| 329 | } |
| 330 | *maxNonCanonical-- |
| 331 | ancestor-- |
| 332 | header := hc.GetHeader(hash, number) |
| 333 | if header == nil { |
| 334 | return common.Hash{}, 0 |
| 335 | } |
| 336 | hash = header.ParentHash |
| 337 | number-- |
| 338 | } |
| 339 | return hash, number |
| 340 | } |
| 341 | |
| 342 | // GetHeader retrieves a block header from the database by hash and number, |
| 343 | // caching it if found. |