Skip to content

Commit d04a540

Browse files
fix: Always use gas throttle for HSS (#21890)
Signed-off-by: Lukasz Gasior <[email protected]>
1 parent fcbe66d commit d04a540

File tree

24 files changed

+124
-108
lines changed

24 files changed

+124
-108
lines changed

hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/AppContext.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import com.hedera.node.app.spi.fees.FeeCharging;
1414
import com.hedera.node.app.spi.info.NodeInfo;
1515
import com.hedera.node.app.spi.signatures.SignatureVerifier;
16-
import com.hedera.node.app.spi.throttle.Throttle;
16+
import com.hedera.node.app.spi.throttle.ScheduleThrottle;
1717
import com.swirlds.config.api.Configuration;
1818
import com.swirlds.metrics.api.Metrics;
1919
import com.swirlds.state.lifecycle.Service;
@@ -215,10 +215,10 @@ default CompletableFuture<Void> submitFuture(
215215
Supplier<Metrics> metricsSupplier();
216216

217217
/**
218-
* The application's strategy for creating {@link Throttle} instances.
218+
* The application's strategy for creating {@link ScheduleThrottle} instances.
219219
* @return the throttle factory
220220
*/
221-
Throttle.Factory throttleFactory();
221+
ScheduleThrottle.Factory throttleFactory();
222222

223223
/**
224224
* Supplier of the application's strategy for charging fees.

hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/throttle/Throttle.java renamed to hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/throttle/ScheduleThrottle.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,25 @@
55
import com.hedera.hapi.node.base.HederaFunctionality;
66
import com.hedera.hapi.node.state.throttles.ThrottleUsageSnapshots;
77
import com.hedera.hapi.node.transaction.TransactionBody;
8-
import com.hedera.node.app.spi.AppContext;
98
import edu.umd.cs.findbugs.annotations.NonNull;
109
import edu.umd.cs.findbugs.annotations.Nullable;
1110
import java.time.Instant;
1211

1312
/**
14-
* A throttle that can be used to limit the rate of transactions. Provided in the {@link AppContext} so that services
15-
* can align to the application's strategy for throttling transactions.
13+
* A throttle that is used by HSS to limit the rate of transactions scheduled for future execution.
1614
*/
17-
public interface Throttle {
15+
public interface ScheduleThrottle {
1816
/**
19-
* A factory for creating {@link Throttle} instances.
17+
* A factory for creating {@link ScheduleThrottle} instances.
2018
*/
2119
interface Factory {
2220
/**
23-
* Creates a new throttle based on the capacity split and usage snapshots.
21+
* Creates a new schedule throttle based on the capacity split and usage snapshots.
2422
* @param capacitySplit the split of the capacity
2523
* @param initialUsageSnapshots if not null, the usage snapshots the throttle should start with
2624
* @return the new throttle
2725
*/
28-
Throttle newThrottle(int capacitySplit, @Nullable ThrottleUsageSnapshots initialUsageSnapshots);
26+
ScheduleThrottle newScheduleThrottle(int capacitySplit, @Nullable ThrottleUsageSnapshots initialUsageSnapshots);
2927
}
3028

3129
/**

hedera-node/hedera-app/src/main/java/com/hedera/node/app/HederaInjectionComponent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import com.hedera.node.app.spi.info.NodeInfo;
4040
import com.hedera.node.app.spi.migrate.StartupNetworks;
4141
import com.hedera.node.app.spi.records.RecordCache;
42-
import com.hedera.node.app.spi.throttle.Throttle;
42+
import com.hedera.node.app.spi.throttle.ScheduleThrottle;
4343
import com.hedera.node.app.state.HederaStateInjectionModule;
4444
import com.hedera.node.app.state.WorkingStateAccessor;
4545
import com.hedera.node.app.throttle.ThrottleServiceManager;
@@ -204,7 +204,7 @@ interface Builder {
204204
Builder instantSource(InstantSource instantSource);
205205

206206
@BindsInstance
207-
Builder throttleFactory(Throttle.Factory throttleFactory);
207+
Builder throttleFactory(ScheduleThrottle.Factory throttleFactory);
208208

209209
@BindsInstance
210210
Builder softwareVersion(SemanticVersion softwareVersion);

hedera-node/hedera-app/src/main/java/com/hedera/node/app/services/AppContextImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import com.hedera.node.app.spi.fees.FeeCharging;
99
import com.hedera.node.app.spi.info.NodeInfo;
1010
import com.hedera.node.app.spi.signatures.SignatureVerifier;
11-
import com.hedera.node.app.spi.throttle.Throttle;
11+
import com.hedera.node.app.spi.throttle.ScheduleThrottle;
1212
import com.swirlds.config.api.Configuration;
1313
import com.swirlds.metrics.api.Metrics;
1414
import edu.umd.cs.findbugs.annotations.NonNull;
@@ -35,7 +35,7 @@ public record AppContextImpl(
3535
@NonNull Supplier<Configuration> configSupplier,
3636
@NonNull Supplier<NodeInfo> selfNodeInfoSupplier,
3737
@NonNull Supplier<Metrics> metricsSupplier,
38-
@NonNull Throttle.Factory throttleFactory,
38+
@NonNull ScheduleThrottle.Factory throttleFactory,
3939
@NonNull Supplier<FeeCharging> feeChargingSupplier,
4040
@NonNull EntityIdFactory idFactory)
4141
implements AppContext {

hedera-node/hedera-app/src/main/java/com/hedera/node/app/throttle/AppThrottleFactory.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import com.hedera.hapi.node.transaction.ThrottleDefinitions;
1313
import com.hedera.hapi.node.transaction.TransactionBody;
1414
import com.hedera.node.app.hapi.utils.throttles.DeterministicThrottle;
15-
import com.hedera.node.app.spi.throttle.Throttle;
15+
import com.hedera.node.app.spi.throttle.ScheduleThrottle;
1616
import com.hedera.node.app.workflows.TransactionInfo;
1717
import com.hedera.pbj.runtime.io.buffer.Bytes;
1818
import com.swirlds.config.api.Configuration;
@@ -24,9 +24,9 @@
2424
import java.util.function.Supplier;
2525

2626
/**
27-
* The application's strategy for creating a {@link Throttle} to use at consensus.
27+
* The application's strategy for creating a {@link ScheduleThrottle} to use at consensus.
2828
*/
29-
public class AppThrottleFactory implements Throttle.Factory {
29+
public class AppThrottleFactory implements ScheduleThrottle.Factory {
3030
private final Supplier<State> stateSupplier;
3131
private final Supplier<Configuration> configSupplier;
3232
private final Supplier<ThrottleDefinitions> definitionsSupplier;
@@ -51,7 +51,8 @@ public AppThrottleFactory(
5151
}
5252

5353
@Override
54-
public Throttle newThrottle(final int capacitySplit, @Nullable final ThrottleUsageSnapshots initialUsageSnapshots) {
54+
public ScheduleThrottle newScheduleThrottle(
55+
final int capacitySplit, @Nullable final ThrottleUsageSnapshots initialUsageSnapshots) {
5556
final var throttleAccumulator = throttleAccumulatorFactory.newThrottleAccumulator(
5657
configSupplier, () -> capacitySplit, ThrottleAccumulator.ThrottleType.BACKEND_THROTTLE);
5758
throttleAccumulator.applyGasConfig();
@@ -67,7 +68,7 @@ public Throttle newThrottle(final int capacitySplit, @Nullable final ThrottleUsa
6768
throttleAccumulator.gasLimitThrottle().resetUsageTo(initialUsageSnapshots.gasThrottleOrThrow());
6869
}
6970
// Throttle.allow() has the opposite polarity of ThrottleAccumulator.checkAndEnforceThrottle()
70-
return new Throttle() {
71+
return new ScheduleThrottle() {
7172
@Override
7273
public boolean allow(
7374
@NonNull final AccountID payerId,
@@ -86,7 +87,8 @@ public boolean allow(
8687
null),
8788
now,
8889
stateSupplier.get(),
89-
null);
90+
null,
91+
true);
9092
}
9193

9294
@Override

hedera-node/hedera-app/src/main/java/com/hedera/node/app/throttle/NetworkUtilizationManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public NetworkUtilizationManagerImpl(
4040
@Override
4141
public boolean trackTxn(
4242
@NonNull final TransactionInfo txnInfo, @NonNull final Instant consensusTime, @NonNull final State state) {
43-
final var shouldThrottle = backendThrottle.checkAndEnforceThrottle(txnInfo, consensusTime, state, null);
43+
final var shouldThrottle = backendThrottle.checkAndEnforceThrottle(txnInfo, consensusTime, state, null, false);
4444
congestionMultipliers.updateMultiplier(consensusTime);
4545
return shouldThrottle;
4646
}

hedera-node/hedera-app/src/main/java/com/hedera/node/app/throttle/SynchronizedThrottleAccumulator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public synchronized boolean shouldThrottle(
5656
requireNonNull(state);
5757
requireNonNull(throttleUsages);
5858
setDecisionTime(instantSource.instant());
59-
return frontendThrottle.checkAndEnforceThrottle(txnInfo, lastDecisionTime, state, throttleUsages);
59+
return frontendThrottle.checkAndEnforceThrottle(txnInfo, lastDecisionTime, state, throttleUsages, false);
6060
}
6161

6262
/**

hedera-node/hedera-app/src/main/java/com/hedera/node/app/throttle/ThrottleAccumulator.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,23 @@ public ThrottleAccumulator(
178178
* @param now the instant of time the transaction throttling should be checked for
179179
* @param state the current state of the node
180180
* @param throttleUsages if not null, a list to accumulate throttle usages into
181+
* @param gasThrottleAlwaysEnabled if set, gas throttle is always enforced within this call,
182+
* even if the throttleByGas configuration flag is off
181183
* @return whether the transaction should be throttled
182184
*/
183185
public boolean checkAndEnforceThrottle(
184186
@NonNull final TransactionInfo txnInfo,
185187
@NonNull final Instant now,
186188
@NonNull final State state,
187-
@Nullable final List<ThrottleUsage> throttleUsages) {
189+
@Nullable final List<ThrottleUsage> throttleUsages,
190+
final boolean gasThrottleAlwaysEnabled) {
188191
if (throttleType == NOOP_THROTTLE) {
189192
return false;
190193
}
191194
resetLastAllowedUse();
192195
lastTxnWasGasThrottled = false;
193-
if (shouldThrottleTxn(false, txnInfo, now, state, throttleUsages)) {
196+
197+
if (shouldThrottleTxn(txnInfo, now, state, throttleUsages, gasThrottleAlwaysEnabled)) {
194198
reclaimLastAllowedUse();
195199
return true;
196200
}
@@ -249,6 +253,7 @@ public boolean checkAndEnforceThrottle(
249253
if (isGasThrottled(queryFunction)) {
250254
final var enforceGasThrottle =
251255
configuration.getConfigData(ContractsConfig.class).throttleThrottleByGas();
256+
252257
return enforceGasThrottle
253258
&& !gasThrottle.allow(
254259
now,
@@ -412,11 +417,11 @@ public void updateAllMetrics() {
412417
}
413418

414419
private boolean shouldThrottleTxn(
415-
final boolean isScheduled,
416420
@NonNull final TransactionInfo txnInfo,
417421
@NonNull final Instant now,
418422
@NonNull final State state,
419-
List<ThrottleUsage> throttleUsages) {
423+
List<ThrottleUsage> throttleUsages,
424+
final boolean gasThrottleAlwaysEnabled) {
420425
final var function = txnInfo.functionality();
421426
final var configuration = configSupplier.get();
422427
final boolean isJumboTransactionsEnabled =
@@ -434,7 +439,10 @@ private boolean shouldThrottleTxn(
434439
return false;
435440
}
436441

437-
if (isGasExhausted(txnInfo, now, configuration, throttleUsages)) {
442+
final boolean throttleByGasFlag =
443+
configuration.getConfigData(ContractsConfig.class).throttleThrottleByGas();
444+
final boolean shouldThrottleByGas = throttleByGasFlag || gasThrottleAlwaysEnabled;
445+
if (shouldThrottleByGas && isGasExhausted(txnInfo, now, throttleUsages)) {
438446
lastTxnWasGasThrottled = true;
439447
return true;
440448
}
@@ -460,12 +468,7 @@ private boolean shouldThrottleTxn(
460468
}
461469

462470
return switch (function) {
463-
case SCHEDULE_CREATE -> {
464-
if (isScheduled) {
465-
throw new IllegalStateException("ScheduleCreate cannot be a child!");
466-
}
467-
yield shouldThrottleScheduleCreate(manager, txnInfo, now, state, throttleUsages);
468-
}
471+
case SCHEDULE_CREATE -> shouldThrottleScheduleCreate(manager, txnInfo, now, state, throttleUsages);
469472
case TOKEN_MINT ->
470473
shouldThrottleMint(manager, txnInfo.txBody().tokenMint(), now, configuration, throttleUsages);
471474
case CRYPTO_TRANSFER -> {
@@ -617,11 +620,8 @@ private long getGasLimitForContractTx(
617620
private boolean isGasExhausted(
618621
@NonNull final TransactionInfo txnInfo,
619622
@NonNull final Instant now,
620-
@NonNull final Configuration configuration,
621623
@Nullable final List<ThrottleUsage> throttleUsages) {
622-
final boolean shouldThrottleByGas =
623-
configuration.getConfigData(ContractsConfig.class).throttleThrottleByGas();
624-
if (shouldThrottleByGas && isGasThrottled(txnInfo.functionality())) {
624+
if (isGasThrottled(txnInfo.functionality())) {
625625
final long amount = getGasLimitForContractTx(txnInfo.txBody(), txnInfo.functionality());
626626
final boolean answer = !gasThrottle.allow(now, amount);
627627
if (!answer && throttleUsages != null) {

hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/standalone/ExecutorComponent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import com.hedera.node.app.service.util.impl.UtilServiceImpl;
1515
import com.hedera.node.app.services.ServicesInjectionModule;
1616
import com.hedera.node.app.spi.AppContext;
17-
import com.hedera.node.app.spi.throttle.Throttle;
17+
import com.hedera.node.app.spi.throttle.ScheduleThrottle;
1818
import com.hedera.node.app.state.HederaStateInjectionModule;
1919
import com.hedera.node.app.throttle.ThrottleServiceManager;
2020
import com.hedera.node.app.throttle.ThrottleServiceModule;
@@ -82,7 +82,7 @@ interface Builder {
8282
Builder metrics(Metrics metrics);
8383

8484
@BindsInstance
85-
Builder throttleFactory(Throttle.Factory throttleFactory);
85+
Builder throttleFactory(ScheduleThrottle.Factory throttleFactory);
8686

8787
@BindsInstance
8888
Builder appContext(AppContext appContext);

hedera-node/hedera-app/src/test/java/com/hedera/node/app/components/IngestComponentTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
import com.hedera.node.app.spi.info.NetworkInfo;
4343
import com.hedera.node.app.spi.info.NodeInfo;
4444
import com.hedera.node.app.spi.migrate.StartupNetworks;
45-
import com.hedera.node.app.spi.throttle.Throttle;
45+
import com.hedera.node.app.spi.throttle.ScheduleThrottle;
4646
import com.hedera.node.app.state.recordcache.RecordCacheService;
4747
import com.hedera.node.config.data.BlockStreamConfig;
4848
import com.hedera.node.config.data.HederaConfig;
@@ -78,7 +78,7 @@ class IngestComponentTest {
7878
private TransactionPoolNexus transactionPool;
7979

8080
@Mock
81-
private Throttle.Factory throttleFactory;
81+
private ScheduleThrottle.Factory throttleFactory;
8282

8383
@Mock
8484
private StartupNetworks startupNetworks;

0 commit comments

Comments
 (0)