1+ /*-
2+ *
3+ * Hedera JSON RPC Relay
4+ *
5+ * Copyright (C) 2022 Hedera Hashgraph, LLC
6+ *
7+ * Licensed under the Apache License, Version 2.0 (the "License");
8+ * you may not use this file except in compliance with the License.
9+ * You may obtain a copy of the License at
10+ *
11+ * http://www.apache.org/licenses/LICENSE-2.0
12+ *
13+ * Unless required by applicable law or agreed to in writing, software
14+ * distributed under the License is distributed on an "AS IS" BASIS,
15+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+ * See the License for the specific language governing permissions and
17+ * limitations under the License.
18+ *
19+ */
20+
21+ import { expect } from 'chai' ;
22+ import HbarLimit from '../../src/lib/hbarlimiter' ;
23+
24+ describe ( 'HBAR Rate Limiter' , async function ( ) {
25+ this . timeout ( 20000 ) ;
26+ let rateLimiter : HbarLimit ;
27+ let currentDateNow : number ;
28+ const invalidDuration : number = 0 ;
29+ const invalidTotal : number = 0 ;
30+ const validDuration : number = 60000 ;
31+ const validTotal : number = 100000000 ;
32+
33+ this . beforeEach ( ( ) => {
34+ currentDateNow = Date . now ( ) ;
35+ } ) ;
36+
37+ it ( 'should be disabled, if we pass invalid total' , async function ( ) {
38+ rateLimiter = new HbarLimit ( currentDateNow , invalidTotal , validDuration ) ;
39+
40+ const isEnabled = rateLimiter . isEnabled ( ) ;
41+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
42+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
43+ const shouldRateLimit = rateLimiter . shouldLimit ( currentDateNow ) ;
44+ rateLimiter . addExpense ( validTotal , currentDateNow ) ;
45+
46+ expect ( isEnabled ) . to . equal ( false ) ;
47+ expect ( shouldRateLimit ) . to . equal ( false ) ;
48+ expect ( limiterResetTime ) . to . equal ( currentDateNow ) ;
49+ expect ( limiterRemainingBudget ) . to . equal ( 0 ) ;
50+ } ) ;
51+
52+ it ( 'should be disabled, if we pass invalid duration' , async function ( ) {
53+ rateLimiter = new HbarLimit ( currentDateNow , validTotal , invalidDuration ) ;
54+
55+ const isEnabled = rateLimiter . isEnabled ( ) ;
56+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
57+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
58+ const shouldRateLimit = rateLimiter . shouldLimit ( currentDateNow ) ;
59+ rateLimiter . addExpense ( validTotal , currentDateNow ) ;
60+
61+ expect ( isEnabled ) . to . equal ( false ) ;
62+ expect ( shouldRateLimit ) . to . equal ( false ) ;
63+ expect ( limiterResetTime ) . to . equal ( currentDateNow ) ;
64+ expect ( limiterRemainingBudget ) . to . equal ( 0 ) ;
65+ } ) ;
66+
67+ it ( 'should be disabled, if we pass both invalid duration and total' , async function ( ) {
68+ rateLimiter = new HbarLimit ( currentDateNow , invalidTotal , invalidDuration ) ;
69+
70+ const isEnabled = rateLimiter . isEnabled ( ) ;
71+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
72+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
73+ const shouldRateLimit = rateLimiter . shouldLimit ( currentDateNow ) ;
74+ rateLimiter . addExpense ( validTotal , currentDateNow ) ;
75+
76+ expect ( isEnabled ) . to . equal ( false ) ;
77+ expect ( shouldRateLimit ) . to . equal ( false ) ;
78+ expect ( limiterResetTime ) . to . equal ( currentDateNow ) ;
79+ expect ( limiterRemainingBudget ) . to . equal ( 0 ) ;
80+ } ) ;
81+
82+ it ( 'should be enabled, if we pass valid duration and total' , async function ( ) {
83+ rateLimiter = new HbarLimit ( currentDateNow , validTotal , validDuration ) ;
84+
85+ const isEnabled = rateLimiter . isEnabled ( ) ;
86+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
87+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
88+ const shouldRateLimit = rateLimiter . shouldLimit ( currentDateNow ) ;
89+
90+ expect ( isEnabled ) . to . equal ( true ) ;
91+ expect ( shouldRateLimit ) . to . equal ( false ) ;
92+ expect ( limiterResetTime ) . to . equal ( currentDateNow + validDuration ) ;
93+ expect ( limiterRemainingBudget ) . to . equal ( validTotal ) ;
94+ } ) ;
95+
96+ it ( 'should not rate limit' , async function ( ) {
97+ const cost = 10000000 ;
98+ rateLimiter = new HbarLimit ( currentDateNow , validTotal , validDuration ) ;
99+ rateLimiter . addExpense ( cost , currentDateNow ) ;
100+
101+ const isEnabled = rateLimiter . isEnabled ( ) ;
102+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
103+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
104+ const shouldRateLimit = rateLimiter . shouldLimit ( currentDateNow ) ;
105+
106+ expect ( isEnabled ) . to . equal ( true ) ;
107+ expect ( shouldRateLimit ) . to . equal ( false ) ;
108+ expect ( limiterResetTime ) . to . equal ( currentDateNow + validDuration ) ;
109+ expect ( limiterRemainingBudget ) . to . equal ( validTotal - cost ) ;
110+ } ) ;
111+
112+ it ( 'should rate limit' , async function ( ) {
113+ const cost = 1000000000 ;
114+ rateLimiter = new HbarLimit ( currentDateNow , validTotal , validDuration ) ;
115+ rateLimiter . addExpense ( cost , currentDateNow ) ;
116+
117+ const isEnabled = rateLimiter . isEnabled ( ) ;
118+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
119+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
120+ const shouldRateLimit = rateLimiter . shouldLimit ( currentDateNow ) ;
121+
122+ expect ( isEnabled ) . to . equal ( true ) ;
123+ expect ( shouldRateLimit ) . to . equal ( true ) ;
124+ expect ( limiterResetTime ) . to . equal ( currentDateNow + validDuration ) ;
125+ expect ( limiterRemainingBudget ) . to . equal ( validTotal - cost ) ;
126+ } ) ;
127+
128+ it ( 'should reset budget, while checking if we should rate limit' , async function ( ) {
129+ const cost = 1000000000 ;
130+ rateLimiter = new HbarLimit ( currentDateNow , validTotal , validDuration ) ;
131+ rateLimiter . addExpense ( cost , currentDateNow ) ;
132+
133+ const isEnabled = rateLimiter . isEnabled ( ) ;
134+ const futureDate = currentDateNow + validDuration * 2 ;
135+ const shouldRateLimit = rateLimiter . shouldLimit ( futureDate ) ;
136+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
137+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
138+
139+ expect ( isEnabled ) . to . equal ( true ) ;
140+ expect ( shouldRateLimit ) . to . equal ( false ) ;
141+ expect ( limiterResetTime ) . to . equal ( futureDate + validDuration ) ;
142+ expect ( limiterRemainingBudget ) . to . equal ( validTotal ) ;
143+ } ) ;
144+
145+ it ( 'should reset budget, while adding expense' , async function ( ) {
146+ const cost = 1000000000 ;
147+ rateLimiter = new HbarLimit ( currentDateNow , validTotal , validDuration ) ;
148+
149+ rateLimiter . addExpense ( cost , currentDateNow ) ;
150+ const shouldRateLimitBefore = rateLimiter . shouldLimit ( currentDateNow ) ;
151+
152+ const futureDate = currentDateNow + validDuration * 2 ;
153+ rateLimiter . addExpense ( 100 , futureDate ) ;
154+ const shouldRateLimitAfter = rateLimiter . shouldLimit ( futureDate ) ;
155+
156+ const isEnabled = rateLimiter . isEnabled ( ) ;
157+ const limiterResetTime = rateLimiter . getResetTime ( ) ;
158+ const limiterRemainingBudget = rateLimiter . getRemainingBudget ( ) ;
159+
160+ expect ( isEnabled ) . to . equal ( true ) ;
161+ expect ( shouldRateLimitBefore ) . to . equal ( true ) ;
162+ expect ( shouldRateLimitAfter ) . to . equal ( false ) ;
163+ expect ( limiterResetTime ) . to . equal ( futureDate + validDuration ) ;
164+ expect ( limiterRemainingBudget ) . to . equal ( validTotal - 100 ) ;
165+ } ) ;
166+ } ) ;
0 commit comments