@@ -64,15 +64,54 @@ type Transaction struct {
64
64
inner TxData // Consensus contents of a transaction
65
65
time time.Time // Time first seen locally (spam avoidance)
66
66
67
- // Arbitrum cache: must be atomically accessed
68
- CalldataUnits uint64
67
+ // Arbitrum cache of the calldata units at a brotli compression level.
68
+ // The top 8 bits are the brotli compression level last used to compute this,
69
+ // and the remaining 56 bits are the calldata units at that compression level.
70
+ calldataUnitsForBrotliCompressionLevel atomic.Uint64
69
71
70
72
// caches
71
73
hash atomic.Pointer [common.Hash ]
72
74
size atomic.Uint64
73
75
from atomic.Pointer [sigCache ]
74
76
}
75
77
78
+ // GetRawCachedCalldataUnits returns the cached brotli compression level and corresponding calldata units,
79
+ // or (0, 0) if the cache is empty.
80
+ func (tx * Transaction ) GetRawCachedCalldataUnits () (uint64 , uint64 ) {
81
+ repr := tx .calldataUnitsForBrotliCompressionLevel .Load ()
82
+ cachedCompressionLevel := repr >> 56
83
+ calldataUnits := repr & ((1 << 56 ) - 1 )
84
+ return cachedCompressionLevel , calldataUnits
85
+ }
86
+
87
+ // GetCachedCalldataUnits returns the cached calldata units for a given brotli compression level,
88
+ // returning nil if no cache is present or the cache is for a different compression level.
89
+ func (tx * Transaction ) GetCachedCalldataUnits (requestedCompressionLevel uint64 ) * uint64 {
90
+ cachedCompressionLevel , cachedUnits := tx .GetRawCachedCalldataUnits ()
91
+ if cachedUnits == 0 {
92
+ // empty cache
93
+ return nil
94
+ }
95
+ if cachedCompressionLevel != requestedCompressionLevel {
96
+ // wrong compression level
97
+ return nil
98
+ }
99
+ return & cachedUnits
100
+ }
101
+
102
+ // SetCachedCalldataUnits sets the cached brotli compression level and corresponding calldata units,
103
+ // or clears the cache if the values are too large to fit (at least 2**8 and 2**56 respectively).
104
+ // Note that a zero calldataUnits is also treated as an empty cache.
105
+ func (tx * Transaction ) SetCachedCalldataUnits (compressionLevel uint64 , calldataUnits uint64 ) {
106
+ var repr uint64
107
+ // Ensure the compressionLevel and calldataUnits will fit.
108
+ // Otherwise, just clear the cache.
109
+ if compressionLevel < 1 << 8 && calldataUnits < 1 << 56 {
110
+ repr = uint64 (compressionLevel )<< 56 | calldataUnits
111
+ }
112
+ tx .calldataUnitsForBrotliCompressionLevel .Store (repr )
113
+ }
114
+
76
115
// NewTx creates a new transaction.
77
116
func NewTx (inner TxData ) * Transaction {
78
117
tx := new (Transaction )
0 commit comments