Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions packages/relay/src/lib/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,9 @@ export class DebugImpl implements Debug {
// The actions endpoint does not return input and output for the calls so we get them from another endpoint
// The first one is excluded because we take its input and output from the contracts/results/{transactionIdOrHash} endpoint
const contract =
index !== 0 && (
action.call_operation_type === CallType.CREATE || action.call_operation_type === CallType.CREATE2
) && action.to
index !== 0 &&
(action.call_operation_type === CallType.CREATE || action.call_operation_type === CallType.CREATE2) &&
action.to
? await this.mirrorNodeClient.getContract(action.to, requestDetails)
: undefined;

Expand Down Expand Up @@ -459,7 +459,7 @@ export class DebugImpl implements Debug {
transactionHash: string,
tracerConfig: ICallTracerConfig,
requestDetails: RequestDetails,
): Promise<CallTracerResult | null> {
): Promise<CallTracerResult> {
try {
const [actionsResponse, transactionsResponse] = await Promise.all([
this.mirrorNodeClient.getContractsResultsActions(transactionHash, requestDetails),
Expand All @@ -473,9 +473,6 @@ export class DebugImpl implements Debug {
throw predefined.RESOURCE_NOT_FOUND(`Failed to retrieve contract results for transaction ${transactionHash}`);
}

// return empty array if no actions
if (actionsResponse.length === 0) return null;

const { call_type: type } = actionsResponse[0];
const formattedActions = await this.formatActionsResult(actionsResponse, requestDetails);

Expand Down Expand Up @@ -510,7 +507,7 @@ export class DebugImpl implements Debug {
// if we have more than one call executed during the transactions we would return all calls
// except the first one in the sub-calls array,
// therefore we need to exclude the first one from the actions response
calls: tracerConfig?.onlyTopCall || actionsResponse.length === 1 ? undefined : formattedActions.slice(1),
calls: tracerConfig?.onlyTopCall || actionsResponse.length === 1 ? [] : formattedActions.slice(1),
};
} catch (e) {
throw this.common.genericErrorHandler(e);
Expand Down
24 changes: 19 additions & 5 deletions packages/relay/tests/lib/debug.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ describe('Debug API Test Suite', async function () {
gasUsed: '0x3a980',
input: '0x1',
output: '0x2',
calls: undefined,
calls: [],
};
const result = await debugService.traceTransaction(
transactionHash,
Expand All @@ -418,17 +418,31 @@ describe('Debug API Test Suite', async function () {

expect(result).to.deep.equal(expectedResult);
});

it('Should return empty array if no actions found', async function () {
restMock.onGet(CONTARCTS_RESULTS_ACTIONS).reply(200, JSON.stringify({ actions: [] }));
it('should return empty calls array when using callTracer with single action (no internal calls)', async function () {
const singleActionResponse = {
actions: [contractsResultsActionsResult.actions[0]], // Only the root action
};
restMock.onGet(CONTARCTS_RESULTS_ACTIONS).reply(200, JSON.stringify(singleActionResponse));

const result = await debugService.traceTransaction(
transactionHash,
tracerObjectCallTracerFalse,
requestDetails,
);

expect(result).to.be.null;
const expectedResult = {
type: 'CREATE',
from: accountsResult.evm_address,
to: contractResult.evm_address,
value: '0x0',
gas: '0x493e0',
gasUsed: '0x3a980',
input: '0x1',
output: '0x2',
calls: [],
};

expect(result).to.deep.equal(expectedResult);
});
});

Expand Down
3 changes: 2 additions & 1 deletion packages/server/tests/acceptance/debug.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,8 @@ describe('@debug API Acceptance Tests', function () {
accounts[0].address,
parentContractAddress,
);
expect(result).to.not.have.property('calls');
expect(result).to.have.property('calls');
expect(result.calls).to.be.an('array').that.is.empty;
});
});

Expand Down
4 changes: 4 additions & 0 deletions packages/server/tests/acceptance/rpc_batch3.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () {
gasUsed: '0x249f00',
input: '',
output: '',
calls: [],
};
const successResultCreateWithDepth = {
...defaultResponseFields,
Expand All @@ -1152,6 +1153,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () {
const successResultCall = {
...defaultResponseFields,
type: 'CALL',
calls: [],
};
const successResultCallWithDepth = {
...successResultCall,
Expand All @@ -1173,12 +1175,14 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () {
error: 'CONTRACT_EXECUTION_EXCEPTION',
revertReason: 'INSUFFICIENT_STACK_ITEMS',
gasUsed: '0x2dc6c0',
calls: [],
};
const failingResultCall = {
...defaultResponseFields,
type: 'CALL',
error: 'CONTRACT_REVERT_EXECUTED',
revertReason: 'Some revert message',
calls: [],
};

describe('Test transactions of type 0', async function () {
Expand Down
Loading