mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
eth,les: add hash-lookup that is easier on memory
This commit is contained in:
parent
400332b99d
commit
319c8d044c
6 changed files with 41 additions and 2 deletions
|
|
@ -1523,6 +1523,12 @@ func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []com
|
||||||
return bc.hc.GetBlockHashesFromHash(hash, max)
|
return bc.hc.GetBlockHashesFromHash(hash, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAncestorBlockHashFromHash retrieves the block hash for the ancestor of a given
|
||||||
|
// hash, fetching towards the genesis block.
|
||||||
|
func (bc *BlockChain) GetAncestorBlockHashFromHash(hash common.Hash, max uint64) common.Hash {
|
||||||
|
return bc.hc.GetAncestorBlockHashFromHash(hash, max)
|
||||||
|
}
|
||||||
|
|
||||||
// GetHeaderByNumber retrieves a block header from the database by number,
|
// GetHeaderByNumber retrieves a block header from the database by number,
|
||||||
// caching it (associated with its hash) if found.
|
// caching it (associated with its hash) if found.
|
||||||
func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,27 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co
|
||||||
return chain
|
return chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAncestorBlockHashFromHash retrieves the block hash for the ancestor of a given
|
||||||
|
// hash, fetching towards the genesis block.
|
||||||
|
func (hc *HeaderChain) GetAncestorBlockHashFromHash(hash common.Hash, max uint64) common.Hash {
|
||||||
|
// Get the origin header from which to fetch
|
||||||
|
header := hc.GetHeaderByHash(hash)
|
||||||
|
if header == nil {
|
||||||
|
return common.Hash{}
|
||||||
|
}
|
||||||
|
// Iterate the headers until enough is collected or the genesis reached
|
||||||
|
next := common.Hash{}
|
||||||
|
for i := uint64(0); i < max; i++ {
|
||||||
|
next = header.ParentHash
|
||||||
|
if header = hc.GetHeader(next, header.Number.Uint64()-1); header == nil {
|
||||||
|
return common.Hash{}
|
||||||
|
}
|
||||||
|
if header.Number.Sign() == 0 {
|
||||||
|
return common.Hash{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return next
|
||||||
|
}
|
||||||
// GetTd retrieves a block's total difficulty in the canonical chain from the
|
// GetTd retrieves a block's total difficulty in the canonical chain from the
|
||||||
// database by hash and number, caching it if found.
|
// database by hash and number, caching it if found.
|
||||||
func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
|
func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
|
||||||
|
|
|
||||||
|
|
@ -387,7 +387,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
unknown = true
|
unknown = true
|
||||||
} else {
|
} else {
|
||||||
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
||||||
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
|
if pm.blockchain.GetAncestorBlockHashFromHash(header.Hash(), query.Skip+1) == query.Origin.Hash {
|
||||||
query.Origin.Hash = header.Hash()
|
query.Origin.Hash = header.Hash()
|
||||||
} else {
|
} else {
|
||||||
unknown = true
|
unknown = true
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ type BlockChain interface {
|
||||||
Rollback(chain []common.Hash)
|
Rollback(chain []common.Hash)
|
||||||
GetHeaderByNumber(number uint64) *types.Header
|
GetHeaderByNumber(number uint64) *types.Header
|
||||||
GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash
|
GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash
|
||||||
|
GetAncestorBlockHashFromHash(hash common.Hash, max uint64) common.Hash
|
||||||
Genesis() *types.Block
|
Genesis() *types.Block
|
||||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||||
}
|
}
|
||||||
|
|
@ -465,7 +466,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
unknown = true
|
unknown = true
|
||||||
} else {
|
} else {
|
||||||
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
||||||
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
|
if pm.blockchain.GetAncestorBlockHashFromHash(header.Hash(), query.Skip+1) == query.Origin.Hash {
|
||||||
query.Origin.Hash = header.Hash()
|
query.Origin.Hash = header.Hash()
|
||||||
} else {
|
} else {
|
||||||
unknown = true
|
unknown = true
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,11 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 1},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 1},
|
||||||
[]common.Hash{bc.GetBlockByNumber(limit / 2).Hash()},
|
[]common.Hash{bc.GetBlockByNumber(limit / 2).Hash()},
|
||||||
},
|
},
|
||||||
|
// Overflow attack
|
||||||
|
{
|
||||||
|
&getBlockHeadersData{Origin: hashOrNumber{Hash:bc.GetBlockByNumber(1).Hash()}, Amount: 1,Skip:0xFFFFFFFFFFFFFFFF},
|
||||||
|
[]common.Hash{},
|
||||||
|
},
|
||||||
// Multiple headers should be retrievable in both directions
|
// Multiple headers should be retrievable in both directions
|
||||||
{
|
{
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3},
|
||||||
|
|
|
||||||
|
|
@ -433,6 +433,12 @@ func (self *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []c
|
||||||
return self.hc.GetBlockHashesFromHash(hash, max)
|
return self.hc.GetBlockHashesFromHash(hash, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAncestorBlockHashFromHash retrieves the block hash for the ancestor of a given
|
||||||
|
// hash, fetching towards the genesis block.
|
||||||
|
func (self *LightChain) GetAncestorBlockHashFromHash(hash common.Hash, max uint64) common.Hash{
|
||||||
|
return self.hc.GetAncestorBlockHashFromHash(hash, max)
|
||||||
|
}
|
||||||
|
|
||||||
// GetHeaderByNumber retrieves a block header from the database by number,
|
// GetHeaderByNumber retrieves a block header from the database by number,
|
||||||
// caching it (associated with its hash) if found.
|
// caching it (associated with its hash) if found.
|
||||||
func (self *LightChain) GetHeaderByNumber(number uint64) *types.Header {
|
func (self *LightChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue