-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(solana): rate limited solana provider #833
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Reinis Martinsons <[email protected]>
Signed-off-by: Reinis Martinsons <[email protected]>
Signed-off-by: Reinis Martinsons <[email protected]>
// This sets up the queue. Each task is executed by forwarding the RPC request to the underlying base transport. | ||
// This queue sends out requests concurrently, but stops once the concurrency limit is reached. The maxConcurrency | ||
// is configured here. | ||
this.queue = queue(async ({ rpcArgs, resolve, reject }: SolanaRateLimitTask, callback: () => void) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This queuing logic looks almost identical to the EVM version, is there any way to refactor and re-use code? We might be able to unit test any refactored code more easily
|
||
// In this path we log an rpc response sample. | ||
// Note: use performance.now() to ensure a purely monotonic clock. | ||
const startTime = performance.now(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think it could be useful to refactor and re-use some of this elapsedTime logic. It would also be a bit easier to unit test if we abstract the hypothetical re-used function well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really well written code! I think we can possibly try to reuse some code from the evm provider and that might make unit testing with mocks even easier!
message: "Solana provider response sample", | ||
provider: getOriginFromURL(this.clusterUrl), | ||
method: payload.method, | ||
params: payload.params, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it safe to send the params in the payload to Winston without validating or serializing them first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be safe as we expect these requests to originate via Solana web3.js library. In addition, we use createDefaultRpcTransport
here to create the underlying transport that internally type checks the request here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! Just added a question.
Signed-off-by: Reinis Martinsons <[email protected]>
This implements the same rate limited provider logic as
src/providers/rateLimitedProvider.ts
, but for Solana using V2 of@solana/web3.js
library that allows creating RPC clients with composable transports.Note that this
@solana/web3.js
library produces build errors and CI node version would need to be updated.It would be quite a lift to implement mocked Solana RPC node for tests, but the expected behavior was tested with:
This produces following logs showing that new Solana slots get mined during rate limited requests (with concurrency set to 1) while normally these concurrent requests would resolve to the same slot: