|
17 | 17 | package com.hedera.node.app.workflows.ingest;
|
18 | 18 |
|
19 | 19 | import static com.hedera.hapi.node.base.HederaFunctionality.CONTRACT_CALL;
|
| 20 | +import static com.hedera.hapi.node.base.HederaFunctionality.CRYPTO_ADD_LIVE_HASH; |
| 21 | +import static com.hedera.hapi.node.base.HederaFunctionality.CRYPTO_DELETE_LIVE_HASH; |
20 | 22 | import static com.hedera.hapi.node.base.HederaFunctionality.ETHEREUM_TRANSACTION;
|
| 23 | +import static com.hedera.hapi.node.base.HederaFunctionality.FREEZE; |
| 24 | +import static com.hedera.hapi.node.base.HederaFunctionality.SYSTEM_DELETE; |
| 25 | +import static com.hedera.hapi.node.base.HederaFunctionality.SYSTEM_UNDELETE; |
21 | 26 | import static com.hedera.hapi.node.base.ResponseCodeEnum.BUSY;
|
22 | 27 | import static com.hedera.hapi.node.base.ResponseCodeEnum.DUPLICATE_TRANSACTION;
|
23 | 28 | import static com.hedera.hapi.node.base.ResponseCodeEnum.INSUFFICIENT_GAS;
|
24 | 29 | import static com.hedera.hapi.node.base.ResponseCodeEnum.INSUFFICIENT_TX_FEE;
|
25 | 30 | import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_ETHEREUM_TRANSACTION;
|
26 | 31 | import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_NODE_ACCOUNT;
|
27 | 32 | import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_SIGNATURE;
|
| 33 | +import static com.hedera.hapi.node.base.ResponseCodeEnum.NOT_SUPPORTED; |
28 | 34 | import static com.hedera.hapi.node.base.ResponseCodeEnum.PLATFORM_NOT_ACTIVE;
|
29 | 35 | import static com.hedera.hapi.node.base.ResponseCodeEnum.UNAUTHORIZED;
|
30 | 36 | import static com.hedera.node.app.hapi.utils.ethereum.EthTxData.populateEthTxData;
|
|
69 | 75 | import com.swirlds.config.api.Configuration;
|
70 | 76 | import edu.umd.cs.findbugs.annotations.NonNull;
|
71 | 77 | import java.time.Instant;
|
| 78 | +import java.util.EnumSet; |
72 | 79 | import java.util.HashSet;
|
73 | 80 | import java.util.List;
|
| 81 | +import java.util.Set; |
74 | 82 | import javax.inject.Inject;
|
75 | 83 | import org.apache.logging.log4j.LogManager;
|
76 | 84 | import org.apache.logging.log4j.Logger;
|
|
80 | 88 | */
|
81 | 89 | public final class IngestChecker {
|
82 | 90 | private static final Logger logger = LogManager.getLogger(IngestChecker.class);
|
| 91 | + private static final Set<HederaFunctionality> UNSUPPORTED_TRANSACTIONS = |
| 92 | + EnumSet.of(CRYPTO_ADD_LIVE_HASH, CRYPTO_DELETE_LIVE_HASH); |
| 93 | + private static final Set<HederaFunctionality> PRIVILEGED_TRANSACTIONS = |
| 94 | + EnumSet.of(FREEZE, SYSTEM_DELETE, SYSTEM_UNDELETE); |
83 | 95 |
|
84 | 96 | private final CurrentPlatformStatus currentPlatformStatus;
|
85 | 97 | private final TransactionChecker transactionChecker;
|
@@ -204,6 +216,7 @@ public TransactionInfo runAllChecks(
|
204 | 216 | }
|
205 | 217 |
|
206 | 218 | // 4. Check throttles
|
| 219 | + assertThrottlingPreconditions(txInfo, configuration); |
207 | 220 | if (synchronizedThrottleAccumulator.shouldThrottle(txInfo, state)) {
|
208 | 221 | throw new PreCheckException(BUSY);
|
209 | 222 | }
|
@@ -245,6 +258,27 @@ public TransactionInfo runAllChecks(
|
245 | 258 | return txInfo;
|
246 | 259 | }
|
247 | 260 |
|
| 261 | + private void assertThrottlingPreconditions( |
| 262 | + @NonNull final TransactionInfo txInfo, @NonNull final Configuration configuration) |
| 263 | + throws PreCheckException { |
| 264 | + if (UNSUPPORTED_TRANSACTIONS.contains(txInfo.functionality())) { |
| 265 | + throw new PreCheckException(NOT_SUPPORTED); |
| 266 | + } |
| 267 | + if (PRIVILEGED_TRANSACTIONS.contains(txInfo.functionality())) { |
| 268 | + final var payerNum = |
| 269 | + txInfo.payerID() == null ? Long.MAX_VALUE : txInfo.payerID().accountNumOrElse(Long.MAX_VALUE); |
| 270 | + final var hederaConfig = configuration.getConfigData(HederaConfig.class); |
| 271 | + // This adds a mild restriction that privileged transactions can only |
| 272 | + // be issued by system accounts; (FUTURE) consider giving non-trivial |
| 273 | + // minimum fees to privileged transactions that fail with UNAUTHORIZED |
| 274 | + // at consensus, and adding them to normal throttle buckets, c.f. |
| 275 | + // https://github.com/hashgraph/hedera-services/issues/12559 |
| 276 | + if (payerNum >= hederaConfig.firstUserEntity()) { |
| 277 | + throw new PreCheckException(UNAUTHORIZED); |
| 278 | + } |
| 279 | + } |
| 280 | + } |
| 281 | + |
248 | 282 | private void verifyPayerSignature(
|
249 | 283 | @NonNull final TransactionInfo txInfo,
|
250 | 284 | @NonNull final Account payer,
|
|
0 commit comments