diff options
author | Felföldi Zsolt <zsfelfoldi@gmail.com> | 2018-06-12 21:52:54 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2018-06-12 21:52:54 +0800 |
commit | 049f5b357200406c01f7bf2d2e2936d1d28a319b (patch) | |
tree | ef73043730c3d77359b9163ab6cbb2f053e5cf86 /les | |
parent | 0255951587ef0eada5d162f3404bc481f70a2ce2 (diff) | |
download | dexon-049f5b357200406c01f7bf2d2e2936d1d28a319b.tar.gz dexon-049f5b357200406c01f7bf2d2e2936d1d28a319b.tar.zst dexon-049f5b357200406c01f7bf2d2e2936d1d28a319b.zip |
core, eth, les: more efficient hash-based header chain retrieval (#16946)
Diffstat (limited to 'les')
-rw-r--r-- | les/handler.go | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/les/handler.go b/les/handler.go index 38f810d72..a1c16cb87 100644 --- a/les/handler.go +++ b/les/handler.go @@ -83,7 +83,7 @@ type BlockChain interface { InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) Rollback(chain []common.Hash) GetHeaderByNumber(number uint64) *types.Header - GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash + GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) Genesis() *types.Block SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription } @@ -419,6 +419,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } hashMode := query.Origin.Hash != (common.Hash{}) + first := true + maxNonCanonical := uint64(100) // Gather headers until the fetch or network limits is reached var ( @@ -430,14 +432,21 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { // Retrieve the next header satisfying the query var origin *types.Header if hashMode { - origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash) + if first { + first = false + origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash) + if origin != nil { + query.Origin.Number = origin.Number.Uint64() + } + } else { + origin = pm.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number) + } } else { origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number) } if origin == nil { break } - number := origin.Number.Uint64() headers = append(headers, origin) bytes += estHeaderRlpSize @@ -445,14 +454,12 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { switch { case hashMode && query.Reverse: // Hash based traversal towards the genesis block - for i := 0; i < int(query.Skip)+1; i++ { - if header := pm.blockchain.GetHeader(query.Origin.Hash, number); header != nil { - query.Origin.Hash = header.ParentHash - number-- - } else { - unknown = true - break - } + ancestor := query.Skip + 1 + if ancestor == 0 { + unknown = true + } else { + query.Origin.Hash, query.Origin.Number = pm.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical) + unknown = (query.Origin.Hash == common.Hash{}) } case hashMode && !query.Reverse: // Hash based traversal towards the leaf block @@ -466,8 +473,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { unknown = true } else { if header := pm.blockchain.GetHeaderByNumber(next); header != nil { - if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash { - query.Origin.Hash = header.Hash() + nextHash := header.Hash() + expOldHash, _ := pm.blockchain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical) + if expOldHash == query.Origin.Hash { + query.Origin.Hash, query.Origin.Number = nextHash, next } else { unknown = true } |