-
Notifications
You must be signed in to change notification settings - Fork 112
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor ContractDebugServiceTest dynamic calls, nested calls enum (#…
…9179) This pr refactors ContractDebugServiceTest. Migrated tests from ContractDebugServiceTest that uses DynamicCallsContractFunctions. Test were migrated into ContractCallDynamicCallsTests as it also tests DynamicCallsContractFunctions. We just add the opcode assertions in the already existing tests there since they use the same setup. This also decreases the time for all tests to run. Moved NestedEthCallContractFunctionsNegativeCases to the nested calls test classes and just added opcode tracer assertions in the specified test. This PR modifies: ContractDebugServiceTest - removed ContractDebugServiceTest function. ContractCallDynamicCallsTests - added debug trace assertions in the tests testing dynamic calls functions - uses exactly the same function of the removed evmDynamicCallsTokenFunctions. ContractCallNestedCallsTest - added debug trace assertions in the tests. ContractCallNestedCallsHistoricalTest - added debug trace assertions in the tests. Deleted ContractDebugServiceTests as all test cases are moved to the above mentioned classes. This pr is related to #8944 but there will be a couple of prs more in future before we can close this task. --------- Signed-off-by: Kristiyan Selveliev <[email protected]>
- Loading branch information
1 parent
764b172
commit df09959
Showing
6 changed files
with
324 additions
and
746 deletions.
There are no files selected for viewing
134 changes: 134 additions & 0 deletions
134
...test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceOpcodeTracerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/* | ||
* Copyright (C) 2024 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.mirror.web3.service; | ||
|
||
import static com.hedera.mirror.web3.utils.OpcodeTracerUtil.OPTIONS; | ||
import static com.hedera.mirror.web3.utils.OpcodeTracerUtil.gasComparator; | ||
import static com.hedera.mirror.web3.utils.OpcodeTracerUtil.toHumanReadableMessage; | ||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; | ||
import static org.mockito.Mockito.doAnswer; | ||
|
||
import com.hedera.mirror.web3.common.ContractCallContext; | ||
import com.hedera.mirror.web3.convert.BytesDecoder; | ||
import com.hedera.mirror.web3.evm.contracts.execution.OpcodesProcessingResult; | ||
import com.hedera.mirror.web3.service.model.ContractDebugParameters; | ||
import com.hedera.mirror.web3.utils.ContractFunctionProviderRecord; | ||
import com.hedera.node.app.service.evm.contracts.execution.HederaEvmTransactionProcessingResult; | ||
import jakarta.annotation.Resource; | ||
import lombok.SneakyThrows; | ||
import org.apache.tuweni.bytes.Bytes; | ||
import org.hyperledger.besu.datatypes.Address; | ||
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.Captor; | ||
import org.web3j.tx.Contract; | ||
|
||
abstract class AbstractContractCallServiceOpcodeTracerTest extends AbstractContractCallServiceTest { | ||
|
||
@Resource | ||
protected ContractDebugService contractDebugService; | ||
|
||
@Captor | ||
private ArgumentCaptor<ContractDebugParameters> paramsCaptor; | ||
|
||
@Captor | ||
private ArgumentCaptor<Long> gasCaptor; | ||
|
||
private HederaEvmTransactionProcessingResult resultCaptor; | ||
private ContractCallContext contextCaptor; | ||
|
||
@BeforeEach | ||
void setUpArgumentCaptors() { | ||
doAnswer(invocation -> { | ||
final var transactionProcessingResult = | ||
(HederaEvmTransactionProcessingResult) invocation.callRealMethod(); | ||
resultCaptor = transactionProcessingResult; | ||
contextCaptor = ContractCallContext.get(); | ||
return transactionProcessingResult; | ||
}) | ||
.when(processor) | ||
.execute(paramsCaptor.capture(), gasCaptor.capture()); | ||
} | ||
|
||
protected void verifyOpcodeTracerCall( | ||
final String callData, final ContractFunctionProviderRecord functionProvider) { | ||
final var callDataBytes = Bytes.fromHexString(callData); | ||
final var debugParameters = getDebugParameters(functionProvider, callDataBytes); | ||
|
||
if (functionProvider.expectedErrorMessage() != null) { | ||
verifyThrowingOpcodeTracerCall(debugParameters, functionProvider); | ||
} else { | ||
verifySuccessfulOpcodeTracerCall(debugParameters); | ||
} | ||
assertThat(paramsCaptor.getValue()).isEqualTo(debugParameters); | ||
assertThat(gasCaptor.getValue()).isEqualTo(debugParameters.getGas()); | ||
} | ||
|
||
protected void verifyOpcodeTracerCall(final String callData, final Contract contract) { | ||
ContractFunctionProviderRecord functionProvider = ContractFunctionProviderRecord.builder() | ||
.contractAddress(Address.fromHexString(contract.getContractAddress())) | ||
.build(); | ||
|
||
final var callDataBytes = Bytes.fromHexString(callData); | ||
final var debugParameters = getDebugParameters(functionProvider, callDataBytes); | ||
|
||
if (functionProvider.expectedErrorMessage() != null) { | ||
verifyThrowingOpcodeTracerCall(debugParameters, functionProvider); | ||
} else { | ||
verifySuccessfulOpcodeTracerCall(debugParameters); | ||
} | ||
assertThat(paramsCaptor.getValue()).isEqualTo(debugParameters); | ||
assertThat(gasCaptor.getValue()).isEqualTo(debugParameters.getGas()); | ||
} | ||
|
||
@SneakyThrows | ||
protected void verifyThrowingOpcodeTracerCall( | ||
final ContractDebugParameters params, final ContractFunctionProviderRecord function) { | ||
final var actual = contractDebugService.processOpcodeCall(params, OPTIONS); | ||
assertThat(actual.transactionProcessingResult().isSuccessful()).isFalse(); | ||
assertThat(actual.transactionProcessingResult().getOutput()).isEqualTo(Bytes.EMPTY); | ||
assertThat(actual.transactionProcessingResult()) | ||
.satisfiesAnyOf( | ||
result -> assertThat(result.getRevertReason()) | ||
.isPresent() | ||
.map(BytesDecoder::maybeDecodeSolidityErrorStringToReadableMessage) | ||
.hasValue(function.expectedErrorMessage()), | ||
result -> assertThat(result.getHaltReason()) | ||
.isPresent() | ||
.map(ExceptionalHaltReason::getDescription) | ||
.hasValue(function.expectedErrorMessage())); | ||
assertThat(actual.opcodes().size()).isNotZero(); | ||
assertThat(toHumanReadableMessage(actual.opcodes().getLast().reason())) | ||
.isEqualTo(function.expectedErrorMessage()); | ||
} | ||
|
||
protected void verifySuccessfulOpcodeTracerCall(final ContractDebugParameters params) { | ||
final var actual = contractDebugService.processOpcodeCall(params, OPTIONS); | ||
final var expected = new OpcodesProcessingResult(resultCaptor, contextCaptor.getOpcodes()); | ||
// Compare transaction processing result | ||
assertThat(actual.transactionProcessingResult()) | ||
.usingRecursiveComparison() | ||
.ignoringFields("logs") | ||
.isEqualTo(expected.transactionProcessingResult()); | ||
// Compare opcodes with gas tolerance | ||
assertThat(actual.opcodes()) | ||
.usingRecursiveComparison() | ||
.withComparatorForFields(gasComparator(), "gas") | ||
.isEqualTo(expected.opcodes()); | ||
} | ||
} |
Oops, something went wrong.