Skip to content

Commit e94a428

Browse files
eth: added dynamic page limit for witness based on gas limit
1 parent 96ab269 commit e94a428

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

eth/backend.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
354354
EventMux: eth.eventMux,
355355
RequiredBlocks: config.RequiredBlocks,
356356
EthAPI: blockChainAPI,
357+
gasCeil: config.Miner.GasCeil,
357358
checker: checker,
358359
enableBlockTracking: eth.config.EnableBlockTracking,
359360
txAnnouncementOnly: eth.p2pServer.TxAnnouncementOnly,

eth/fetcher/block_fetcher.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ type BlockFetcher struct {
249249
}
250250

251251
// NewBlockFetcher creates a block fetcher to retrieve blocks based on hash announcements.
252-
func NewBlockFetcher(light bool, getHeader HeaderRetrievalFn, getBlock blockRetrievalFn, verifyHeader headerVerifierFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertHeaders headersInsertFn, insertChain chainInsertFn, dropPeer peerDropFn, enableBlockTracking bool, requireWitness bool) *BlockFetcher {
252+
func NewBlockFetcher(light bool, getHeader HeaderRetrievalFn, getBlock blockRetrievalFn, verifyHeader headerVerifierFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertHeaders headersInsertFn, insertChain chainInsertFn, dropPeer peerDropFn, enableBlockTracking bool, requireWitness bool, gasCeil uint64) *BlockFetcher {
253253
f := &BlockFetcher{
254254
light: light,
255255
notify: make(chan *blockAnnounce),
@@ -287,6 +287,7 @@ func NewBlockFetcher(light bool, getHeader HeaderRetrievalFn, getBlock blockRetr
287287
f.getBlock,
288288
f.getHeader,
289289
f.chainHeight,
290+
gasCeil,
290291
)
291292

292293
return f

eth/fetcher/witness_manager.go

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,15 @@ const (
4040
witnessCacheTTL = 2 * time.Minute
4141

4242
// Witness verification constants
43-
witnessPageWarningThreshold = 10 // Trigger verification when peer reports >10 pages
4443
witnessVerificationPeers = 2 // Number of random peers to query for verification
4544
witnessVerificationTimeout = 5 * time.Second // Timeout for verification queries
4645
witnessVerificationCacheTTL = 10 * time.Minute // Cache verification results for 10 minutes
46+
47+
// Witness size estimation constants
48+
// Assuming 1M gas results in 1MB witness, and max page size is 15MB
49+
gasPerMB = 1_000_000 // 1M gas per MB of witness
50+
maxPageSizeMB = 15 // Maximum page size in MB
51+
witnessPageThreshold = 10 // Default threshold if gas ceil not available
4752
)
4853

4954
// witnessRequestState tracks the state of a pending witness request.
@@ -95,6 +100,7 @@ type witnessManager struct {
95100

96101
// Witness verification state
97102
witnessVerificationCache *ttlcache.Cache[common.Hash, *witnessVerificationResult] // Cache of verified page counts
103+
gasCeil uint64 // Gas ceiling for calculating dynamic page threshold
98104

99105
// Communication channels (owned by witnessManager)
100106
injectNeedWitnessCh chan *injectBlockNeedWitnessMsg // Injected blocks needing witness fetch
@@ -124,6 +130,7 @@ func newWitnessManager(
124130
parentGetBlock blockRetrievalFn,
125131
parentGetHeader HeaderRetrievalFn,
126132
parentChainHeight chainHeightFn,
133+
gasCeil uint64,
127134
) *witnessManager {
128135
// Create TTL cache with 1 minute expiration for witnesses
129136
witnessCache := ttlcache.New[common.Hash, *cachedWitness](
@@ -150,6 +157,7 @@ func newWitnessManager(
150157
witnessUnavailable: make(map[common.Hash]time.Time),
151158
witnessCache: witnessCache,
152159
witnessVerificationCache: witnessVerificationCache,
160+
gasCeil: gasCeil,
153161
injectNeedWitnessCh: make(chan *injectBlockNeedWitnessMsg, 10),
154162
injectWitnessCh: make(chan *injectedWitnessMsg, 10),
155163
witnessTimer: time.NewTimer(0),
@@ -1001,6 +1009,29 @@ func (m *witnessManager) penalisePeer(peer string) {
10011009

10021010
var ErrNoWitnessPeerAvailable = errors.New("no peer with witness available") // Define a potential specific error
10031011

1012+
// calculatePageThreshold calculates the dynamic page threshold based on gas ceiling
1013+
// Formula: ceil(gasCeil (in millions) / maxPageSizeMB)
1014+
// Example: 50M gas / 15MB per page = ceil(3.33) = 4 pages
1015+
func (m *witnessManager) calculatePageThreshold() uint64 {
1016+
if m.gasCeil == 0 {
1017+
return witnessPageThreshold // Return default if gas ceil not set
1018+
}
1019+
1020+
// Convert gas ceil to millions and divide by max page size in MB using ceiling division
1021+
gasCeilMB := m.gasCeil / gasPerMB
1022+
1023+
// Ceiling division: (a + b - 1) / b
1024+
threshold := (gasCeilMB + maxPageSizeMB - 1) / maxPageSizeMB
1025+
1026+
// Ensure minimum threshold of 1 page
1027+
if threshold < 1 {
1028+
threshold = 1
1029+
}
1030+
1031+
log.Debug("[wm] Calculated dynamic page threshold", "gasCeil", m.gasCeil, "gasCeilMB", gasCeilMB, "threshold", threshold)
1032+
return threshold
1033+
}
1034+
10041035
// verifyWitnessPageCount verifies a witness page count by querying random peers
10051036
func (m *witnessManager) verifyWitnessPageCount(hash common.Hash, reportedPageCount uint64, reportingPeer string, getRandomPeers func() []string, getWitnessPageCount func(peer string, hash common.Hash) (uint64, error)) {
10061037
// Check if we already have a cached verification result
@@ -1090,9 +1121,12 @@ func (m *witnessManager) cacheVerificationResult(hash common.Hash, pageCount uin
10901121

10911122
// CheckWitnessPageCount checks if a witness page count should trigger verification
10921123
func (m *witnessManager) CheckWitnessPageCount(hash common.Hash, pageCount uint64, peer string, getRandomPeers func() []string, getWitnessPageCount func(peer string, hash common.Hash) (uint64, error)) {
1093-
// Only trigger verification if page count exceeds warning threshold
1094-
if pageCount > witnessPageWarningThreshold {
1095-
log.Debug("[wm] Witness page count exceeds threshold, triggering verification", "peer", peer, "hash", hash, "pageCount", pageCount, "threshold", witnessPageWarningThreshold)
1124+
// Calculate dynamic threshold based on gas ceiling
1125+
threshold := m.calculatePageThreshold()
1126+
1127+
// Only trigger verification if page count exceeds dynamic threshold
1128+
if pageCount > threshold {
1129+
log.Debug("[wm] Witness page count exceeds threshold, triggering verification", "peer", peer, "hash", hash, "pageCount", pageCount, "threshold", threshold)
10961130
go m.verifyWitnessPageCount(hash, pageCount, peer, getRandomPeers, getWitnessPageCount)
10971131
}
10981132
}

eth/handler.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ type handlerConfig struct {
114114
fastForwardThreshold uint64 // Minimum necessary distance between local header and peer to fast forward
115115
witnessPruneThreshold uint64 // Minimum necessary distance between local header and latest non pruned witness
116116
witnessPruneInterval time.Duration // The time interval between each witness prune routine
117+
gasCeil uint64 // Gas ceiling for dynamic witness page threshold calculation
117118
}
118119

119120
type handler struct {
@@ -280,7 +281,7 @@ func newHandler(config *handlerConfig) (*handler, error) {
280281
return nil, errors.New("snap sync not supported with snapshots disabled")
281282
}
282283

283-
h.blockFetcher = fetcher.NewBlockFetcher(false, nil, h.chain.GetBlockByHash, validator, h.BroadcastBlock, heighter, nil, inserter, h.removePeer, h.enableBlockTracking, h.statelessSync.Load() || h.syncWithWitnesses)
284+
h.blockFetcher = fetcher.NewBlockFetcher(false, nil, h.chain.GetBlockByHash, validator, h.BroadcastBlock, heighter, nil, inserter, h.removePeer, h.enableBlockTracking, h.statelessSync.Load() || h.syncWithWitnesses, config.gasCeil)
284285

285286
fetchTx := func(peer string, hashes []common.Hash) error {
286287
p := h.peers.peer(peer)

0 commit comments

Comments
 (0)