Skip to content

Commit

Permalink
update http quicknode rpc-provider (#7102)
Browse files Browse the repository at this point in the history
* update http

* update changelog

* update web3-rpc-providers

* update

* update

* update

* update tests

* remove quicknode errors

* update imports

* change return type of request

* update changelog

---------

Co-authored-by: Alex Luu <alex.luu@mail.utoronto.ca>
  • Loading branch information
luu-alex and Alex Luu authored Jul 10, 2024
1 parent 1436228 commit 89711ab
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 8 deletions.
7 changes: 4 additions & 3 deletions packages/web3-providers-http/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ export default class HttpProvider<
},
body: JSON.stringify(payload),
});

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
if (!response.ok) throw new ResponseError(await response.json());
if (!response.ok) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
throw new ResponseError(await response.json())
};

return (await response.json()) as JsonRpcResponseWithResult<ResultType>;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/web3-rpc-providers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- RC release

## [Unreleased]
- When error is returned with code 429, throw rate limit error (#7102)
- Change request return type `Promise<ResultType>` to `Promise<JsonRpcResponseWithResult<ResultType>>` (#7102)
2 changes: 2 additions & 0 deletions packages/web3-rpc-providers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@
"typescript": "^4.7.4"
},
"dependencies": {
"web3-errors": "^1.2.0",
"web3-providers-http": "^4.1.0",
"web3-providers-ws": "^4.0.7",
"web3-validator": "^2.0.6",
"web3-types": "^1.7.0",
"web3-utils": "^4.3.0"
}
Expand Down
28 changes: 28 additions & 0 deletions packages/web3-rpc-providers/src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

import { BaseWeb3Error } from 'web3-errors';
import { } from 'web3-types';

const ERR_QUICK_NODE_RATE_LIMIT = 1300;
export class QuickNodeRateLimitError extends BaseWeb3Error {
public code = ERR_QUICK_NODE_RATE_LIMIT;

public constructor() {
super(`Too many requests, Quicknode has reached its rate limit.`);
}
}
20 changes: 15 additions & 5 deletions packages/web3-rpc-providers/src/web3_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.

import HttpProvider from "web3-providers-http";
import WebSocketProvider from "web3-providers-ws";
import { isNullish } from "web3-validator";
import {
EthExecutionAPI, JsonRpcResult, ProviderConnectInfo, ProviderMessage,
ProviderRpcError, Web3APIMethod, Web3APIPayload, Web3APIReturnType, Web3APISpec, Web3BaseProvider,
Web3Eip1193ProviderEventCallback,
Web3ProviderEventCallback,
Web3ProviderMessageEventCallback,
Web3ProviderStatus
Web3ProviderStatus,
JsonRpcResponseWithResult,
} from "web3-types";
import { Eip1193Provider } from "web3-utils";
import { Transport, Network } from "./types.js";
import { QuickNodeRateLimitError } from './errors.js';

/*
This class can be used to create new providers only when there is custom logic required in each Request method like
Expand Down Expand Up @@ -68,13 +71,20 @@ API extends Web3APISpec = EthExecutionAPI,
>(
payload: Web3APIPayload<EthExecutionAPI, Method>,
requestOptions?: RequestInit,
): Promise<ResultType> {
): Promise<JsonRpcResponseWithResult<ResultType>> {

if (this.transport === Transport.HTTPS) {
return ( (this.provider as HttpProvider).request(payload, requestOptions)) as unknown as Promise<ResultType>;
}
const res = await ( (this.provider as HttpProvider).request(payload, requestOptions)) as unknown as JsonRpcResponseWithResult<ResultType>;

if (typeof res === 'object' && !isNullish(res) && 'error' in res && !isNullish(res.error) && 'code' in res.error && (res.error as { code: number }).code === 429){
// rate limiting error by quicknode;
throw new QuickNodeRateLimitError();

}
return res;
}

return ( (this.provider as WebSocketProvider).request(payload)) as unknown as Promise<ResultType>;
return (this.provider as WebSocketProvider).request(payload);

}

Expand Down
29 changes: 29 additions & 0 deletions packages/web3-rpc-providers/test/unit/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
import { Web3APIPayload, EthExecutionAPI, Web3APIMethod } from "web3-types";
import { Network, Transport } from "../../src/types";
import { Web3ExternalProvider } from "../../src/web3_provider";
import { QuickNodeRateLimitError } from '../../src/errors';

jest.mock('web3-providers-ws', () => {
return {
Expand Down Expand Up @@ -78,4 +79,32 @@ describe('Web3ExternalProvider', () => {
const result = await provider.request(payload);
expect(result).toEqual({ result: 'mock-result' });
});
it('should return a rate limiting error when code is 429', async () => {
const network: Network = Network.ETH_MAINNET;
const transport: Transport = Transport.HTTPS;
const token = 'your-token';

const mockHttpProvider = {
request: jest.fn(),
};

const mockResponse = {
jsonrpc: '2.0',
id: '458408f4-7e2c-43f1-b61d-1fe09a9ee25a',
error: {
code: 429,
message: 'the method eth_stuff does not exist/is not available'
}
};
mockHttpProvider.request.mockResolvedValue(mockResponse);

const provider = new MockWeb3ExternalProvider(network, transport, token);
(provider as any).provider = mockHttpProvider;

const payload: Web3APIPayload<EthExecutionAPI, Web3APIMethod<EthExecutionAPI>> = {
method: 'eth_getBalance',
params: ['0x0123456789012345678901234567890123456789', 'latest'],
};
await expect(provider.request(payload)).rejects.toThrow(QuickNodeRateLimitError);
});
});

1 comment on commit 89711ab

@github-actions
Copy link

Choose a reason for hiding this comment

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

Benchmark

Benchmark suite Current: 89711ab Previous: 1436228 Ratio
processingTx 9435 ops/sec (±3.67%) 9231 ops/sec (±4.50%) 0.98
processingContractDeploy 40686 ops/sec (±6.96%) 41209 ops/sec (±6.76%) 1.01
processingContractMethodSend 16574 ops/sec (±8.48%) 17267 ops/sec (±7.07%) 1.04
processingContractMethodCall 28430 ops/sec (±6.15%) 27522 ops/sec (±7.88%) 0.97
abiEncode 45419 ops/sec (±7.37%) 45151 ops/sec (±6.90%) 0.99
abiDecode 31557 ops/sec (±7.64%) 30258 ops/sec (±7.82%) 0.96
sign 1572 ops/sec (±3.54%) 1598 ops/sec (±0.81%) 1.02
verify 375 ops/sec (±0.51%) 375 ops/sec (±0.45%) 1

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.