Skip to content

Commit

Permalink
Implementation check for Debug endpoints and eth_sendTransaction endp…
Browse files Browse the repository at this point in the history
…oint (#570)

* fix: change a little bit debug rpc output endpoints

* fix: typo
  • Loading branch information
rodolfopietro97 authored Feb 15, 2024
1 parent bafa919 commit bf215d8
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,24 @@ type CallNameConfig = Record<string, unknown>;
* Return type for the 'call' name type
*/
interface CallNameReturnType {
/**
* Transaction parameters
*/
from: string;
gas: string;
gasUsed: string;
to: string;
input: string;
output: string;
// Trace clause type (/debug/tracers endpoint)

/**
* Transaction errors (if any)
*/
error?: string;

/**
* Trace clause type (/debug/tracers endpoint)
*/
calls?: Array<{
from: string;
gas: string;
Expand All @@ -23,7 +34,10 @@ interface CallNameReturnType {
output: string;
type: string;
}>;
// Trace contract type (/debug/tracers/call endpoint)

/**
* Trace contract type (/debug/tracers/call endpoint)
*/
value?: string;
type?: string;
}
Expand Down
49 changes: 49 additions & 0 deletions packages/provider/src/utils/formatter/debug/formatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { type TraceReturnType } from '@vechain/vechain-sdk-network/src/thor-client/debug';
import { type TracerNameRPC, type TracerReturnTypeRPC } from './types';

/**
* Output formatter for RPC debug endpoints:
* * debug_traceTransaction
* * debug_traceCall
* It converts our endpoint calls output to the RPC standard output.
*
* @param tracerName - Tracer name used for the debug endpoint.
* @param debugDetails - Debug details to be formatted.
*/
function formatToRPCStandard<TDebugType extends TracerNameRPC>(
tracerName: TDebugType,
debugDetails: TraceReturnType<TDebugType>
): TracerReturnTypeRPC<'call'> | TracerReturnTypeRPC<'prestate'> {
if (tracerName === 'call') {
return {
...(debugDetails as TraceReturnType<'call'>),

// Empty revert reason
revertReason: ''
} satisfies TracerReturnTypeRPC<'call'>;
}

return Object.fromEntries(
Object.entries(debugDetails as TraceReturnType<'prestate'>).map(
([key, value]) => {
const valueWithoutEnergy = {
balance: value.balance,
code: value.code,
storage: value.storage
} satisfies Omit<
{
balance: string;
energy: string;
code?: string;
storage?: Record<string, string>;
},
'energy'
>;

return [key, { ...valueWithoutEnergy, nonce: 0 }];
}
)
) satisfies TracerReturnTypeRPC<'prestate'>;
}

export { formatToRPCStandard };
8 changes: 8 additions & 0 deletions packages/provider/src/utils/formatter/debug/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { formatToRPCStandard } from './formatter';

export * from './formatter';
export * from './types.d';

export const debugFormatter = {
formatToRPCStandard
};
58 changes: 58 additions & 0 deletions packages/provider/src/utils/formatter/debug/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { type TraceReturnType } from '@vechain/vechain-sdk-network/src/thor-client/debug';

/**
* Return type for the following RPC endpoints:
* * debug_traceTransaction
* * debug_traceCall
*/
type TracerReturnTypeRPC<TracerNameType extends TracerNamesRPC> =
TracerNameType extends 'call' ? CallTracerRPC : PrestateTracerRPC;

/**
* Available tracers for the RPC standard.
*/
type TracerNameRPC = 'call' | 'prestate';

/**
* The return type of the 'call' tracer for the RPC standard.
*/
type CallTracerRPC = TraceReturnType<'call'> & {
/**
* Same of the 'call' tracer of vechain,
* BUT with the addition of the revertReason field.
*
* @note This is not part of the vechain's 'call' tracer.
* For this reason, it will have a default value of ''.
*/
revertReason?: '';
};

/**
* The return type of the 'prestate' tracer for the RPC standard.
*/
type PrestateTracerRPC = Record<
string,
{
balance: string;
code?: string;
storage?: Record<string, string>;

/**
* Same of the 'prestate' tracer of vechain,
* BUT with the addition of the nonce field.
* This field substitutes the 'energy' field
* of the vechain's 'prestate' tracer.
*
* @note This is not part of the vechain's 'prestate' tracer.
* For this reason, it will have a default value of 0.
*/
nonce: 0;
}
>;

export type {
TracerReturnTypeRPC,
TracerNameRPC,
CallTracerRPC,
PrestateTracerRPC
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import type {
TraceReturnType,
TracerName
} from '@vechain/vechain-sdk-network/src/thor-client/debug';
import {
debugFormatter,
type TracerReturnTypeRPC
} from '../../../formatter/debug';

/**
* Type for trace options
Expand Down Expand Up @@ -56,7 +60,7 @@ interface TransactionObjectInput {
const debugTraceCall = async (
thorClient: ThorClient,
params: unknown[]
): Promise<TraceReturnType<'call'> | TraceReturnType<'prestate'>> => {
): Promise<TracerReturnTypeRPC<'call'> | TracerReturnTypeRPC<'prestate'>> => {
assert(
params.length === 3 &&
typeof params[0] === 'object' &&
Expand Down Expand Up @@ -87,7 +91,7 @@ const debugTraceCall = async (
tracerOptions.tracer === 'callTracer' ? 'call' : 'prestate';

try {
return (await thorClient.debug.traceContractCall(
const trace = (await thorClient.debug.traceContractCall(
{
transactionOptions: {
caller: transactionOptions.from,
Expand All @@ -105,6 +109,11 @@ const debugTraceCall = async (
},
tracerToUse
)) as TraceReturnType<'call'> | TraceReturnType<'prestate'>;

return debugFormatter.formatToRPCStandard(
tracerToUse as 'call' | 'prestate',
trace
);
} catch (e) {
throw buildProviderError(
JSONRPC.INTERNAL_ERROR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,12 @@ import type {
TraceReturnType,
TracerName
} from '@vechain/vechain-sdk-network/src/thor-client/debug';
import { ethGetTransactionReceipt } from './eth_getTransactionReceipt';

/**
* Type for trace options
*/
interface TraceOptionsRPC {
tracer: 'callTracer' | 'prestateTracer';
tracerConfig?: { onlyTopCall?: boolean };
// Not supported yet
timeout?: string;
}
import { ethGetTransactionReceipt } from '../eth_getTransactionReceipt';
import { type TraceOptionsRPC } from './types';
import {
debugFormatter,
type TracerReturnTypeRPC
} from '../../../../formatter/debug';

/**
* RPC Method debug_traceTransaction implementation
Expand All @@ -44,7 +39,7 @@ interface TraceOptionsRPC {
const debugTraceTransaction = async (
thorClient: ThorClient,
params: unknown[]
): Promise<TraceReturnType<'call'> | TraceReturnType<'prestate'>> => {
): Promise<TracerReturnTypeRPC<'call'> | TracerReturnTypeRPC<'prestate'>> => {
// Check input params
assert(
params.length === 2 &&
Expand Down Expand Up @@ -74,7 +69,7 @@ const debugTraceTransaction = async (
transactionId
]);

return (await thorClient.debug.traceTransactionClause(
const trace = (await thorClient.debug.traceTransactionClause(
{
target: {
blockID: transactionReceipt?.blockHash as string,
Expand All @@ -85,6 +80,11 @@ const debugTraceTransaction = async (
},
tracerToUse
)) as TraceReturnType<'call'> | TraceReturnType<'prestate'>;

return debugFormatter.formatToRPCStandard(
tracerToUse as 'call' | 'prestate',
trace
);
} catch (e) {
throw buildProviderError(
JSONRPC.INTERNAL_ERROR,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './debug_traceTransaction';
export * from './types.d';
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Type for trace options
*/
interface TraceOptionsRPC {
tracer: 'callTracer' | 'prestateTracer';
tracerConfig?: { onlyTopCall?: boolean };
// Not supported yet
timeout?: string;
}

export type { TraceOptionsRPC };
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ const ethSendTransaction = async (
);

// 3 - Get the signed transaction (we already know wallet is defined, thanks to the input validation)
const delegatorIntoWallet: SignTransactionOptions | null = await (
provider?.wallet as Wallet
).getDelegator();
const walletTouse: Wallet = provider?.wallet as Wallet;

const signerIntoWallet: WalletAccount | null = await (
provider?.wallet as Wallet
).getAccount(transaction.from);
const delegatorIntoWallet: SignTransactionOptions | null =
await walletTouse.getDelegator();

const signerIntoWallet: WalletAccount | null =
await walletTouse.getAccount(transaction.from);

// 4 - Create transaction body
const transactionBody =
Expand Down
19 changes: 9 additions & 10 deletions packages/provider/src/utils/rpc-mapper/rpc-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import {
import { ethRequestAccounts } from './methods-map/methods/eth_requestAccounts';
import { type LogsRPC } from '../formatter/logs';
import { type VechainProvider } from '../../providers';
import { type TraceReturnType } from '@vechain/vechain-sdk-network/src/thor-client/debug';
import { type TracerReturnTypeRPC } from '../formatter/debug';

/**
* Map of RPC methods to their implementations with the SDK.
Expand Down Expand Up @@ -213,19 +213,18 @@ const RPCMethodsMap = (

[RPC_METHODS.debug_traceTransaction]: async (
params
): Promise<TraceReturnType<'call'> | TraceReturnType<'prestate'>> => {
const transactionTrace = await debugTraceTransaction(
thorClient,
params
);
return transactionTrace;
): Promise<
TracerReturnTypeRPC<'call'> | TracerReturnTypeRPC<'prestate'>
> => {
return await debugTraceTransaction(thorClient, params);
},

[RPC_METHODS.debug_traceCall]: async (
params
): Promise<TraceReturnType<'call'> | TraceReturnType<'prestate'>> => {
const callTrace = await debugTraceCall(thorClient, params);
return callTrace;
): Promise<
TracerReturnTypeRPC<'call'> | TracerReturnTypeRPC<'prestate'>
> => {
return await debugTraceCall(thorClient, params);
},

[RPC_METHODS.evm_mine]: async (): Promise<BlocksRPC | null> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ const debugTraceCallPositiveCasesFixtureTestnet = [
input: '0xa9059cbb0000000000000000000000000000000000000000000000000000456e65726779000000000000000000000000000000000000000000000004563918244f400000',
output: '0x0000000000000000000000000000000000000000000000000000000000000001',
value: '0x0',
type: 'CALL'
type: 'CALL',
revertReason: ''
}
}
},
Expand Down Expand Up @@ -63,7 +64,8 @@ const debugTraceCallPositiveCasesFixtureTestnet = [
input: '0x6080604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b4578063095ea7b31461014457806318160ddd146101a957806323b872dd146101d4578063313ce5671461025957806370a082311461028a57806395d89b41146102e1578063a9059cbb14610371578063bb35783b146103d6578063d89135cd1461045b578063dd62ed3e14610486575b600080fd5b3480156100c057600080fd5b506100c96104fd565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101095780820151818401526020810190506100ee565b50505050905090810190601f1680156101365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015057600080fd5b5061018f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061053a565b604051808215151515815260200191505060405180910390f35b3480156101b557600080fd5b506101be61062b565b6040518082815260200191505060405180910390f35b3480156101e057600080fd5b5061023f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106d1565b604051808215151515815260200191505060405180910390f35b34801561026557600080fd5b5061026e610865565b604051808260ff1660ff16815260200191505060405180910390f35b34801561029657600080fd5b506102cb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061086e565b6040518082815260200191505060405180910390f35b3480156102ed57600080fd5b506102f661094d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033657808201518184015260208101905061031b565b50505050905090810190601f1680156103635780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561037d57600080fd5b506103bc600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061098a565b604051808215151515815260200191505060405180910390f35b3480156103e257600080fd5b50610441600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506109a1565b604051808215151515815260200191505060405180910390f35b34801561046757600080fd5b50610470610b67565b6040518082815260200191505060405180910390f35b34801561049257600080fd5b506104e7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c0d565b6040518082815260200191505060405180910390f35b60606040805190810160405280600681526020017f566554686f720000000000000000000000000000000000000000000000000000815250905090565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1663592b389c6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561069157600080fd5b505af11580156106a5573d6000803e3d6000fd5b505050506040513d60208110156106bb57600080fd5b8101908080519060200190929190505050905090565b6000816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156107c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6275696c74696e3a20696e73756666696369656e7420616c6c6f77616e63650081525060200191505060405180910390fd5b816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555061085a848484610c93565b600190509392505050565b60006012905090565b60003073ffffffffffffffffffffffffffffffffffffffff1663ee660480836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561090b57600080fd5b505af115801561091f573d6000803e3d6000fd5b505050506040513d602081101561093557600080fd5b81019080805190602001909291905050509050919050565b60606040805190810160405280600481526020017f5654484f00000000000000000000000000000000000000000000000000000000815250905090565b6000610997338484610c93565b6001905092915050565b60003373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610add57503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1663059950e9866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610a8a57600080fd5b505af1158015610a9e573d6000803e3d6000fd5b505050506040513d6020811015610ab457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16145b1515610b51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f6275696c74696e3a2073656c66206f72206d617374657220726571756972656481525060200191505060405180910390fd5b610b5c848484610c93565b600190509392505050565b60003073ffffffffffffffffffffffffffffffffffffffff1663138d4d0c6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610bcd57600080fd5b505af1158015610be1573d6000803e3d6000fd5b505050506040513d6020811015610bf757600080fd5b8101908080519060200190929190505050905090565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000811115610eaa573073ffffffffffffffffffffffffffffffffffffffff166339ed08d584836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610d3f57600080fd5b505af1158015610d53573d6000803e3d6000fd5b505050506040513d6020811015610d6957600080fd5b81019080805190602001909291905050501515610dee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6275696c74696e3a20696e73756666696369656e742062616c616e636500000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16631cedfac183836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610e9157600080fd5b505af1158015610ea5573d6000803e3d6000fd5b505050505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050505600a165627a7a72305820bd55cb9aff347dc60fe8280ae6b08a6f6deacc85a4e1c89ba0a8ef31fbcaecc60029',
error: 'execution reverted',
value: '0x0',
type: 'CREATE'
type: 'CREATE',
revertReason: ''
}
}
}
Expand Down
Loading

1 comment on commit bf215d8

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Coverage

Summary

Lines Statements Branches Functions
Coverage: 100%
100% (2535/2535) 100% (527/527) 100% (530/530)
Title Tests Skipped Failures Errors Time
core 409 0 💤 0 ❌ 0 🔥 1m 8s ⏱️
network 234 0 💤 0 ❌ 0 🔥 2m 28s ⏱️
errors 43 0 💤 0 ❌ 0 🔥 9.5s ⏱️

Please sign in to comment.