@@ -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
10021010var 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
10051036func (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
10921123func (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}
0 commit comments