forked from cerc-io/plugeth
core/state/snapshot: check difflayer staleness early (#27255)
This PR adds a staleness-check to AccountRLP, before checking the bloom-filter and potentially going directly into the disklayer. --------- Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
This commit is contained in:
parent
d46f69dc7a
commit
eb83e7c540
@ -292,9 +292,14 @@ func (dl *diffLayer) Account(hash common.Hash) (*Account, error) {
|
|||||||
//
|
//
|
||||||
// Note the returned account is not a copy, please don't modify it.
|
// Note the returned account is not a copy, please don't modify it.
|
||||||
func (dl *diffLayer) AccountRLP(hash common.Hash) ([]byte, error) {
|
func (dl *diffLayer) AccountRLP(hash common.Hash) ([]byte, error) {
|
||||||
|
dl.lock.RLock()
|
||||||
|
// Check staleness before reaching further.
|
||||||
|
if dl.Stale() {
|
||||||
|
dl.lock.RUnlock()
|
||||||
|
return nil, ErrSnapshotStale
|
||||||
|
}
|
||||||
// Check the bloom filter first whether there's even a point in reaching into
|
// Check the bloom filter first whether there's even a point in reaching into
|
||||||
// all the maps in all the layers below
|
// all the maps in all the layers below
|
||||||
dl.lock.RLock()
|
|
||||||
hit := dl.diffed.Contains(accountBloomHasher(hash))
|
hit := dl.diffed.Contains(accountBloomHasher(hash))
|
||||||
if !hit {
|
if !hit {
|
||||||
hit = dl.diffed.Contains(destructBloomHasher(hash))
|
hit = dl.diffed.Contains(destructBloomHasher(hash))
|
||||||
@ -361,6 +366,11 @@ func (dl *diffLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
|
|||||||
// Check the bloom filter first whether there's even a point in reaching into
|
// Check the bloom filter first whether there's even a point in reaching into
|
||||||
// all the maps in all the layers below
|
// all the maps in all the layers below
|
||||||
dl.lock.RLock()
|
dl.lock.RLock()
|
||||||
|
// Check staleness before reaching further.
|
||||||
|
if dl.Stale() {
|
||||||
|
dl.lock.RUnlock()
|
||||||
|
return nil, ErrSnapshotStale
|
||||||
|
}
|
||||||
hit := dl.diffed.Contains(storageBloomHasher{accountHash, storageHash})
|
hit := dl.diffed.Contains(storageBloomHasher{accountHash, storageHash})
|
||||||
if !hit {
|
if !hit {
|
||||||
hit = dl.diffed.Contains(destructBloomHasher(accountHash))
|
hit = dl.diffed.Contains(destructBloomHasher(accountHash))
|
||||||
|
@ -185,6 +185,10 @@ func TestDiskLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
|||||||
// be returned with junk data. This version of the test retains the bottom diff
|
// be returned with junk data. This version of the test retains the bottom diff
|
||||||
// layer to check the usual mode of operation where the accumulator is retained.
|
// layer to check the usual mode of operation where the accumulator is retained.
|
||||||
func TestDiffLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
func TestDiffLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
||||||
|
// Un-commenting this triggers the bloom set to be deterministic. The values below
|
||||||
|
// were used to trigger the flaw described in https://github.com/ethereum/go-ethereum/issues/27254.
|
||||||
|
// bloomDestructHasherOffset, bloomAccountHasherOffset, bloomStorageHasherOffset = 14, 24, 5
|
||||||
|
|
||||||
// Create an empty base layer and a snapshot tree out of it
|
// Create an empty base layer and a snapshot tree out of it
|
||||||
base := &diskLayer{
|
base := &diskLayer{
|
||||||
diskdb: rawdb.NewMemoryDatabase(),
|
diskdb: rawdb.NewMemoryDatabase(),
|
||||||
|
Loading…
Reference in New Issue
Block a user