Skip to content

Commit e7975bf

Browse files
authored
feat: make blockNumberOrTagOrHash a required parameter for eth_getStorageAt (#3839) (#3879)
Signed-off-by: Michał Walczak <[email protected]>
1 parent f220ace commit e7975bf

File tree

7 files changed

+11
-75
lines changed

7 files changed

+11
-75
lines changed

packages/relay/src/lib/decorators/cache.decorator.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ const shouldSkipCachingForSingleParams = (args: IArgument[], params: CacheSingle
4949
return true;
5050
}
5151

52-
// do not cache optional parameters like 'blockNumber' on 'eth_getStorageAt'
52+
// do not cache when a parameter is missing or undefined
53+
// this handles cases where optional parameters are not provided
5354
if (!Object.prototype.hasOwnProperty.call(args, item.index) || args[item.index] === undefined) {
5455
return true;
5556
}

packages/relay/src/lib/eth.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -671,15 +671,15 @@ export class EthImpl implements Eth {
671671
*
672672
* @param {string} address - The Ethereum address to get the storage value from
673673
* @param {string} slot - The storage slot to get the value from
674-
* @param {string | null} blockNumberOrTagOrHash - The block number or tag or hash to get the storage value from
674+
* @param {string} blockNumberOrTagOrHash - The block number or tag or hash to get the storage value from
675675
* @param {RequestDetails} requestDetails - The request details for logging and tracking
676676
* @returns {Promise<string>} A promise that resolves to the storage value as a hexadecimal string
677677
*/
678678
@rpcMethod
679679
@rpcParamValidationRules({
680680
0: { type: ParamType.ADDRESS, required: true },
681681
1: { type: ParamType.HEX64, required: true },
682-
2: { type: ParamType.BLOCK_NUMBER_OR_HASH, required: false },
682+
2: { type: ParamType.BLOCK_NUMBER_OR_HASH, required: true },
683683
})
684684
@rpcParamLayoutConfig(RPC_LAYOUT.custom((params) => [params[0], params[1], params[2]]))
685685
@cache(CacheService.getInstance(CACHE_LEVEL.L1), {
@@ -688,7 +688,7 @@ export class EthImpl implements Eth {
688688
async getStorageAt(
689689
address: string,
690690
slot: string,
691-
blockNumberOrTagOrHash: string | null,
691+
blockNumberOrTagOrHash: string,
692692
requestDetails: RequestDetails,
693693
): Promise<string> {
694694
return this.contractService.getStorageAt(address, slot, blockNumberOrTagOrHash, requestDetails);

packages/relay/src/lib/services/ethService/contractService/ContractService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,14 @@ export class ContractService implements IContractService {
288288
*
289289
* @param {string} address - The address of the storage
290290
* @param {string} slot - The slot index (hex string)
291-
* @param {string | null} blockNumberOrTagOrHash - Block number, tag, or hash
291+
* @param {string} blockNumberOrTagOrHash - Block number, tag, or hash
292292
* @param {RequestDetails} requestDetails - The request details for logging and tracking
293293
* @returns {Promise<string>} The value at the given storage position
294294
*/
295295
public async getStorageAt(
296296
address: string,
297297
slot: string,
298-
blockNumberOrTagOrHash: string | null,
298+
blockNumberOrTagOrHash: string,
299299
requestDetails: RequestDetails,
300300
): Promise<string> {
301301
const requestIdPrefix = requestDetails.formattedRequestId;

packages/relay/src/lib/services/ethService/contractService/IContractService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export interface IContractService {
3535
getStorageAt: (
3636
address: string,
3737
slot: string,
38-
blockNumberOrTagOrHash: string | null,
38+
blockNumberOrTagOrHash: string,
3939
requestDetails: RequestDetails,
4040
) => Promise<string>;
4141

packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -205,27 +205,6 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () {
205205
// verify slot value
206206
});
207207

208-
// Block number is a required param, this should not work and should be removed when/if validations are added.
209-
// Instead, the relay should return `missing value for required argument <argumentIndex> error`.
210-
it('eth_getStorageAt with match null block', async function () {
211-
// mirror node request mocks
212-
restMock
213-
.onGet(
214-
`contracts/${CONTRACT_ADDRESS_1}/state?slot=${DEFAULT_CURRENT_CONTRACT_STATE.state[0].slot}&limit=100&order=desc`,
215-
)
216-
.reply(200, JSON.stringify(DEFAULT_CURRENT_CONTRACT_STATE));
217-
218-
const result = await ethImpl.getStorageAt(
219-
CONTRACT_ADDRESS_1,
220-
defaultDetailedContractResults.state_changes[0].slot,
221-
null,
222-
requestDetails,
223-
);
224-
confirmResult(result);
225-
226-
// verify slot value
227-
});
228-
229208
it('eth_getStorageAt should throw a predefined RESOURCE_NOT_FOUND when block not found', async function () {
230209
restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, JSON.stringify(null));
231210

packages/server/tests/acceptance/rpc_batch2.spec.ts

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -971,46 +971,6 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () {
971971
expect(storageValBeforeChange).to.eq(beginStorageVal);
972972
});
973973

974-
it('should execute "eth_getStorageAt" request to get current state changes without passing block', async function () {
975-
const BEGIN_EXPECTED_STORAGE_VAL = '0x000000000000000000000000000000000000000000000000000000000000000f';
976-
const END_EXPECTED_STORAGE_VAL = '0x0000000000000000000000000000000000000000000000000000000000000008';
977-
978-
const beginStorageVal = await relay.call(
979-
RelayCalls.ETH_ENDPOINTS.ETH_GET_STORAGE_AT,
980-
[storageContractAddress, '0x0000000000000000000000000000000000000000000000000000000000000000'],
981-
requestId,
982-
);
983-
expect(beginStorageVal).to.eq(BEGIN_EXPECTED_STORAGE_VAL);
984-
985-
const gasPrice = await relay.gasPrice(requestId);
986-
const transaction = {
987-
value: 0,
988-
gasLimit: 50000,
989-
chainId: Number(CHAIN_ID),
990-
to: storageContractAddress,
991-
nonce: await relay.getAccountNonce(accounts[1].address),
992-
gasPrice: gasPrice,
993-
data: STORAGE_CONTRACT_UPDATE,
994-
maxPriorityFeePerGas: gasPrice,
995-
maxFeePerGas: gasPrice,
996-
type: 2,
997-
};
998-
999-
const signedTx = await accounts[1].wallet.signTransaction(transaction);
1000-
const transactionHash = await relay.sendRawTransaction(signedTx, requestId);
1001-
await relay.pollForValidTransactionReceipt(transactionHash);
1002-
1003-
// wait for the transaction to propogate to mirror node
1004-
await new Promise((r) => setTimeout(r, 4000));
1005-
1006-
const storageVal = await relay.call(
1007-
RelayCalls.ETH_ENDPOINTS.ETH_GET_STORAGE_AT,
1008-
[storageContractAddress, '0x0000000000000000000000000000000000000000000000000000000000000000'],
1009-
requestId,
1010-
);
1011-
expect(storageVal).to.eq(END_EXPECTED_STORAGE_VAL);
1012-
});
1013-
1014974
it('should execute "eth_getStorageAt" request to get current state changes with passing specific block', async function () {
1015975
const EXPECTED_STORAGE_VAL = '0x0000000000000000000000000000000000000000000000000000000000000008';
1016976

packages/server/tests/integration/server.spec.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,22 +2016,18 @@ describe('RPC Server', function () {
20162016
}
20172017
});
20182018

2019-
it('validates parameter 2 is valid block tag', async function () {
2019+
it('validates parameter 2 exists', async function () {
20202020
try {
20212021
await testClient.post('/', {
20222022
id: '2',
20232023
jsonrpc: '2.0',
20242024
method: RelayCalls.ETH_ENDPOINTS.ETH_GET_STORAGE_AT,
2025-
params: ['0x0000000000000000000000000000000000000001', '0x1', 'newest'],
2025+
params: ['0x0000000000000000000000000000000000000001', '0x1'],
20262026
});
20272027

20282028
Assertions.expectedError();
20292029
} catch (error: any) {
2030-
BaseTest.invalidParamError(
2031-
error.response,
2032-
Validator.ERROR_CODE,
2033-
`Invalid parameter 2: The value passed is not valid: newest. ${Constants.BLOCK_NUMBER_ERROR} OR ${Constants.BLOCK_HASH_ERROR}`,
2034-
);
2030+
BaseTest.invalidParamError(error.response, Validator.ERROR_CODE, MISSING_PARAM_ERROR + ' 2');
20352031
}
20362032
});
20372033
});

0 commit comments

Comments
 (0)