core/state/snapshot: node behavioural difference on bloom content
This commit is contained in:
parent
fd39f722a3
commit
3ad4335acc
@ -20,6 +20,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -63,8 +64,20 @@ var (
|
|||||||
// bloom filter to keep its size to a minimum (given it's size and maximum
|
// bloom filter to keep its size to a minimum (given it's size and maximum
|
||||||
// entry count).
|
// entry count).
|
||||||
bloomFuncs = math.Round((bloomSize / float64(aggregatorItemLimit)) * math.Log(2))
|
bloomFuncs = math.Round((bloomSize / float64(aggregatorItemLimit)) * math.Log(2))
|
||||||
|
|
||||||
|
// bloomHashesOffset is a runtime constant which determines which part of the
|
||||||
|
// the account/storage hash the hasher functions looks at, to determine the
|
||||||
|
// bloom key for an account/slot. This is randomized at init(), so that the
|
||||||
|
// global population of nodes do not all display the exact same behaviour with
|
||||||
|
// regards to bloom content
|
||||||
|
bloomHasherOffset = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Init bloomHasherOffset in the range [0:24] (requires 8 bytes)
|
||||||
|
bloomHasherOffset = rand.Intn(25)
|
||||||
|
}
|
||||||
|
|
||||||
// diffLayer represents a collection of modifications made to a state snapshot
|
// diffLayer represents a collection of modifications made to a state snapshot
|
||||||
// after running a block on top. It contains one sorted list for the account trie
|
// after running a block on top. It contains one sorted list for the account trie
|
||||||
// and one-one list for each storage tries.
|
// and one-one list for each storage tries.
|
||||||
@ -100,7 +113,7 @@ func (h accountBloomHasher) Reset() { panic("not impl
|
|||||||
func (h accountBloomHasher) BlockSize() int { panic("not implemented") }
|
func (h accountBloomHasher) BlockSize() int { panic("not implemented") }
|
||||||
func (h accountBloomHasher) Size() int { return 8 }
|
func (h accountBloomHasher) Size() int { return 8 }
|
||||||
func (h accountBloomHasher) Sum64() uint64 {
|
func (h accountBloomHasher) Sum64() uint64 {
|
||||||
return binary.BigEndian.Uint64(h[:8])
|
return binary.BigEndian.Uint64(h[bloomHasherOffset : bloomHasherOffset+8])
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageBloomHasher is a wrapper around a [2]common.Hash to satisfy the interface
|
// storageBloomHasher is a wrapper around a [2]common.Hash to satisfy the interface
|
||||||
@ -114,7 +127,8 @@ func (h storageBloomHasher) Reset() { panic("not impl
|
|||||||
func (h storageBloomHasher) BlockSize() int { panic("not implemented") }
|
func (h storageBloomHasher) BlockSize() int { panic("not implemented") }
|
||||||
func (h storageBloomHasher) Size() int { return 8 }
|
func (h storageBloomHasher) Size() int { return 8 }
|
||||||
func (h storageBloomHasher) Sum64() uint64 {
|
func (h storageBloomHasher) Sum64() uint64 {
|
||||||
return binary.BigEndian.Uint64(h[0][:8]) ^ binary.BigEndian.Uint64(h[1][:8])
|
return binary.BigEndian.Uint64(h[0][bloomHasherOffset:bloomHasherOffset+8]) ^
|
||||||
|
binary.BigEndian.Uint64(h[1][bloomHasherOffset:bloomHasherOffset+8])
|
||||||
}
|
}
|
||||||
|
|
||||||
// newDiffLayer creates a new diff on top of an existing snapshot, whether that's a low
|
// newDiffLayer creates a new diff on top of an existing snapshot, whether that's a low
|
||||||
@ -205,7 +219,6 @@ func (dl *diffLayer) rebloom(origin *diskLayer) {
|
|||||||
k := float64(dl.diffed.K())
|
k := float64(dl.diffed.K())
|
||||||
n := float64(dl.diffed.N())
|
n := float64(dl.diffed.N())
|
||||||
m := float64(dl.diffed.M())
|
m := float64(dl.diffed.M())
|
||||||
|
|
||||||
snapshotBloomErrorGauge.Update(math.Pow(1.0-math.Exp((-k)*(n+0.5)/(m-1)), k))
|
snapshotBloomErrorGauge.Update(math.Pow(1.0-math.Exp((-k)*(n+0.5)/(m-1)), k))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
"github.com/VictoriaMetrics/fastcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
@ -216,7 +217,7 @@ func BenchmarkSearch(b *testing.B) {
|
|||||||
layer = fill(layer)
|
layer = fill(layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
key := common.Hash{}
|
key := crypto.Keccak256Hash([]byte{0x13, 0x38})
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
layer.AccountRLP(key)
|
layer.AccountRLP(key)
|
||||||
@ -229,10 +230,12 @@ func BenchmarkSearch(b *testing.B) {
|
|||||||
// BenchmarkSearchSlot-6 100000 14554 ns/op
|
// BenchmarkSearchSlot-6 100000 14554 ns/op
|
||||||
// BenchmarkSearchSlot-6 100000 22254 ns/op (when checking parent root using mutex)
|
// BenchmarkSearchSlot-6 100000 22254 ns/op (when checking parent root using mutex)
|
||||||
// BenchmarkSearchSlot-6 100000 14551 ns/op (when checking parent number using atomic)
|
// BenchmarkSearchSlot-6 100000 14551 ns/op (when checking parent number using atomic)
|
||||||
|
// With bloom filter:
|
||||||
|
// BenchmarkSearchSlot-6 3467835 351 ns/op
|
||||||
func BenchmarkSearchSlot(b *testing.B) {
|
func BenchmarkSearchSlot(b *testing.B) {
|
||||||
// First, we set up 128 diff layers, with 1K items each
|
// First, we set up 128 diff layers, with 1K items each
|
||||||
accountKey := common.Hash{}
|
accountKey := crypto.Keccak256Hash([]byte{0x13, 0x37})
|
||||||
storageKey := common.HexToHash("0x1337")
|
storageKey := crypto.Keccak256Hash([]byte{0x13, 0x37})
|
||||||
accountRLP := randomAccount()
|
accountRLP := randomAccount()
|
||||||
fill := func(parent snapshot) *diffLayer {
|
fill := func(parent snapshot) *diffLayer {
|
||||||
accounts := make(map[common.Hash][]byte)
|
accounts := make(map[common.Hash][]byte)
|
||||||
|
Loading…
Reference in New Issue
Block a user