Skip to content

Commit

Permalink
Implement TransactionRateMultiplierSource (#9305)
Browse files Browse the repository at this point in the history
Signed-off-by: Miroslav Gatsanoga <miroslav.gatsanoga@limechain.tech>
Signed-off-by: Michael Heinrichs <netopyr@users.noreply.github.com>
Co-authored-by: Michael Heinrichs <netopyr@users.noreply.github.com>
  • Loading branch information
MiroslavGatsanoga and netopyr authored Oct 31, 2023
1 parent e8e3828 commit 6f96c20
Show file tree
Hide file tree
Showing 14 changed files with 1,294 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
import com.hedera.node.app.config.ConfigProviderImpl;
import com.hedera.node.app.fees.ExchangeRateManager;
import com.hedera.node.app.fees.FeeService;
import com.hedera.node.app.fees.congestion.MonoMultiplierSources;
import com.hedera.node.app.fees.congestion.CongestionMultipliers;
import com.hedera.node.app.fees.congestion.EntityUtilizationMultiplier;
import com.hedera.node.app.fees.congestion.ThrottleMultiplier;
import com.hedera.node.app.ids.EntityIdService;
import com.hedera.node.app.info.CurrentPlatformStatusImpl;
import com.hedera.node.app.info.NetworkInfoImpl;
Expand All @@ -41,7 +43,6 @@
import com.hedera.node.app.service.file.ReadableFileStore;
import com.hedera.node.app.service.file.impl.FileServiceImpl;
import com.hedera.node.app.service.mono.context.properties.BootstrapProperties;
import com.hedera.node.app.service.mono.fees.congestion.ThrottleMultiplierSource;
import com.hedera.node.app.service.mono.utils.NamedDigestFactory;
import com.hedera.node.app.service.networkadmin.impl.FreezeServiceImpl;
import com.hedera.node.app.service.networkadmin.impl.NetworkServiceImpl;
Expand Down Expand Up @@ -175,7 +176,7 @@ public final class Hedera implements SwirldMain {

private ThrottleAccumulator backendThrottle;
private ThrottleAccumulator frontendThrottle;
private MonoMultiplierSources monoMultiplierSources;
private CongestionMultipliers congestionMultipliers;

/**
* The application name from the platform's perspective. This is currently locked in at the old main class name and
Expand Down Expand Up @@ -678,7 +679,7 @@ private void genesis(@NonNull final MerkleHederaState state) {
this.backendThrottle = new ThrottleAccumulator(() -> 1, configProvider);
this.frontendThrottle =
new ThrottleAccumulator(() -> platform.getAddressBook().getSize(), configProvider);
this.monoMultiplierSources = createMultiplierSources();
this.congestionMultipliers = createCongestionMultipliers(state);

logger.info("Initializing ExchangeRateManager");
exchangeRateManager = new ExchangeRateManager(configProvider);
Expand All @@ -697,12 +698,11 @@ private void genesis(@NonNull final MerkleHederaState state) {
initializeThrottles(state);
}

private MonoMultiplierSources createMultiplierSources() {
final var genericFeeMultiplier = new ThrottleMultiplierSource(
private CongestionMultipliers createCongestionMultipliers(HederaState state) {
final var genericFeeMultiplier = new ThrottleMultiplier(
"logical TPS",
"TPS",
"CryptoTransfer throughput",
logger,
() -> configProvider
.getConfiguration()
.getConfigData(FeesConfig.class)
Expand All @@ -712,11 +712,13 @@ private MonoMultiplierSources createMultiplierSources() {
.getConfigData(FeesConfig.class)
.percentCongestionMultipliers(),
() -> backendThrottle.activeThrottlesFor(CRYPTO_TRANSFER));
final var gasFeeMultiplier = new ThrottleMultiplierSource(

final var txnRateMultiplier = new EntityUtilizationMultiplier(genericFeeMultiplier, configProvider);

final var gasFeeMultiplier = new ThrottleMultiplier(
"EVM gas/sec",
"gas/sec",
"EVM utilization",
logger,
() -> configProvider
.getConfiguration()
.getConfigData(FeesConfig.class)
Expand All @@ -727,7 +729,7 @@ private MonoMultiplierSources createMultiplierSources() {
.percentCongestionMultipliers(),
() -> List.of(backendThrottle.gasLimitThrottle()));

return new MonoMultiplierSources(genericFeeMultiplier, gasFeeMultiplier);
return new CongestionMultipliers(txnRateMultiplier, gasFeeMultiplier);
}

/*==================================================================================================================
Expand Down Expand Up @@ -761,7 +763,7 @@ private void restart(
this.backendThrottle = new ThrottleAccumulator(() -> 1, configProvider);
this.frontendThrottle =
new ThrottleAccumulator(() -> platform.getAddressBook().getSize(), configProvider);
this.monoMultiplierSources = createMultiplierSources();
this.congestionMultipliers = createCongestionMultipliers(state);

logger.info("Initializing ExchangeRateManager");
exchangeRateManager = new ExchangeRateManager(configProvider);
Expand Down Expand Up @@ -814,11 +816,11 @@ private void initializeDagger(@NonNull final MerkleHederaState state, @NonNull f
configProvider,
throttleManager,
exchangeRateManager,
monoMultiplierSources,
congestionMultipliers,
backendThrottle,
frontendThrottle))
.networkUtilizationManager(
new NetworkUtilizationManagerImpl(backendThrottle, monoMultiplierSources))
new NetworkUtilizationManagerImpl(backendThrottle, congestionMultipliers))
.synchronizedThrottleAccumulator(new SynchronizedThrottleAccumulator(frontendThrottle))
.self(SelfNodeInfoImpl.of(nodeAddress, version))
.platform(platform)
Expand Down Expand Up @@ -890,7 +892,7 @@ private void initializeThrottles(@NonNull final HederaState state) {
this.frontendThrottle.applyGasConfig();

// Updating the multiplier source to use the new throttle definitions
this.monoMultiplierSources.resetExpectations();
this.congestionMultipliers.resetExpectations();
}
logger.info("Throttles initialized");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2023 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.node.app.fees.congestion;

import static java.util.Objects.requireNonNull;

import com.hedera.node.app.state.HederaState;
import com.hedera.node.app.workflows.TransactionInfo;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.time.Instant;

/**
* An implementation for congestion multipliers that uses two types of multiplier implementation ({@link EntityUtilizationMultiplier} and a {@link ThrottleMultiplier})
* to determine the current congestion multiplier.
*/
public class CongestionMultipliers {
private final EntityUtilizationMultiplier entityUtilizationMultiplier;
private final ThrottleMultiplier throttleMultiplier;

public CongestionMultipliers(
@NonNull final EntityUtilizationMultiplier entityUtilizationMultiplier,
@NonNull final ThrottleMultiplier throttleMultiplier) {
this.entityUtilizationMultiplier =
requireNonNull(entityUtilizationMultiplier, "entityUtilizationMultiplier must not be null");
this.throttleMultiplier = requireNonNull(throttleMultiplier, "throttleMultiplier must not be null");
}

/**
* Updates the congestion multipliers for the given consensus time.
*
* @param consensusTime the consensus time
*/
public void updateMultiplier(@NonNull final Instant consensusTime) {
throttleMultiplier.updateMultiplier(consensusTime);
entityUtilizationMultiplier.updateMultiplier(consensusTime);
}

/**
* Returns the maximum congestion multiplier of the gas and entity utilization based multipliers.
*
* @param txnInfo transaction info needed for entity utilization based multiplier
* @param state the state needed for entity utilization based multiplier
*
* @return the max congestion multiplier
*/
public long maxCurrentMultiplier(@NonNull final TransactionInfo txnInfo, @NonNull final HederaState state) {
return Math.max(
throttleMultiplier.currentMultiplier(), entityUtilizationMultiplier.currentMultiplier(txnInfo, state));
}

/**
* Returns the congestion level starts for the entity utilization based multiplier.
*
* @return the congestion level starts
*/
@NonNull
public Instant[] genericCongestionStarts() {
return entityUtilizationMultiplier.congestionLevelStarts();
}

/**
* Returns the congestion level starts for the throttle multiplier.
*
* @return the congestion level starts
*/
@NonNull
public Instant[] throttleMultiplierCongestionStarts() {
return throttleMultiplier.congestionLevelStarts();
}

/**
* Resets the congestion level starts for the entity utilization based multiplier.
*
* @param startTimes the congestion level starts
*/
public void resetEntityUtilizationMultiplierStarts(@NonNull final Instant[] startTimes) {
entityUtilizationMultiplier.resetCongestionLevelStarts(startTimes);
}

/**
* Resets the congestion level starts for the throttle multiplier.
*
* @param startTimes the congestion level starts
*/
public void resetThrottleMultiplierStarts(@NonNull final Instant[] startTimes) {
throttleMultiplier.resetCongestionLevelStarts(startTimes);
}

/**
* Resets the state of the underlying congestion multipliers.
*/
public void resetExpectations() {
throttleMultiplier.resetExpectations();
entityUtilizationMultiplier.resetExpectations();
}
}
Loading

0 comments on commit 6f96c20

Please sign in to comment.