@@ -64,16 +64,18 @@ protected long increase(long lastUsage, long usage, long lastTime, long now, lon
6464
6565 if (lastTime != now ) {
6666 assert now > lastTime ;
67- if (lastTime + windowSize > now ) {
68- long delta = now - lastTime ;
69- double decay = (windowSize - delta ) / (double ) windowSize ;
70- averageLastUsage = round (averageLastUsage * decay ,
71- this .disableJavaLangMath ());
67+ if (windowNotExpired (lastTime , now , windowSize )) {
68+ long delta = elapsedTime (now , lastTime );
69+ averageLastUsage = decayAverageUsage (averageLastUsage , windowSize - delta , windowSize );
7270 } else {
7371 averageLastUsage = 0 ;
7472 }
7573 }
76- averageLastUsage += averageUsage ;
74+ if (hardenCalculation ()) {
75+ averageLastUsage = StrictMathWrapper .addExact (averageLastUsage , averageUsage );
76+ } else {
77+ averageLastUsage += averageUsage ;
78+ }
7779 return getUsage (averageLastUsage , windowSize );
7880 }
7981
@@ -105,11 +107,10 @@ public long increase(AccountCapsule accountCapsule, ResourceCode resourceCode,
105107 }
106108
107109 if (lastTime != now ) {
108- if (lastTime + oldWindowSize > now ) {
109- long delta = now - lastTime ;
110- double decay = (oldWindowSize - delta ) / (double ) oldWindowSize ;
111- averageLastUsage = round (averageLastUsage * decay ,
112- this .disableJavaLangMath ());
110+ if (windowNotExpired (lastTime , now , oldWindowSize )) {
111+ long delta = elapsedTime (now , lastTime );
112+ averageLastUsage = decayAverageUsage (averageLastUsage , oldWindowSize - delta ,
113+ oldWindowSize );
113114 } else {
114115 averageLastUsage = 0 ;
115116 }
@@ -122,7 +123,7 @@ public long increase(AccountCapsule accountCapsule, ResourceCode resourceCode,
122123 accountCapsule .setNewWindowSize (resourceCode , this .windowSize );
123124 return newUsage ;
124125 }
125- long remainWindowSize = oldWindowSize - ( now - lastTime );
126+ long remainWindowSize = remainWindowSize ( oldWindowSize , now , lastTime );
126127 long newWindowSize = getNewWindowSize (remainUsage , remainWindowSize , usage ,
127128 windowSize , newUsage );
128129 accountCapsule .setNewWindowSize (resourceCode , newWindowSize );
@@ -150,11 +151,10 @@ public long increaseV2(AccountCapsule accountCapsule, ResourceCode resourceCode,
150151 }
151152
152153 if (lastTime != now ) {
153- if (lastTime + oldWindowSize > now ) {
154- long delta = now - lastTime ;
155- double decay = (oldWindowSize - delta ) / (double ) oldWindowSize ;
156- averageLastUsage = round (averageLastUsage * decay ,
157- this .disableJavaLangMath ());
154+ if (windowNotExpired (lastTime , now , oldWindowSize )) {
155+ long delta = elapsedTime (now , lastTime );
156+ averageLastUsage = decayAverageUsage (averageLastUsage , oldWindowSize - delta ,
157+ oldWindowSize );
158158 } else {
159159 averageLastUsage = 0 ;
160160 }
@@ -167,7 +167,7 @@ public long increaseV2(AccountCapsule accountCapsule, ResourceCode resourceCode,
167167 return newUsage ;
168168 }
169169
170- long remainWindowSize = oldWindowSizeV2 - ( now - lastTime ) * WINDOW_SIZE_PRECISION ;
170+ long remainWindowSize = remainWindowSizeV2 ( oldWindowSizeV2 , now , lastTime );
171171 long newWindowSize ;
172172 if (hardenCalculation ()) {
173173 BigInteger biNewWindowSize = BigInteger .valueOf (remainUsage )
@@ -203,7 +203,9 @@ public void unDelegateIncrease(AccountCapsule owner, final AccountCapsule receiv
203203 remainOwnerWindowSize = remainOwnerWindowSize < 0 ? 0 : remainOwnerWindowSize ;
204204 remainReceiverWindowSize = remainReceiverWindowSize < 0 ? 0 : remainReceiverWindowSize ;
205205
206- long newOwnerUsage = ownerUsage + transferUsage ;
206+ long newOwnerUsage = hardenCalculation ()
207+ ? StrictMathWrapper .addExact (ownerUsage , transferUsage )
208+ : ownerUsage + transferUsage ;
207209 // mean ownerUsage == 0 and transferUsage == 0
208210 if (newOwnerUsage == 0 ) {
209211 owner .setNewWindowSize (resourceCode , this .windowSize );
@@ -225,7 +227,9 @@ public void unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule rece
225227 long ownerUsage = owner .getUsage (resourceCode );
226228 // Update itself first
227229 ownerUsage = increase (owner , resourceCode , ownerUsage , 0 , lastOwnerTime , now );
228- long newOwnerUsage = ownerUsage + transferUsage ;
230+ long newOwnerUsage = hardenCalculation ()
231+ ? StrictMathWrapper .addExact (ownerUsage , transferUsage )
232+ : ownerUsage + transferUsage ;
229233 // mean ownerUsage == 0 and transferUsage == 0
230234 if (newOwnerUsage == 0 ) {
231235 owner .setNewWindowSizeV2 (resourceCode , this .windowSize * WINDOW_SIZE_PRECISION );
@@ -282,6 +286,53 @@ private long divideCeilExact(BigInteger numerator, BigInteger denominator) {
282286 return result ;
283287 }
284288
289+ private long decayAverageUsage (long averageUsage , long remainWindowSize , long windowSize ) {
290+ if (hardenCalculation ()) {
291+ BigInteger denominator = BigInteger .valueOf (windowSize );
292+ BigInteger [] divRem = BigInteger .valueOf (averageUsage )
293+ .multiply (BigInteger .valueOf (remainWindowSize ))
294+ .divideAndRemainder (denominator );
295+ BigInteger result = divRem [0 ];
296+ if (divRem [1 ].shiftLeft (1 ).compareTo (denominator ) >= 0 ) {
297+ result = result .add (BigInteger .ONE );
298+ }
299+ return result .longValueExact ();
300+ }
301+ double decay = remainWindowSize / (double ) windowSize ;
302+ return round (averageUsage * decay , this .disableJavaLangMath ());
303+ }
304+
305+ private boolean windowNotExpired (long lastTime , long now , long windowSize ) {
306+ if (hardenCalculation ()) {
307+ return StrictMathWrapper .addExact (lastTime , windowSize ) > now ;
308+ }
309+ return lastTime + windowSize > now ;
310+ }
311+
312+ private long elapsedTime (long now , long lastTime ) {
313+ if (hardenCalculation ()) {
314+ return StrictMathWrapper .subtractExact (now , lastTime );
315+ }
316+ return now - lastTime ;
317+ }
318+
319+ private long remainWindowSize (long windowSize , long now , long lastTime ) {
320+ if (hardenCalculation ()) {
321+ return StrictMathWrapper .subtractExact (windowSize , elapsedTime (now , lastTime ));
322+ }
323+ return windowSize - (now - lastTime );
324+ }
325+
326+ private long remainWindowSizeV2 (long windowSizeV2 , long now , long lastTime ) {
327+ if (hardenCalculation ()) {
328+ BigInteger remain = BigInteger .valueOf (windowSizeV2 )
329+ .subtract (BigInteger .valueOf (elapsedTime (now , lastTime ))
330+ .multiply (BigInteger .valueOf (WINDOW_SIZE_PRECISION )));
331+ return remain .longValueExact ();
332+ }
333+ return windowSizeV2 - (now - lastTime ) * WINDOW_SIZE_PRECISION ;
334+ }
335+
285336 private long getUsage (long usage , long windowSize ) {
286337 if (hardenCalculation ()) {
287338 return BigInteger .valueOf (usage ).multiply (BigInteger .valueOf (windowSize ))
0 commit comments