Skip to content

Commit

Permalink
Implementation check for RPC methods - part 1 (#555)
Browse files Browse the repository at this point in the history
* fix: improve chain_id RPC and relative tests

* fix: update eth_getBalance comments

* fix: update eth_getCode comments

* fix: update comments for eth_getStorageAt

* fix: rename format functions

* fix: update eth_getBlockByHash comments

* fix: remove unused interface and improve comments

* fix: improve code quality

* fix: improve eth_chainId

* fix: update eth_chainId

* fix: chainid

---------

Co-authored-by: rodolfopietro97 <[email protected]>
  • Loading branch information
fabiorigam and rodolfopietro97 authored Feb 14, 2024
1 parent d1e7635 commit 8707ec8
Show file tree
Hide file tree
Showing 15 changed files with 56 additions and 111 deletions.
62 changes: 0 additions & 62 deletions packages/provider/src/providers/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,68 +123,6 @@ interface SubscriptionManager {
*/
type EventEmitterable<T> = vechain_sdk_core_ethers.EventEmitterable<T>;

/**
* ----- TEMPORARY COMMENT -----
* ContractRunner is an ethers interface which is used by ether's Provider.
* We can change the naming if needed.
* -----------------------------
*/
interface ContractRunner {
/**
* Required to estimate gas.
*
* ----- TEMPORARY COMMENT -----
* estimateGas will call `estimateGas` method which will be defined by the driver.
* estimateGas will use Transaction.intrinsicGas() + the explainer functionality of driver-no-vendor.
*
* @param tx - TransactionRequest can be refactored to our `TransactionBody` (core/src/transaction/types.d.ts)
* and then internally we perform all operations needed (e.g., creation of `Transaction` object and calculation of estimateGas)
*
* TO_MODIFY - typesafety
* -----------------------------
*/
estimateGas?: (tx: TransactionRequest) => Promise<bigint>;

/**
* Required for pure, view or static calls to contracts
*
* ----- TEMPORARY COMMENT -----
* call can be implemented by using call() of account-visitor.ts or compat.ts
* This depends on driver-no-vendor that uses httpPost and creates a query for Simple net's `query` NetParam
*
* TO_MODIFY - typesafety
* -----------------------------
*/
call?: (tx: TransactionRequest) => Promise<string>;

/**
* Required to support ENS names
*
* ----- TEMPORARY COMMENT -----
* resolveName will not be used in first release.
* Maybe we can consider it in the future when VNS is supported.
*
* TO_MODIFY - typesafety
* -----------------------------
*/
resolveName?: (name: string) => Promise<null | string>;

/**
* Required for state mutating calls
*
* ----- TEMPORARY COMMENT -----
* sendTransaction will call `sendTransaction` method which will be implemented in driver.
* Internally we will get the raw tx needed to `sendTransaction`.
*
* @param tx - TransactionRequest can be refactored to our `Transaction` (core/src/transaction/types.d.ts)
* in this case we need to create a `Transaction` object that is signed.
*
* TO_MODIFY - typesafety
* -----------------------------
*/
sendTransaction?: (tx: TransactionRequest) => Promise<TransactionResponse>;
}

export {
type EventEmitterable,
type SubscriptionEvent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ enum RPC_METHODS {
/**
* ----- TEMPORARY COMMENT -----
* STATUS:
* * Implemented in web3-provviders-connex: False (AND NOT LISTED in `EthJsonRpcMethods`array in `src/common.ts` file. Probably NEW methods)
* * Implemented in web3-providers-connex: False (AND NOT LISTED in `EthJsonRpcMethods`array in `src/common.ts` file. Probably NEW methods)
* * Required for hardhat: False (BUT WE MUST INVESTIGATE IT BETTER) -> @see https://github.com/vechain/vechain-sdk/issues/462
* * Possible to implement: TO UNDERSTAND
*
Expand Down
2 changes: 1 addition & 1 deletion packages/provider/src/utils/formatter/blocks/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const formatToRPCStandard = (
typeof block.transactions[0] === 'string'
? (block.transactions as string[])
: block.transactions.map((tx, index) => {
return transactionsFormatter.formatFromExpandedBlockToRPCStandard(
return transactionsFormatter.formatExpandedBlockToRPCStandard(
tx as TransactionsExpandedBlockDetail,
block,
index,
Expand Down
14 changes: 7 additions & 7 deletions packages/provider/src/utils/formatter/transactions/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const _formatTransactionToRPC = (

/**
* `input`, `to`, `value` are being referred to the first clause.
* Vechain supports multiple clauses in one transaction, thus the actual data should obtained by looking into each clause.
* Vechain supports multiple clauses in one transaction, thus the actual data should be obtained by looking into each clause.
* Due to the single clause limitation of Ethereum, we assume the first clause is the clause from which we obtain the data.
*/
input: tx.clauses[0].data,
Expand Down Expand Up @@ -107,7 +107,7 @@ const formatToRPCStandard = (
*
* @returns The RPC standard formatted transaction.
*/
const formatFromExpandedBlockToRPCStandard = (
const formatExpandedBlockToRPCStandard = (
tx: TransactionsExpandedBlockDetail,
block: BlockDetail,
txIndex: number,
Expand All @@ -132,7 +132,7 @@ const formatFromExpandedBlockToRPCStandard = (
* @param blockContainsTransaction - The block contains the transaction to be formatted.
* @param chainId - The chain ID of the network.
*/
function formatFromTransactionReceiptToRPCStandard(
function formatTransactionReceiptToRPCStandard(
transactionHash: string,
receipt: TransactionReceipt,
transaction: TransactionDetailNoRaw,
Expand Down Expand Up @@ -213,7 +213,7 @@ function formatFromTransactionReceiptToRPCStandard(
*
* @param transaction - The transaction result to be formatted.
*/
const formatFromSendRawTransactionToRPCStandard = (
const formatSendRawTransactionToRPCStandard = (
transaction: SendTransactionResult
): SendRawTransactionResultRPC => {
return {
Expand All @@ -223,7 +223,7 @@ const formatFromSendRawTransactionToRPCStandard = (

export {
formatToRPCStandard,
formatFromExpandedBlockToRPCStandard,
formatFromTransactionReceiptToRPCStandard,
formatFromSendRawTransactionToRPCStandard
formatExpandedBlockToRPCStandard,
formatTransactionReceiptToRPCStandard,
formatSendRawTransactionToRPCStandard
};
12 changes: 6 additions & 6 deletions packages/provider/src/utils/formatter/transactions/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {
formatFromExpandedBlockToRPCStandard,
formatFromSendRawTransactionToRPCStandard,
formatFromTransactionReceiptToRPCStandard,
formatExpandedBlockToRPCStandard,
formatSendRawTransactionToRPCStandard,
formatTransactionReceiptToRPCStandard,
formatToRPCStandard
} from './formatter';

export * from './types.d';

export const transactionsFormatter = {
formatToRPCStandard,
formatFromExpandedBlockToRPCStandard,
formatFromTransactionReceiptToRPCStandard,
formatFromSendRawTransactionToRPCStandard
formatExpandedBlockToRPCStandard,
formatTransactionReceiptToRPCStandard,
formatSendRawTransactionToRPCStandard
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ import { buildProviderError, JSONRPC } from '@vechain/vechain-sdk-errors';
*
* @param thorClient - ThorClient instance.
*
* @returns The chain id or '0x0' if the chain id is not available.
* @returns The chain id
*/
const ethChainId = async (thorClient: ThorClient): Promise<string> => {
try {
const genesisBlock = await thorClient.blocks.getGenesisBlock();
return genesisBlock?.id ?? '0x0';

if (genesisBlock?.id === null || genesisBlock?.id === undefined) {
throw new Error(
`The genesis block id is null.\n\tgenesisBlock: ${JSON.stringify(genesisBlock)}`
);
}

return genesisBlock.id;
} catch (e) {
throw buildProviderError(
JSONRPC.INTERNAL_ERROR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
*
* @returns the balance of the account at the given address formatted to the RPC standard.
*
* @note Only 'latest' and 'finalized' block numbers are supported.
*
* @throws {ProviderRpcError} - Will throw an error if the retrieval of the balance fails.
*/
const ethGetBalance = async (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const ethGetBlockByHash = async (
thorClient: ThorClient,
params: unknown[]
): Promise<BlocksRPC | null> => {
// Check different params from eth_getBlockByNumber. Otherwise, the logic is the same. Only difference is the block number is replaced by block hash.
assert(
params.length === 2 &&
typeof params[0] === 'string' &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import {
* * params[0]: The address to get the code for as a hex string.
* * params[1]: The block number to get the code at as a hex string or "latest".
*
* @returns the code of the account at the given address formatted to the RPC standard.
* @returns The code of the account at the given address formatted to the RPC standard.
*
* @note Only 'latest' and 'finalized' block numbers are supported.
*
* @throws {ProviderRpcError} - Will throw an error if the retrieval of the code fails.
*/
Expand All @@ -38,11 +40,9 @@ const ethGetCode = async (
if (blockNumber === 'latest') blockNumber = 'best';

// Get the account details
const accountCode = await thorClient.accounts.getBytecode(address, {
return await thorClient.accounts.getBytecode(address, {
revision: blockNumber
});

return accountCode;
} catch (e) {
throw buildProviderError(
JSONRPC.INTERNAL_ERROR,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { dataUtils } from '@vechain/vechain-sdk-core';
import {
DATA,
JSONRPC,
assert,
buildProviderError
buildProviderError,
DATA,
JSONRPC
} from '@vechain/vechain-sdk-errors';
import { type ThorClient } from '@vechain/vechain-sdk-network';

Expand All @@ -18,7 +18,9 @@ import { type ThorClient } from '@vechain/vechain-sdk-network';
* * params[1]: The storage position to get as a hex string.
* * params[2]: The block number to get the storage slot at as a hex string or "latest".
*
* @returns the storage slot of the account at the given address formatted to the RPC standard.
* @returns The storage slot of the account at the given address formatted to the RPC standard.
*
* @note Only 'latest' and 'finalized' block numbers are supported.
*
* @throws {ProviderRpcError} - Will throw an error if the retrieval of the storage slot fails.
*/
Expand All @@ -45,15 +47,13 @@ const ethGetStorageAt = async (
if (blockNumber === 'latest') blockNumber = 'best';

// Get the account details
const accountCode = await thorClient.accounts.getStorageAt(
return await thorClient.accounts.getStorageAt(
address,
dataUtils.padHexString(storagePosition),
{
revision: blockNumber
}
);

return accountCode;
} catch (e) {
throw buildProviderError(
JSONRPC.INTERNAL_ERROR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,15 @@ const ethGetTransactionReceipt = async (
]([])) as string;

// Initialize the result
const result =
transactionsFormatter.formatFromTransactionReceiptToRPCStandard(
hash,
receipt,
transactionDetail,
blockContainsTransaction,
chainId
);

return await Promise.resolve(result);
return transactionsFormatter.formatTransactionReceiptToRPCStandard(
hash,
receipt,
transactionDetail,
blockContainsTransaction,
chainId
);
} else {
return await Promise.resolve(null);
return null;
}
} catch (e) {
throw buildProviderError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const ethSendRawTransaction = async (
signedTransactionData
);

return transactionsFormatter.formatFromSendRawTransactionToRPCStandard(
return transactionsFormatter.formatSendRawTransactionToRPCStandard(
sentTransaction
);
} catch (e) {
Expand Down
4 changes: 2 additions & 2 deletions packages/provider/src/utils/rpc-mapper/rpc-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ import { type VechainProvider } from '../../providers';
import { type TraceReturnType } from '@vechain/vechain-sdk-network/src/thor-client/debug';

/**
* Map of RPC methods to their implementations with our SDK.
* We can consider this as a "RPC Mapper" for our SDK.
* Map of RPC methods to their implementations with the SDK.
* We can consider this as an "RPC Mapper" for the SDK.
*
* List of all RPC methods:
* * https://eth.wiki/json-rpc/API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,9 @@ describe('RPC Mapper - eth_chainId method tests', () => {
null
);

const rpcCallChainId = (await RPCMethodsMap(thorClient)[
RPC_METHODS.eth_chainId
]([])) as string;

expect(rpcCallChainId).toBe('0x0');
await expect(
RPCMethodsMap(thorClient)[RPC_METHODS.eth_chainId]([])
).rejects.toThrowError(ProviderRpcError);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ describe('RPC Mapper - eth_chainId method tests', () => {
RPC_METHODS.eth_chainId
]([])) as string;

expect(rpcCallChainId).toBe(networkInfo.solo.genesisBlock.id);
expect(rpcCallChainId).toBe(
(
networkInfo.solo.genesisBlock.id as unknown as number
).toString(16)
);
});
});
});

1 comment on commit 8707ec8

@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% (2503/2503) 100% (513/513) 100% (528/528)
Title Tests Skipped Failures Errors Time
core 409 0 💤 0 ❌ 0 🔥 1m 26s ⏱️
network 234 0 💤 0 ❌ 0 🔥 2m 49s ⏱️
errors 43 0 💤 0 ❌ 0 🔥 11.394s ⏱️

Please sign in to comment.