Skip to content

Commit

Permalink
improve handleFailedResult to provide info about all transaction reco…
Browse files Browse the repository at this point in the history
…rds for the executed transaction

Signed-off-by: sdimitrov9 <[email protected]>
  • Loading branch information
sdimitrov9 committed Jan 23, 2025
1 parent 753b84f commit facdead
Showing 1 changed file with 45 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.hedera.hapi.node.base.ContractID;
import com.hedera.hapi.node.base.Duration;
import com.hedera.hapi.node.base.FileID;
import com.hedera.hapi.node.base.ResponseCodeEnum;
import com.hedera.hapi.node.base.Timestamp;
import com.hedera.hapi.node.base.TransactionID;
import com.hedera.hapi.node.contract.ContractCallTransactionBody;
Expand All @@ -44,13 +45,15 @@
import com.hedera.mirror.web3.state.keyvalue.AliasesReadableKVState;
import com.hedera.node.app.service.evm.contracts.execution.HederaEvmTransactionProcessingResult;
import com.hedera.node.app.service.token.TokenService;
import com.hedera.node.app.state.SingleTransactionRecord;
import com.hedera.node.config.data.EntitiesConfig;
import com.swirlds.state.State;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Meter.MeterProvider;
import jakarta.inject.Named;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.CustomLog;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -114,11 +117,15 @@ public HederaEvmTransactionProcessingResult execute(
}

var receipt = executor.execute(transactionBody, Instant.now(), getOperationTracers());
var transactionRecord = receipt.getFirst().transactionRecord();
if (transactionRecord.receiptOrThrow().status() == com.hedera.hapi.node.base.ResponseCodeEnum.SUCCESS) {
result = buildSuccessResult(isContractCreate, transactionRecord, params);
var transactionRecords =
receipt.stream().map(SingleTransactionRecord::transactionRecord).toList();
var transactionRecordsStatuses = transactionRecords.stream()
.map(record -> record.receiptOrThrow().status())
.toList();
if (transactionRecordsStatuses.stream().allMatch(com.hedera.hapi.node.base.ResponseCodeEnum.SUCCESS::equals)) {
result = buildSuccessResult(isContractCreate, transactionRecords.getFirst(), params);
} else {
handleFailedResult(transactionRecord, isContractCreate, gasUsedCounter);
handleFailedResult(transactionRecords, isContractCreate, gasUsedCounter);

Check warning on line 128 in hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java

View check run for this annotation

Codecov / codecov/patch

hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java#L128

Added line #L128 was not covered by tests
}
return result;
}
Expand Down Expand Up @@ -155,22 +162,39 @@ private HederaEvmTransactionProcessingResult buildSuccessResult(
}

private void handleFailedResult(
final TransactionRecord transactionRecord,
final List<TransactionRecord> transactionRecords,
final boolean isContractCreate,
final MeterProvider<Counter> gasUsedCounter)
throws MirrorEvmTransactionException {
var result =
isContractCreate ? transactionRecord.contractCreateResult() : transactionRecord.contractCallResult();
var status = transactionRecord.receiptOrThrow().status();
if (result == null) {
var results = isContractCreate
? transactionRecords.stream()
.map(TransactionRecord::contractCreateResult)
.toList()

Check warning on line 172 in hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java

View check run for this annotation

Codecov / codecov/patch

hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java#L170-L172

Added lines #L170 - L172 were not covered by tests
: transactionRecords.stream()
.map(TransactionRecord::contractCallResult)
.toList();
var statuses = transactionRecords.stream()
.map(t -> t.receiptOrThrow().status())
.toList();
if (results.stream().allMatch(Objects::isNull)) {
// No result - the call did not reach the EVM and probably failed at pre-checks. No metric to update in this
// case.
throw new MirrorEvmTransactionException(status.protoName(), StringUtils.EMPTY, StringUtils.EMPTY);
throw new MirrorEvmTransactionException(
String.join(
" -> ",
statuses.stream().map(ResponseCodeEnum::protoName).toList()),
StringUtils.EMPTY,
StringUtils.EMPTY);
} else {
var errorMessage = getErrorMessage(result).orElse(Bytes.EMPTY);
var errorMessage = getErrorMessage(results.getFirst()).orElse(Bytes.EMPTY);
var detail = maybeDecodeSolidityErrorStringToReadableMessage(errorMessage);
updateErrorGasUsedMetric(gasUsedCounter, result.gasUsed(), 1);
throw new MirrorEvmTransactionException(status.protoName(), detail, errorMessage.toHexString());
updateErrorGasUsedMetric(gasUsedCounter, results.getFirst().gasUsed(), 1);
throw new MirrorEvmTransactionException(
String.join(
" -> ",
statuses.stream().map(ResponseCodeEnum::protoName).toList()),
detail,
errorMessage.toHexString());
}
}

Expand All @@ -180,6 +204,14 @@ private Optional<Bytes> getErrorMessage(final ContractFunctionResult result) {
: Optional.empty(); // If it doesn't start with 0x, the message is already decoded and readable.
}

private List<Optional<?>> getErrorMessages(final List<ContractFunctionResult> results) {
return results.stream()

Check warning on line 208 in hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java

View check run for this annotation

Codecov / codecov/patch

hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java#L208

Added line #L208 was not covered by tests
.map(result -> result.errorMessage().startsWith(HEX_PREFIX)
? Optional.of(Bytes.fromHexString(result.errorMessage()))
: Optional.empty())
.toList(); // If it doesn't start with 0x, the message is already decoded and readable.

Check warning on line 212 in hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java

View check run for this annotation

Codecov / codecov/patch

hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java#L210-L212

Added lines #L210 - L212 were not covered by tests
}

private TransactionBody.Builder defaultTransactionBodyBuilder(final CallServiceParameters params) {
return TransactionBody.newBuilder()
.transactionID(TransactionID.newBuilder()
Expand Down

0 comments on commit facdead

Please sign in to comment.