Skip to content

Commit

Permalink
fix: Set the designated payer when building an EVM transactions from …
Browse files Browse the repository at this point in the history
…scheduled transactions (#16708)

Signed-off-by: Zhivko Kelchev <[email protected]>
Signed-off-by: Valentin Tronkov <[email protected]>
Signed-off-by: ibankov <[email protected]>
Signed-off-by: Michael Tinker <[email protected]>
Co-authored-by: Valentin Tronkov <[email protected]>
Co-authored-by: ibankov <[email protected]>
Co-authored-by: Michael Tinker <[email protected]>
Co-authored-by: Joseph S. <[email protected]>
  • Loading branch information
5 people committed Nov 28, 2024
1 parent 1b4339d commit b85211e
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public CallOutcome call() {

private HederaEvmTransaction safeCreateHevmTransaction() {
try {
return hevmTransactionFactory.fromHapiTransaction(context.body());
return hevmTransactionFactory.fromHapiTransaction(context.body(), context.payer());
} catch (HandleException e) {
// Return a HederaEvmTransaction that represents the error in order to charge fees to the sender
return hevmTransactionFactory.fromContractTxException(context.body(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,15 @@ public HevmTransactionFactory(
* Given a {@link TransactionBody}, creates the implied {@link HederaEvmTransaction}.
*
* @param body the {@link TransactionBody} to convert
* @param payerId transaction payer id
* @return the implied {@link HederaEvmTransaction}
* @throws IllegalArgumentException if the {@link TransactionBody} is not a contract operation
*/
public HederaEvmTransaction fromHapiTransaction(@NonNull final TransactionBody body) {
public HederaEvmTransaction fromHapiTransaction(@NonNull final TransactionBody body, @NonNull AccountID payerId) {
return switch (body.data().kind()) {
case CONTRACT_CREATE_INSTANCE -> fromHapiCreate(
body.transactionIDOrThrow().accountIDOrThrow(), body.contractCreateInstanceOrThrow());
case CONTRACT_CALL -> fromHapiCall(
body.transactionIDOrThrow().accountIDOrThrow(), body.contractCallOrThrow());
case ETHEREUM_TRANSACTION -> fromHapiEthereum(
body.transactionIDOrThrow().accountIDOrThrow(), body.ethereumTransactionOrThrow());
case CONTRACT_CREATE_INSTANCE -> fromHapiCreate(payerId, body.contractCreateInstanceOrThrow());
case CONTRACT_CALL -> fromHapiCall(payerId, body.contractCallOrThrow());
case ETHEREUM_TRANSACTION -> fromHapiEthereum(payerId, body.ethereumTransactionOrThrow());
default -> throw new IllegalArgumentException("Not a contract operation");
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import com.hedera.hapi.node.base.AccountID;
import com.hedera.hapi.node.base.TimestampSeconds;
import com.hedera.hapi.node.base.TransactionID;
import com.hedera.hapi.node.transaction.ExchangeRate;
Expand Down Expand Up @@ -132,9 +133,7 @@ void callsComponentInfraAsExpectedForValidEthTx() {
customGasCharging);

givenSenderAccount();
given(context.body()).willReturn(TransactionBody.DEFAULT);
given(hevmTransactionFactory.fromHapiTransaction(TransactionBody.DEFAULT))
.willReturn(HEVM_CREATION);
givenBodyWithTxnIdWillReturnHEVM();
given(processor.processTransaction(
HEVM_CREATION, rootProxyWorldUpdater, feesOnlyUpdater, hederaEvmContext, tracer, CONFIGURATION))
.willReturn(SUCCESS_RESULT_WITH_SIGNER_NONCE);
Expand Down Expand Up @@ -171,9 +170,7 @@ void callsComponentInfraAsExpectedForValidEthTxWithoutTo() {
customGasCharging);

givenSenderAccount();
given(context.body()).willReturn(TransactionBody.DEFAULT);
given(hevmTransactionFactory.fromHapiTransaction(TransactionBody.DEFAULT))
.willReturn(HEVM_CREATION);
givenBodyWithTxnIdWillReturnHEVM();
given(processor.processTransaction(
HEVM_CREATION, rootProxyWorldUpdater, feesOnlyUpdater, hederaEvmContext, tracer, CONFIGURATION))
.willReturn(SUCCESS_RESULT_WITH_SIGNER_NONCE);
Expand Down Expand Up @@ -208,9 +205,7 @@ void callsComponentInfraAsExpectedForNonEthTx() {
processor,
customGasCharging);

given(context.body()).willReturn(TransactionBody.DEFAULT);
given(hevmTransactionFactory.fromHapiTransaction(TransactionBody.DEFAULT))
.willReturn(HEVM_CREATION);
givenBodyWithTxnIdWillReturnHEVM();
given(processor.processTransaction(
HEVM_CREATION, rootProxyWorldUpdater, feesOnlyUpdater, hederaEvmContext, tracer, CONFIGURATION))
.willReturn(SUCCESS_RESULT);
Expand Down Expand Up @@ -240,9 +235,7 @@ void stillChargesHapiFeesOnAbort() {
processor,
customGasCharging);

given(context.body()).willReturn(TransactionBody.DEFAULT);
given(hevmTransactionFactory.fromHapiTransaction(TransactionBody.DEFAULT))
.willReturn(HEVM_CREATION);
givenBodyWithTxnIdWillReturnHEVM();
given(processor.processTransaction(
HEVM_CREATION, rootProxyWorldUpdater, feesOnlyUpdater, hederaEvmContext, tracer, CONFIGURATION))
.willThrow(new HandleException(INVALID_CONTRACT_ID));
Expand Down Expand Up @@ -272,8 +265,9 @@ void chargeHapiFeeOnFailedEthTransaction() {
customGasCharging);

given(context.body()).willReturn(TransactionBody.DEFAULT);
given(context.payer()).willReturn(AccountID.DEFAULT);
final var ethTx = wellKnownRelayedHapiCallWithGasLimit(1_000_000L);
given(hevmTransactionFactory.fromHapiTransaction(TransactionBody.DEFAULT))
given(hevmTransactionFactory.fromHapiTransaction(TransactionBody.DEFAULT, context.payer()))
.willReturn(ethTx);
given(processor.processTransaction(
ethTx, rootProxyWorldUpdater, feesOnlyUpdater, hederaEvmContext, tracer, CONFIGURATION))
Expand Down Expand Up @@ -308,7 +302,10 @@ void stillChargesGasFeesOnHevmException() {
customGasCharging);

given(context.body()).willReturn(transactionBody);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody)).willReturn(HEVM_Exception);
final var payer = AccountID.DEFAULT;
given(context.payer()).willReturn(payer);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody, payer))
.willReturn(HEVM_Exception);
given(transactionBody.transactionIDOrThrow()).willReturn(transactionID);
given(transactionID.accountIDOrThrow()).willReturn(SENDER_ID);

Expand Down Expand Up @@ -337,7 +334,10 @@ void doesNotChargeGasFeesOnHevmExceptionIfSoConfigured() {
customGasCharging);

given(context.body()).willReturn(transactionBody);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody)).willReturn(HEVM_Exception);
final var payer = AccountID.DEFAULT;
given(context.payer()).willReturn(payer);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody, payer))
.willReturn(HEVM_Exception);
given(transactionBody.transactionIDOrThrow()).willReturn(transactionID);
given(transactionID.accountIDOrThrow()).willReturn(SENDER_ID);

Expand Down Expand Up @@ -366,7 +366,9 @@ void stillChargesGasFeesOnExceptionThrown() {
customGasCharging);

given(context.body()).willReturn(transactionBody);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody))
final var payer = AccountID.DEFAULT;
given(context.payer()).willReturn(payer);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody, payer))
.willThrow(new HandleException(INVALID_CONTRACT_ID));
given(hevmTransactionFactory.fromContractTxException(any(), any())).willReturn(HEVM_Exception);
given(transactionBody.transactionIDOrThrow()).willReturn(transactionID);
Expand Down Expand Up @@ -399,7 +401,9 @@ void doesNotChargeGasAndHapiFeesOnExceptionThrownIfSoConfigured() {
customGasCharging);

given(context.body()).willReturn(transactionBody);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody))
final var payer = AccountID.DEFAULT;
given(context.payer()).willReturn(payer);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody, payer))
.willThrow(new HandleException(INVALID_CONTRACT_ID));
given(hevmTransactionFactory.fromContractTxException(any(), any())).willReturn(HEVM_Exception);
given(transactionBody.transactionIDOrThrow()).willReturn(transactionID);
Expand Down Expand Up @@ -432,9 +436,10 @@ void reThrowsExceptionWhenNotContractCall() {
customGasCharging);

given(context.body()).willReturn(transactionBody);
given(context.payer()).willReturn(SENDER_ID);
given(transactionBody.transactionIDOrThrow()).willReturn(transactionID);
given(transactionID.accountIDOrThrow()).willReturn(SENDER_ID);
given(hevmTransactionFactory.fromHapiTransaction(transactionBody))
given(hevmTransactionFactory.fromHapiTransaction(transactionBody, SENDER_ID))
.willThrow(new HandleException(INVALID_CONTRACT_ID));
given(hevmTransactionFactory.fromContractTxException(any(), any())).willReturn(HEVM_Exception);

Expand Down Expand Up @@ -467,4 +472,14 @@ void givenSenderAccount() {
given(rootProxyWorldUpdater.getHederaAccount(SENDER_ID)).willReturn(senderAccount);
given(senderAccount.getNonce()).willReturn(1L);
}

void givenBodyWithTxnIdWillReturnHEVM() {
final var body = TransactionBody.newBuilder()
.transactionID(TransactionID.DEFAULT)
.build();
final var payer = AccountID.DEFAULT;
given(context.body()).willReturn(body);
given(context.payer()).willReturn(payer);
given(hevmTransactionFactory.fromHapiTransaction(body, payer)).willReturn(HEVM_CREATION);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;

import com.hedera.hapi.node.base.AccountID;
import com.hedera.hapi.node.base.TransactionID;
import com.hedera.hapi.node.contract.EthereumTransactionBody;
import com.hedera.hapi.node.transaction.TransactionBody;
import com.hedera.node.app.hapi.utils.ethereum.EthTxData;
Expand Down Expand Up @@ -177,7 +179,13 @@ void setUpTransactionProcessing() {
customGasCharging);

given(component.contextTransactionProcessor()).willReturn(contextTransactionProcessor);
given(hevmTransactionFactory.fromHapiTransaction(handleContext.body())).willReturn(HEVM_CREATION);
final var body = TransactionBody.newBuilder()
.transactionID(TransactionID.DEFAULT)
.build();
given(handleContext.body()).willReturn(body);
given(handleContext.payer()).willReturn(AccountID.DEFAULT);
given(hevmTransactionFactory.fromHapiTransaction(handleContext.body(), handleContext.payer()))
.willReturn(HEVM_CREATION);

given(transactionProcessor.processTransaction(
HEVM_CREATION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,9 @@ void fromHapiCreationSkips0xPrefixFromInitcodeIfPresent() {

@Test
void fromHapiTransactionThrowsOnNonContractOperation() {
assertThrows(IllegalArgumentException.class, () -> subject.fromHapiTransaction(TransactionBody.DEFAULT));
assertThrows(
IllegalArgumentException.class,
() -> subject.fromHapiTransaction(TransactionBody.DEFAULT, AccountID.DEFAULT));
}

@Test
Expand Down Expand Up @@ -627,53 +629,65 @@ private void assertCreateFailsWith(
@NonNull final Consumer<ContractCreateTransactionBody.Builder> spec) {
assertFailsWith(
status,
() -> subject.fromHapiTransaction(TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCreateInstance(createWith(spec))
.build()));
() -> subject.fromHapiTransaction(
TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCreateInstance(createWith(spec))
.build(),
SENDER_ID));
}

private void assertCallFailsWith(
@NonNull final ResponseCodeEnum status, @NonNull final Consumer<ContractCallTransactionBody.Builder> spec) {
assertFailsWith(
status,
() -> subject.fromHapiTransaction(TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCall(callWith(spec))
.build()));
() -> subject.fromHapiTransaction(
TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCall(callWith(spec))
.build(),
SENDER_ID));
}

private void assertEthTxFailsWith(
@NonNull final ResponseCodeEnum status, @NonNull final Consumer<EthereumTransactionBody.Builder> spec) {
assertFailsWith(
status,
() -> subject.fromHapiTransaction(TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.ethereumTransaction(ethTxWith(spec))
.build()));
() -> subject.fromHapiTransaction(
TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.ethereumTransaction(ethTxWith(spec))
.build(),
SENDER_ID));
}

private HederaEvmTransaction getManufacturedEthTx(@NonNull final Consumer<EthereumTransactionBody.Builder> spec) {
return subject.fromHapiTransaction(TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(RELAYER_ID))
.ethereumTransaction(ethTxWith(spec))
.build());
return subject.fromHapiTransaction(
TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(RELAYER_ID))
.ethereumTransaction(ethTxWith(spec))
.build(),
RELAYER_ID);
}

private HederaEvmTransaction getManufacturedCreation(
@NonNull final Consumer<ContractCreateTransactionBody.Builder> spec) {
return subject.fromHapiTransaction(TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCreateInstance(createWith(spec))
.build());
return subject.fromHapiTransaction(
TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCreateInstance(createWith(spec))
.build(),
SENDER_ID);
}

private HederaEvmTransaction getManufacturedCall(
@NonNull final Consumer<ContractCallTransactionBody.Builder> spec) {
return subject.fromHapiTransaction(TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCall(callWith(spec))
.build());
return subject.fromHapiTransaction(
TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder().accountID(SENDER_ID))
.contractCall(callWith(spec))
.build(),
SENDER_ID);
}

private HederaEvmTransaction getManufacturedCallException(
Expand Down
Loading

0 comments on commit b85211e

Please sign in to comment.