private void handleDepthIncreased(
      final VmOperation op,
      final VmOperationExecutionReport report,
      final Optional<TraceFrame> nextTraceFrame) {
    // check if next frame depth has increased i.e the current operation is a call
    switch (currentOperation) {
      case "STATICCALL":
      case "DELEGATECALL":
      case "CALLCODE":
      case "CALL":
      case "CREATE":
      case "CREATE2":
        if (currentOperation.equals("CALL") || currentOperation.equals("DELEGATECALL")) {
          findReturnInCall(currentTraceFrame, currentIndex)
              .map(output -> new Mem(output.getOutputData().toHexString(), 0))
              .ifPresent(report::setMem);
        }

        findLastFrameInCall(currentTraceFrame, currentIndex)
            .ifPresent(
                lastFrameInCall -> {
                  report.setUsed(lastFrameInCall.getGasRemaining());
                  lastFrameInCall
                      .getStack()
                      .filter(stack -> stack.length > 0)
                      .map(stack -> stack[stack.length - 1])
                      .map(last -> Quantity.create(UInt256.fromHexString(last.toHexString())))
                      .ifPresent(report::singlePush);
                  if (!currentOperation.startsWith("CREATE")) {
                    lastFrameInCall
                        .getMaybeUpdatedMemory()
                        .map(mem -> new Mem(mem.getValue().toHexString(), mem.getOffset()))
                        .ifPresent(report::setMem);
                  }
                });

        if (currentTraceFrame.getMaybeCode().map(Code::getSize).orElse(0) > 0) {
          if (nextTraceFrame.map(TraceFrame::getDepth).orElse(0) > currentTraceFrame.getDepth()) {
            op.setCost(currentTraceFrame.getGasRemainingPostExecution() + op.getCost());
            final VmTrace newSubTrace = new VmTrace();
            parentTraces.addLast(newSubTrace);
            op.setSub(newSubTrace);
          } else if (currentTraceFrame.getDepth() == 0) {
            op.setCost(
                currentTraceFrame.getGasRemaining()
                    - currentTraceFrame.getGasRemainingPostExecution());
            currentTraceFrame
                .getMaybeCode()
                .ifPresent(
                    code ->
                        op.setSub(
                            new VmTrace(
                                currentTraceFrame.getMaybeCode().get().getBytes().toHexString())));
          } else {
            op.setCost(op.getCost());
            op.setSub(null);
          }
        } else {
          if (currentTraceFrame.getPrecompiledGasCost().isPresent()) {
            op.setCost(op.getCost() + currentTraceFrame.getPrecompiledGasCost().orElse(0L));
          } else if ((currentOperation.equals("STATICCALL") || currentOperation.equals("CALL"))
              && nextTraceFrame.map(TraceFrame::getDepth).orElse(0)
                  > currentTraceFrame.getDepth()) {
            op.setCost(currentTraceFrame.getGasRemainingPostExecution() + op.getCost());
          }
          op.setSub(new VmTrace());
        }
        break;
      default:
        break;
    }
  }
Add a trace frame to the VmTrace result object.

@param frame the current trace frame
ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/vm/VmTraceGenerator.java