Skip to content

Commit 48d3a62

Browse files
fix: Only use inner results for BATCH_INNER dispatches (#19157)
Signed-off-by: Michael Tinker <[email protected]>
1 parent 47dd677 commit 48d3a62

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/workflows/DispatchOptions.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public record DispatchOptions<T extends StreamBuilder>(
4141
@NonNull DispatchMetadata dispatchMetadata,
4242
@Nullable FeeCharging customFeeCharging) {
4343
private static final Predicate<Key> PREAUTHORIZED_KEYS = k -> true;
44+
private static final Predicate<Key> NO_AUTHORIZED_KEYS = k -> false;
4445

4546
/**
4647
* The choice of when to commit the dispatched transaction's effects on state.
@@ -357,7 +358,7 @@ public static <T extends StreamBuilder> DispatchOptions<T> atomicBatchDispatch(
357358
payerId,
358359
body,
359360
UsePresetTxnId.NO,
360-
PREAUTHORIZED_KEYS,
361+
NO_AUTHORIZED_KEYS,
361362
emptySet(),
362363
TransactionCategory.BATCH_INNER,
363364
ConsensusThrottling.ON,

hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/DispatchHandleContext.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import static com.hedera.hapi.node.base.ResponseCodeEnum.UNRESOLVABLE_REQUIRED_SIGNERS;
55
import static com.hedera.hapi.util.HapiUtils.functionOf;
6+
import static com.hedera.node.app.spi.workflows.HandleContext.TransactionCategory.BATCH_INNER;
67
import static com.hedera.node.app.workflows.handle.stack.SavepointStackImpl.castBuilder;
78
import static java.util.Collections.emptyMap;
89
import static java.util.Objects.requireNonNull;
@@ -361,7 +362,7 @@ public <T extends StreamBuilder> T dispatch(@NonNull final DispatchOptions<T> op
361362
PreHandleResult childPreHandleResult = null;
362363
// If we have pre-computed pre-handle results for the inner transactions, pass them to the child
363364
// dispatch instead of computing a synthetic pre-handle result for child dispatch.
364-
if (preHandleResults != null && !preHandleResults.isEmpty()) {
365+
if (options.category() == BATCH_INNER && preHandleResults != null && !preHandleResults.isEmpty()) {
365366
childPreHandleResult = preHandleResults.removeFirst();
366367
}
367368
final var childDispatch = childDispatchFactory.createChildDispatch(

hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/hip551/AtomicBatchTest.java

+15-11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static com.hedera.services.bdd.spec.keys.KeyShape.sigs;
1111
import static com.hedera.services.bdd.spec.keys.TrieSigMapGenerator.uniqueWithFullPrefixesFor;
1212
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountBalance;
13+
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountRecords;
1314
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAliasedAccountInfo;
1415
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getReceipt;
1516
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTxnRecord;
@@ -40,7 +41,6 @@
4041
import static com.hedera.services.bdd.suites.HapiSuite.MAX_CALL_DATA_SIZE;
4142
import static com.hedera.services.bdd.suites.HapiSuite.ONE_HBAR;
4243
import static com.hedera.services.bdd.suites.HapiSuite.ONE_HUNDRED_HBARS;
43-
import static com.hedera.services.bdd.suites.HapiSuite.ONE_MILLION_HBARS;
4444
import static com.hedera.services.bdd.suites.HapiSuite.SECP_256K1_SHAPE;
4545
import static com.hedera.services.bdd.suites.HapiSuite.SECP_256K1_SOURCE_KEY;
4646
import static com.hedera.services.bdd.suites.HapiSuite.THROTTLE_DEFS;
@@ -49,8 +49,10 @@
4949
import static com.hedera.services.bdd.suites.crypto.AutoCreateUtils.updateSpecFor;
5050
import static com.hedera.services.bdd.suites.utils.sysfiles.serdes.ThrottleDefsLoader.protoDefsFromResource;
5151
import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.INNER_TRANSACTION_FAILED;
52+
import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.INSUFFICIENT_PAYER_BALANCE;
5253
import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.SUCCESS;
5354
import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.TRANSACTION_EXPIRED;
55+
import static org.junit.jupiter.api.Assertions.assertTrue;
5456

5557
import com.hedera.node.app.hapi.utils.ethereum.EthTxData;
5658
import com.hedera.services.bdd.junit.HapiTest;
@@ -438,20 +440,18 @@ final Stream<DynamicTest> batchFinalizeHollowAccount() {
438440
final var alias = "alias";
439441
final var batchOperator = "batchOperator";
440442
return hapiTest(flattened(
443+
cryptoCreate("innerRecipient").balance(0L),
441444
cryptoCreate(batchOperator),
442445
newKeyNamed(alias).shape(SECP_256K1_SHAPE),
443446
createHollowAccountFrom(alias),
444447
getAliasedAccountInfo(alias).isHollow(),
445-
atomicBatch(cryptoCreate("foo")
446-
.payingWith(alias)
447-
.sigMapPrefixes(uniqueWithFullPrefixesFor(alias))
448+
atomicBatch(cryptoTransfer(tinyBarsFromTo(GENESIS, "innerRecipient", 123L))
448449
.batchKey(batchOperator))
449450
.payingWith(alias)
450451
.sigMapPrefixes(uniqueWithFullPrefixesFor(alias))
451452
.signedBy(alias, batchOperator),
452-
getAliasedAccountInfo(alias)
453-
.has(accountWith().hasNonEmptyKey())
454-
.logged()));
453+
getAliasedAccountInfo(alias).has(accountWith().hasNonEmptyKey()),
454+
getAccountBalance("innerRecipient").hasTinyBars(123L)));
455455
}
456456

457457
@HapiTest
@@ -461,19 +461,23 @@ final Stream<DynamicTest> failingBatchShouldFinalizeHollowAccount() {
461461
final var alias = "alias";
462462
final var batchOperator = "batchOperator";
463463
return hapiTest(flattened(
464+
cryptoCreate("innerRecipient").balance(0L),
464465
cryptoCreate(batchOperator),
465466
newKeyNamed(alias).shape(SECP_256K1_SHAPE),
466467
createHollowAccountFrom(alias),
467468
getAliasedAccountInfo(alias).isHollow(),
468-
atomicBatch(cryptoTransfer(tinyBarsFromToWithAlias(alias, GENESIS, ONE_MILLION_HBARS))
469-
.payingWith(alias)
470-
.sigMapPrefixes(uniqueWithFullPrefixesFor(alias))
469+
atomicBatch(cryptoTransfer(tinyBarsFromTo(GENESIS, "innerRecipient", 123L))
470+
// Use a payer account with zero balance
471+
.payingWith("innerRecipient")
471472
.batchKey(batchOperator))
472473
.payingWith(alias)
473474
.sigMapPrefixes(uniqueWithFullPrefixesFor(alias))
474475
.signedBy(alias, batchOperator)
475476
.hasKnownStatus(INNER_TRANSACTION_FAILED),
476-
getAliasedAccountInfo(alias).isNotHollow()));
477+
getAliasedAccountInfo(alias).isNotHollow(),
478+
getAccountRecords("innerRecipient")
479+
.exposingTo(records -> assertTrue(records.stream()
480+
.anyMatch(r -> r.getReceipt().getStatus() == INSUFFICIENT_PAYER_BALANCE)))));
477481
}
478482

479483
@HapiTest

0 commit comments

Comments
 (0)