mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
eth/protocols/eth: use bloomfilter instead of set
This commit is contained in:
parent
b95c7220c7
commit
970737198a
4 changed files with 81 additions and 111 deletions
|
|
@ -85,7 +85,7 @@ func (e *ExpiringBloom) Stop() {
|
||||||
close(e.closeCh)
|
close(e.closeCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ExpiringBloom) Put(key hash.Hash64) {
|
func (e *ExpiringBloom) Add(key hash.Hash64) {
|
||||||
e.mu.RLock()
|
e.mu.RLock()
|
||||||
defer e.mu.RUnlock()
|
defer e.mu.RUnlock()
|
||||||
|
|
||||||
|
|
@ -93,7 +93,7 @@ func (e *ExpiringBloom) Put(key hash.Hash64) {
|
||||||
e.union.Add(key)
|
e.union.Add(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ExpiringBloom) Contain(key hash.Hash64) bool {
|
func (e *ExpiringBloom) Contains(key hash.Hash64) bool {
|
||||||
e.mu.RLock()
|
e.mu.RLock()
|
||||||
defer e.mu.RUnlock()
|
defer e.mu.RUnlock()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,20 +39,20 @@ func TestBloom(t *testing.T) {
|
||||||
bloom, _ := NewExpiringBloom(3, 1024, 10*time.Millisecond)
|
bloom, _ := NewExpiringBloom(3, 1024, 10*time.Millisecond)
|
||||||
|
|
||||||
testKey := hashable{[]byte{0x01}}
|
testKey := hashable{[]byte{0x01}}
|
||||||
bloom.Put(testKey)
|
bloom.Add(testKey)
|
||||||
if !bloom.Contain(testKey) {
|
if !bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
time.Sleep(11 * time.Millisecond)
|
time.Sleep(11 * time.Millisecond)
|
||||||
if !bloom.Contain(testKey) {
|
if !bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
time.Sleep(11 * time.Millisecond)
|
time.Sleep(11 * time.Millisecond)
|
||||||
if !bloom.Contain(testKey) {
|
if !bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
time.Sleep(11 * time.Millisecond)
|
time.Sleep(11 * time.Millisecond)
|
||||||
if bloom.Contain(testKey) {
|
if bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -61,34 +61,34 @@ func TestBloom2(t *testing.T) {
|
||||||
bloom, _ := NewExpiringBloom(3, 1024, 10*time.Second)
|
bloom, _ := NewExpiringBloom(3, 1024, 10*time.Second)
|
||||||
|
|
||||||
testKey := hashable{[]byte{0x01}}
|
testKey := hashable{[]byte{0x01}}
|
||||||
// Put key in bloom 0
|
// Add key in bloom 0
|
||||||
bloom.Put(testKey)
|
bloom.Add(testKey)
|
||||||
if !bloom.Contain(testKey) {
|
if !bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
// Override bloom 1
|
// Override bloom 1
|
||||||
bloom.tick()
|
bloom.tick()
|
||||||
if !bloom.Contain(testKey) {
|
if !bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
// Override bloom 2
|
// Override bloom 2
|
||||||
bloom.tick()
|
bloom.tick()
|
||||||
if !bloom.Contain(testKey) {
|
if !bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
// Override bloom 0
|
// Override bloom 0
|
||||||
bloom.tick()
|
bloom.tick()
|
||||||
if bloom.Contain(testKey) {
|
if bloom.Contains(testKey) {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPut(b *testing.B) {
|
func BenchmarkAdd(b *testing.B) {
|
||||||
bloom, _ := NewExpiringBloom(2, 1024, 10*time.Second)
|
bloom, _ := NewExpiringBloom(2, 1024, 10*time.Second)
|
||||||
|
|
||||||
testKey := hashable{[]byte{0x01}}
|
testKey := hashable{[]byte{0x01}}
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
bloom.Put(testKey)
|
bloom.Add(testKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,25 +17,27 @@
|
||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
mapset "github.com/deckarep/golang-set/v2"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
bloom "github.com/ethereum/go-ethereum/common/expbloom"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// maxKnownTxs is the maximum transactions hashes to keep in the known list
|
// transactionEvictionInterval specifies the interval in which a previously recorded
|
||||||
// before starting to randomly evict them.
|
// transaction hash is forgotten.
|
||||||
maxKnownTxs = 32768
|
transactionEvictionInterval = 10 * time.Minute
|
||||||
|
|
||||||
// maxKnownBlocks is the maximum block hashes to keep in the known list
|
// blockEvictionInterval specifies the interval in which a previously recorded
|
||||||
// before starting to randomly evict them.
|
// block hash is forgotten.
|
||||||
maxKnownBlocks = 1024
|
blockEvictionInterval = 10 * time.Minute
|
||||||
|
|
||||||
// maxQueuedTxs is the maximum number of transactions to queue up before dropping
|
// maxQueuedTxs is the maximum number of transactions to queue up before dropping
|
||||||
// older broadcasts.
|
// older broadcasts.
|
||||||
|
|
@ -75,14 +77,14 @@ type Peer struct {
|
||||||
head common.Hash // Latest advertised head block hash
|
head common.Hash // Latest advertised head block hash
|
||||||
td *big.Int // Latest advertised head block total difficulty
|
td *big.Int // Latest advertised head block total difficulty
|
||||||
|
|
||||||
knownBlocks *knownCache // Set of block hashes known to be known by this peer
|
knownBlocks *bloom.ExpiringBloom // Set of block hashes known to be known by this peer
|
||||||
queuedBlocks chan *blockPropagation // Queue of blocks to broadcast to the peer
|
queuedBlocks chan *blockPropagation // Queue of blocks to broadcast to the peer
|
||||||
queuedBlockAnns chan *types.Block // Queue of blocks to announce to the peer
|
queuedBlockAnns chan *types.Block // Queue of blocks to announce to the peer
|
||||||
|
|
||||||
txpool TxPool // Transaction pool used by the broadcasters for liveness checks
|
txpool TxPool // Transaction pool used by the broadcasters for liveness checks
|
||||||
knownTxs *knownCache // Set of transaction hashes known to be known by this peer
|
knownTxs *bloom.ExpiringBloom // Set of transaction hashes known to be known by this peer
|
||||||
txBroadcast chan []common.Hash // Channel used to queue transaction propagation requests
|
txBroadcast chan []common.Hash // Channel used to queue transaction propagation requests
|
||||||
txAnnounce chan []common.Hash // Channel used to queue transaction announcement requests
|
txAnnounce chan []common.Hash // Channel used to queue transaction announcement requests
|
||||||
|
|
||||||
reqDispatch chan *request // Dispatch channel to send requests and track then until fulfilment
|
reqDispatch chan *request // Dispatch channel to send requests and track then until fulfilment
|
||||||
reqCancel chan *cancel // Dispatch channel to cancel pending requests and untrack them
|
reqCancel chan *cancel // Dispatch channel to cancel pending requests and untrack them
|
||||||
|
|
@ -95,13 +97,17 @@ type Peer struct {
|
||||||
// NewPeer create a wrapper for a network connection and negotiated protocol
|
// NewPeer create a wrapper for a network connection and negotiated protocol
|
||||||
// version.
|
// version.
|
||||||
func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Peer {
|
func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Peer {
|
||||||
|
// https://hur.st/bloomfilter/?n=32768&p=1.0E-2&m=&k=4
|
||||||
|
txBloom, _ := bloom.NewExpiringBloom(10, 42*1024, transactionEvictionInterval/10)
|
||||||
|
// https://hur.st/bloomfilter/?n=1024&p=1.0E-2&m=&k=4
|
||||||
|
blockBloom, _ := bloom.NewExpiringBloom(10, 2*1024, 5*time.Minute)
|
||||||
peer := &Peer{
|
peer := &Peer{
|
||||||
id: p.ID().String(),
|
id: p.ID().String(),
|
||||||
Peer: p,
|
Peer: p,
|
||||||
rw: rw,
|
rw: rw,
|
||||||
version: version,
|
version: version,
|
||||||
knownTxs: newKnownCache(maxKnownTxs),
|
knownTxs: txBloom,
|
||||||
knownBlocks: newKnownCache(maxKnownBlocks),
|
knownBlocks: blockBloom,
|
||||||
queuedBlocks: make(chan *blockPropagation, maxQueuedBlocks),
|
queuedBlocks: make(chan *blockPropagation, maxQueuedBlocks),
|
||||||
queuedBlockAnns: make(chan *types.Block, maxQueuedBlockAnns),
|
queuedBlockAnns: make(chan *types.Block, maxQueuedBlockAnns),
|
||||||
txBroadcast: make(chan []common.Hash),
|
txBroadcast: make(chan []common.Hash),
|
||||||
|
|
@ -158,26 +164,26 @@ func (p *Peer) SetHead(hash common.Hash, td *big.Int) {
|
||||||
|
|
||||||
// KnownBlock returns whether peer is known to already have a block.
|
// KnownBlock returns whether peer is known to already have a block.
|
||||||
func (p *Peer) KnownBlock(hash common.Hash) bool {
|
func (p *Peer) KnownBlock(hash common.Hash) bool {
|
||||||
return p.knownBlocks.Contains(hash)
|
return p.knownBlocks.Contains(bloomHashWrapper(hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
// KnownTransaction returns whether peer is known to already have a transaction.
|
// KnownTransaction returns whether peer is known to already have a transaction.
|
||||||
func (p *Peer) KnownTransaction(hash common.Hash) bool {
|
func (p *Peer) KnownTransaction(hash common.Hash) bool {
|
||||||
return p.knownTxs.Contains(hash)
|
return p.knownTxs.Contains(bloomHashWrapper(hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
// markBlock marks a block as known for the peer, ensuring that the block will
|
// markBlock marks a block as known for the peer, ensuring that the block will
|
||||||
// never be propagated to this particular peer.
|
// never be propagated to this particular peer.
|
||||||
func (p *Peer) markBlock(hash common.Hash) {
|
func (p *Peer) markBlock(hash common.Hash) {
|
||||||
// If we reached the memory allowance, drop a previously known block hash
|
// If we reached the memory allowance, drop a previously known block hash
|
||||||
p.knownBlocks.Add(hash)
|
p.knownBlocks.Add(bloomHashWrapper(hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
// markTransaction marks a transaction as known for the peer, ensuring that it
|
// markTransaction marks a transaction as known for the peer, ensuring that it
|
||||||
// will never be propagated to this particular peer.
|
// will never be propagated to this particular peer.
|
||||||
func (p *Peer) markTransaction(hash common.Hash) {
|
func (p *Peer) markTransaction(hash common.Hash) {
|
||||||
// If we reached the memory allowance, drop a previously known transaction hash
|
// If we reached the memory allowance, drop a previously known transaction hash
|
||||||
p.knownTxs.Add(hash)
|
p.knownTxs.Add(bloomHashWrapper(hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendTransactions sends transactions to the peer and includes the hashes
|
// SendTransactions sends transactions to the peer and includes the hashes
|
||||||
|
|
@ -190,9 +196,9 @@ func (p *Peer) markTransaction(hash common.Hash) {
|
||||||
// The reasons this is public is to allow packages using this protocol to write
|
// The reasons this is public is to allow packages using this protocol to write
|
||||||
// tests that directly send messages without having to do the async queueing.
|
// tests that directly send messages without having to do the async queueing.
|
||||||
func (p *Peer) SendTransactions(txs types.Transactions) error {
|
func (p *Peer) SendTransactions(txs types.Transactions) error {
|
||||||
// Mark all the transactions as known, but ensure we don't overflow our limits
|
// Mark all the transactions as known
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
p.knownTxs.Add(tx.Hash())
|
p.knownTxs.Add(bloomHashWrapper(tx.Hash()))
|
||||||
}
|
}
|
||||||
return p2p.Send(p.rw, TransactionsMsg, txs)
|
return p2p.Send(p.rw, TransactionsMsg, txs)
|
||||||
}
|
}
|
||||||
|
|
@ -203,8 +209,10 @@ func (p *Peer) SendTransactions(txs types.Transactions) error {
|
||||||
func (p *Peer) AsyncSendTransactions(hashes []common.Hash) {
|
func (p *Peer) AsyncSendTransactions(hashes []common.Hash) {
|
||||||
select {
|
select {
|
||||||
case p.txBroadcast <- hashes:
|
case p.txBroadcast <- hashes:
|
||||||
// Mark all the transactions as known, but ensure we don't overflow our limits
|
// Mark all the transactions as known
|
||||||
p.knownTxs.Add(hashes...)
|
for _, hash := range hashes {
|
||||||
|
p.knownTxs.Add(bloomHashWrapper(hash))
|
||||||
|
}
|
||||||
case <-p.term:
|
case <-p.term:
|
||||||
p.Log().Debug("Dropping transaction propagation", "count", len(hashes))
|
p.Log().Debug("Dropping transaction propagation", "count", len(hashes))
|
||||||
}
|
}
|
||||||
|
|
@ -217,8 +225,10 @@ func (p *Peer) AsyncSendTransactions(hashes []common.Hash) {
|
||||||
// directly as the queueing (memory) and transmission (bandwidth) costs should
|
// directly as the queueing (memory) and transmission (bandwidth) costs should
|
||||||
// not be managed directly.
|
// not be managed directly.
|
||||||
func (p *Peer) sendPooledTransactionHashes66(hashes []common.Hash) error {
|
func (p *Peer) sendPooledTransactionHashes66(hashes []common.Hash) error {
|
||||||
// Mark all the transactions as known, but ensure we don't overflow our limits
|
// Mark all the transactions as known
|
||||||
p.knownTxs.Add(hashes...)
|
for _, hash := range hashes {
|
||||||
|
p.knownTxs.Add(bloomHashWrapper(hash))
|
||||||
|
}
|
||||||
return p2p.Send(p.rw, NewPooledTransactionHashesMsg, NewPooledTransactionHashesPacket66(hashes))
|
return p2p.Send(p.rw, NewPooledTransactionHashesMsg, NewPooledTransactionHashesPacket66(hashes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,8 +240,10 @@ func (p *Peer) sendPooledTransactionHashes66(hashes []common.Hash) error {
|
||||||
// directly as the queueing (memory) and transmission (bandwidth) costs should
|
// directly as the queueing (memory) and transmission (bandwidth) costs should
|
||||||
// not be managed directly.
|
// not be managed directly.
|
||||||
func (p *Peer) sendPooledTransactionHashes68(hashes []common.Hash, types []byte, sizes []uint32) error {
|
func (p *Peer) sendPooledTransactionHashes68(hashes []common.Hash, types []byte, sizes []uint32) error {
|
||||||
// Mark all the transactions as known, but ensure we don't overflow our limits
|
// Mark all the transactions as known
|
||||||
p.knownTxs.Add(hashes...)
|
for _, hash := range hashes {
|
||||||
|
p.knownTxs.Add(bloomHashWrapper(hash))
|
||||||
|
}
|
||||||
return p2p.Send(p.rw, NewPooledTransactionHashesMsg, NewPooledTransactionHashesPacket68{Types: types, Sizes: sizes, Hashes: hashes})
|
return p2p.Send(p.rw, NewPooledTransactionHashesMsg, NewPooledTransactionHashesPacket68{Types: types, Sizes: sizes, Hashes: hashes})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,8 +253,10 @@ func (p *Peer) sendPooledTransactionHashes68(hashes []common.Hash, types []byte,
|
||||||
func (p *Peer) AsyncSendPooledTransactionHashes(hashes []common.Hash) {
|
func (p *Peer) AsyncSendPooledTransactionHashes(hashes []common.Hash) {
|
||||||
select {
|
select {
|
||||||
case p.txAnnounce <- hashes:
|
case p.txAnnounce <- hashes:
|
||||||
// Mark all the transactions as known, but ensure we don't overflow our limits
|
// Mark all the transactions as known
|
||||||
p.knownTxs.Add(hashes...)
|
for _, hash := range hashes {
|
||||||
|
p.knownTxs.Add(bloomHashWrapper(hash))
|
||||||
|
}
|
||||||
case <-p.term:
|
case <-p.term:
|
||||||
p.Log().Debug("Dropping transaction announcement", "count", len(hashes))
|
p.Log().Debug("Dropping transaction announcement", "count", len(hashes))
|
||||||
}
|
}
|
||||||
|
|
@ -250,8 +264,10 @@ func (p *Peer) AsyncSendPooledTransactionHashes(hashes []common.Hash) {
|
||||||
|
|
||||||
// ReplyPooledTransactionsRLP is the eth/66 version of SendPooledTransactionsRLP.
|
// ReplyPooledTransactionsRLP is the eth/66 version of SendPooledTransactionsRLP.
|
||||||
func (p *Peer) ReplyPooledTransactionsRLP(id uint64, hashes []common.Hash, txs []rlp.RawValue) error {
|
func (p *Peer) ReplyPooledTransactionsRLP(id uint64, hashes []common.Hash, txs []rlp.RawValue) error {
|
||||||
// Mark all the transactions as known, but ensure we don't overflow our limits
|
// Mark all the transactions as known
|
||||||
p.knownTxs.Add(hashes...)
|
for _, hash := range hashes {
|
||||||
|
p.knownTxs.Add(bloomHashWrapper(hash))
|
||||||
|
}
|
||||||
|
|
||||||
// Not packed into PooledTransactionsPacket to avoid RLP decoding
|
// Not packed into PooledTransactionsPacket to avoid RLP decoding
|
||||||
return p2p.Send(p.rw, PooledTransactionsMsg, &PooledTransactionsRLPPacket66{
|
return p2p.Send(p.rw, PooledTransactionsMsg, &PooledTransactionsRLPPacket66{
|
||||||
|
|
@ -263,8 +279,10 @@ func (p *Peer) ReplyPooledTransactionsRLP(id uint64, hashes []common.Hash, txs [
|
||||||
// SendNewBlockHashes announces the availability of a number of blocks through
|
// SendNewBlockHashes announces the availability of a number of blocks through
|
||||||
// a hash notification.
|
// a hash notification.
|
||||||
func (p *Peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error {
|
func (p *Peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error {
|
||||||
// Mark all the block hashes as known, but ensure we don't overflow our limits
|
// Mark all the block hashes as known
|
||||||
p.knownBlocks.Add(hashes...)
|
for _, hash := range hashes {
|
||||||
|
p.knownBlocks.Add(bloomHashWrapper(hash))
|
||||||
|
}
|
||||||
|
|
||||||
request := make(NewBlockHashesPacket, len(hashes))
|
request := make(NewBlockHashesPacket, len(hashes))
|
||||||
for i := 0; i < len(hashes); i++ {
|
for i := 0; i < len(hashes); i++ {
|
||||||
|
|
@ -280,8 +298,8 @@ func (p *Peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error
|
||||||
func (p *Peer) AsyncSendNewBlockHash(block *types.Block) {
|
func (p *Peer) AsyncSendNewBlockHash(block *types.Block) {
|
||||||
select {
|
select {
|
||||||
case p.queuedBlockAnns <- block:
|
case p.queuedBlockAnns <- block:
|
||||||
// Mark all the block hash as known, but ensure we don't overflow our limits
|
// Mark all the block hash as known
|
||||||
p.knownBlocks.Add(block.Hash())
|
p.knownBlocks.Add(bloomHashWrapper(block.Hash()))
|
||||||
default:
|
default:
|
||||||
p.Log().Debug("Dropping block announcement", "number", block.NumberU64(), "hash", block.Hash())
|
p.Log().Debug("Dropping block announcement", "number", block.NumberU64(), "hash", block.Hash())
|
||||||
}
|
}
|
||||||
|
|
@ -289,8 +307,8 @@ func (p *Peer) AsyncSendNewBlockHash(block *types.Block) {
|
||||||
|
|
||||||
// SendNewBlock propagates an entire block to a remote peer.
|
// SendNewBlock propagates an entire block to a remote peer.
|
||||||
func (p *Peer) SendNewBlock(block *types.Block, td *big.Int) error {
|
func (p *Peer) SendNewBlock(block *types.Block, td *big.Int) error {
|
||||||
// Mark all the block hash as known, but ensure we don't overflow our limits
|
// Mark all the block hash as known
|
||||||
p.knownBlocks.Add(block.Hash())
|
p.knownBlocks.Add(bloomHashWrapper(block.Hash()))
|
||||||
return p2p.Send(p.rw, NewBlockMsg, &NewBlockPacket{
|
return p2p.Send(p.rw, NewBlockMsg, &NewBlockPacket{
|
||||||
Block: block,
|
Block: block,
|
||||||
TD: td,
|
TD: td,
|
||||||
|
|
@ -302,8 +320,8 @@ func (p *Peer) SendNewBlock(block *types.Block, td *big.Int) error {
|
||||||
func (p *Peer) AsyncSendNewBlock(block *types.Block, td *big.Int) {
|
func (p *Peer) AsyncSendNewBlock(block *types.Block, td *big.Int) {
|
||||||
select {
|
select {
|
||||||
case p.queuedBlocks <- &blockPropagation{block: block, td: td}:
|
case p.queuedBlocks <- &blockPropagation{block: block, td: td}:
|
||||||
// Mark all the block hash as known, but ensure we don't overflow our limits
|
// Mark all the block hash as known
|
||||||
p.knownBlocks.Add(block.Hash())
|
p.knownBlocks.Add(bloomHashWrapper(block.Hash()))
|
||||||
default:
|
default:
|
||||||
p.Log().Debug("Dropping block propagation", "number", block.NumberU64(), "hash", block.Hash())
|
p.Log().Debug("Dropping block propagation", "number", block.NumberU64(), "hash", block.Hash())
|
||||||
}
|
}
|
||||||
|
|
@ -500,36 +518,15 @@ func (p *Peer) RequestTxs(hashes []common.Hash) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// knownCache is a cache for known hashes.
|
// bloomHashWrapper wraps a common.Hash to be used in the bloom filter library.
|
||||||
type knownCache struct {
|
// It converts the common.Hash to a mini hash of size 8 bytes.
|
||||||
hashes mapset.Set[common.Hash]
|
type bloomHashWrapper common.Hash
|
||||||
max int
|
|
||||||
}
|
|
||||||
|
|
||||||
// newKnownCache creates a new knownCache with a max capacity.
|
func (h bloomHashWrapper) Write(p []byte) (n int, err error) { panic("not implemented") }
|
||||||
func newKnownCache(max int) *knownCache {
|
func (h bloomHashWrapper) Sum(b []byte) []byte { panic("not implemented") }
|
||||||
return &knownCache{
|
func (h bloomHashWrapper) Reset() { panic("not implemented") }
|
||||||
max: max,
|
func (h bloomHashWrapper) BlockSize() int { panic("not implemented") }
|
||||||
hashes: mapset.NewSet[common.Hash](),
|
func (h bloomHashWrapper) Size() int { return 8 }
|
||||||
}
|
func (h bloomHashWrapper) Sum64() uint64 {
|
||||||
}
|
return binary.BigEndian.Uint64(h[0:8])
|
||||||
|
|
||||||
// Add adds a list of elements to the set.
|
|
||||||
func (k *knownCache) Add(hashes ...common.Hash) {
|
|
||||||
for k.hashes.Cardinality() > max(0, k.max-len(hashes)) {
|
|
||||||
k.hashes.Pop()
|
|
||||||
}
|
|
||||||
for _, hash := range hashes {
|
|
||||||
k.hashes.Add(hash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains returns whether the given item is in the set.
|
|
||||||
func (k *knownCache) Contains(hash common.Hash) bool {
|
|
||||||
return k.hashes.Contains(hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cardinality returns the number of elements in the set.
|
|
||||||
func (k *knownCache) Cardinality() int {
|
|
||||||
return k.hashes.Cardinality()
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,7 @@ package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
)
|
)
|
||||||
|
|
@ -63,28 +61,3 @@ func (p *testPeer) close() {
|
||||||
p.Peer.Close()
|
p.Peer.Close()
|
||||||
p.app.Close()
|
p.app.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPeerSet(t *testing.T) {
|
|
||||||
size := 5
|
|
||||||
s := newKnownCache(size)
|
|
||||||
|
|
||||||
// add 10 items
|
|
||||||
for i := 0; i < size*2; i++ {
|
|
||||||
s.Add(common.Hash{byte(i)})
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.Cardinality() != size {
|
|
||||||
t.Fatalf("wrong size, expected %d but found %d", size, s.Cardinality())
|
|
||||||
}
|
|
||||||
|
|
||||||
vals := []common.Hash{}
|
|
||||||
for i := 10; i < 20; i++ {
|
|
||||||
vals = append(vals, common.Hash{byte(i)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// add item in batch
|
|
||||||
s.Add(vals...)
|
|
||||||
if s.Cardinality() < size {
|
|
||||||
t.Fatalf("bad size")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue