-
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
Support batching multiple RPC requests #187
Conversation
…wift into feat/186-batch-multiple-rpc-requests
|
||
XCTAssertEqual(simulations2.count, 2) | ||
XCTAssertTrue(simulations2[0].transactionTrace is StarknetInvokeTransactionTrace) | ||
XCTAssertTrue(simulations2[1].transactionTrace is StarknetDeployAccountTransactionTrace) | ||
} | ||
|
||
func testBatchGetTransactionByHash() async throws { |
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.
- Do we need to include more calls in this test?
- There should be a test for incorrect responses order. Imho it should be placed in a separate class eg.
JsonRpcResponseTests
as it focuses on the responses parsing mechanism.
Wdyt? @DelevoXDG
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 that can be enough
- Yes, should add such test to
JsonRpcResponseTests
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've added test for incorrect responses order
Also getOrderedRpcResults()
is now a separate internal function. It doesn't affect StarknetBatchRequest
, but simplifies creating test for incorrect order.
…wift into feat/186-batch-multiple-rpc-requests
let nonce = try await account.getNonce() | ||
let feeEstimate = try await account.estimateFeeV1(call: call, nonce: nonce) | ||
let nonce = try await account.getNonce().send() | ||
let feeEstimate = try await account.estimateFeeV1(call: call, nonce: nonce).send()[0] |
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.
The change of estimate fee return type resulted in having to access element [0]
every time we use this metod. Unfortunately there isn't any other way, because first we need to send the request and the access its result.
@@ -30,16 +31,17 @@ final class ProviderTests: XCTestCase { | |||
} | |||
|
|||
provider = makeStarknetProvider(url: Self.devnetClient.rpcUrl) | |||
batchProvider = makeStarknetProvider(url: Self.devnetClient.rpcUrl) |
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.
Nit: could the variable name be improved?
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 we might wanna add batch to the StarknetProviderProtocol
, WDYT?
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.
Yup, I added it to the protocol 👍
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.
If that's the case, can we just go ahead and use provider
instead of batchProvider
?
do { | ||
let _ = try transactionsResponse[1].get().transaction.hash | ||
XCTFail("Fetching transaction with nonexistent hash should fail") | ||
} catch let error as StarknetProviderError { | ||
switch error { | ||
case let .jsonRpcError(_, message, _): | ||
XCTAssertEqual(message, "Transaction hash not found", "Unexpected error message received") | ||
default: | ||
XCTFail("Expected JsonRpcError but received \(error)") | ||
} | ||
} catch { | ||
XCTFail("Error was not a StarknetProviderError. Received error type: \(type(of: error))") | ||
} |
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 don't really like the fact that there is double nesting here, maybe there's other way to access jsonRpcError
message?
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 understand the concern, but afaik we can't have some kind of property that is shared amongst all enums, enums in swift just work differently. So we'll have to stick to what's possible here 😅
All requested changes have been addressed, I've also added few remarks about newly applied changes. |
} | ||
|
||
if let paramsResourceBounds = params.resourceBounds { | ||
resourceBounds = paramsResourceBounds | ||
} else { | ||
let feeEstimate = try await estimateFeeV3(calls: calls, nonce: nonce) | ||
let feeEstimate = try await estimateFeeV3(calls: calls, nonce: nonce).send()[0] |
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.
Are you sure getting the first estimate is a valid approach?
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.
It has been discussed in previous thread
#187 (comment)
public typealias EmptySequence = [String] | ||
public struct EmptyParams: Encodable {} |
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.
It could be theoretically achieved, if we decrease params' level of abstraction.
Can we do that? I think it would considerably simplify the codebase (no unnecessary generis, no public param structs), but if that's too much effort it can be done in a separate PR.
Sources/Starknet/Providers/StarknetProvider/StarknetProvider.swift
Outdated
Show resolved
Hide resolved
….com/software-mansion/starknet.swift into feat/186-batch-multiple-rpc-requests
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.
Mostly ok, few minor comments to be addressed before merging
Sources/Starknet/Providers/StarknetProvider/JsonRpcParams.swift
Outdated
Show resolved
Hide resolved
Sources/Starknet/Providers/StarknetProvider/StarknetProvider.swift
Outdated
Show resolved
Hide resolved
do { | ||
let _ = try transactionsResponse[1].get().transaction.hash | ||
XCTFail("Fetching transaction with nonexistent hash should fail") | ||
} catch let error as StarknetProviderError { | ||
switch error { | ||
case let .jsonRpcError(_, message, _): | ||
XCTAssertEqual(message, "Transaction hash not found", "Unexpected error message received") | ||
default: | ||
XCTFail("Expected JsonRpcError but received \(error)") | ||
} | ||
} catch { | ||
XCTFail("Error was not a StarknetProviderError. Received error type: \(type(of: error))") | ||
} |
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 understand the concern, but afaik we can't have some kind of property that is shared amongst all enums, enums in swift just work differently. So we'll have to stick to what's possible here 😅
} | ||
} | ||
|
||
func getOrderedRpcResults<U: Decodable>(rpcResponses: [JsonRpcResponse<U>], count: Int) -> [Result<U, StarknetProviderError>] { |
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.
Nit:
We can rename this to prepareOrderedRpcResults
or orderRpcResults
.
Also, I think we can just inline this.
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 renamed it to orderRpcResults
. It wasn't inlined on purpose - thanks to keeping it in separate function, ordering can be tested in testBatchResponseWithIncorrectOrder
@@ -30,16 +31,17 @@ final class ProviderTests: XCTestCase { | |||
} | |||
|
|||
provider = makeStarknetProvider(url: Self.devnetClient.rpcUrl) | |||
batchProvider = makeStarknetProvider(url: Self.devnetClient.rpcUrl) |
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 we might wanna add batch to the StarknetProviderProtocol
, WDYT?
Sources/Starknet/Providers/StarknetProvider/StarknetProvider.swift
Outdated
Show resolved
Hide resolved
Sources/Starknet/Providers/StarknetProvider/JsonRpcParams.swift
Outdated
Show resolved
Hide resolved
Sources/Starknet/Providers/StarknetProvider/JsonRpcParams.swift
Outdated
Show resolved
Hide resolved
Co-authored-by: Maksim Zdobnikau <43750648+DelevoXDG@users.noreply.github.com>
Co-authored-by: Maksim Zdobnikau <43750648+DelevoXDG@users.noreply.github.com>
….com/software-mansion/starknet.swift into feat/186-batch-multiple-rpc-requests
Co-authored-by: Maksim Zdobnikau <43750648+DelevoXDG@users.noreply.github.com>
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.
LGTM overall, can be merged after addressing the comments
@@ -30,16 +31,17 @@ final class ProviderTests: XCTestCase { | |||
} | |||
|
|||
provider = makeStarknetProvider(url: Self.devnetClient.rpcUrl) | |||
batchProvider = makeStarknetProvider(url: Self.devnetClient.rpcUrl) |
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.
If that's the case, can we just go ahead and use provider
instead of batchProvider
?
Describe your changes
Suport batching multiple RPC requests
StarknetRequest
andStarknetBatchRequest
structsStarknetProvider.batchRequests()
accepting both list and variadic parametersJsonRpcParams
enum and extensionLinked issues
Closes #186, #145
Breaking changes
StarknetAccount
executeV1(...) async throws -> StarknetInvokeTransactionResponse
->executeV1(...) -> StarknetRequest<StarknetInvokeTransactionResponse>
executeV3(...) async throws -> StarknetInvokeTransactionResponse
->executeV3(...) -> StarknetRequest<StarknetInvokeTransactionResponse>
executeV1(...) async throws -> StarknetInvokeTransactionResponse
->executeV1(...) -> StarknetRequest<StarknetInvokeTransactionResponse>
executeV3(...) async throws -> StarknetInvokeTransactionResponse
->executeV3(...) -> StarknetRequest<StarknetInvokeTransactionResponse>
estimateFeeV1(...) async throws -> StarknetFeeEstimate
->estimateFeeV1(...) -> StarknetRequest<[StarknetFeeEstimate]>
estimateFeeV3(...) async throws -> StarknetFeeEstimate
->estimateFeeV3(...) -> StarknetRequest<[StarknetFeeEstimate]>
estimateDeployAccountFeeV1(...) async throws -> StarknetFeeEstimate
->estimateDeployAccountFeeV1(...) -> StarknetRequest<[StarknetFeeEstimate]>
estimateDeployAccountFeeV3(...) async throws -> StarknetFeeEstimate
->estimateDeployAccountFeeV3(...) -> StarknetRequest<[StarknetFeeEstimate]>
getNonce() async throws -> Felt
->getNonce()-> StarknetRequest<Felt>
StarknetProvider
specVersion() async throws -> String
->specVersion() -> StarknetRequest<String>
callContract(...) async throws -> [Felt]
->callContract(...) -> StarknetRequest<[Felt]>
estimateMessageFee(...) async throws -> StarknetFeeEstimate
->estimateMessageFee(...) -> StarknetRequest<StarknetFeeEstimate>
getNonce() async throws -> Felt
->getNonce() -> StarknetRequest<Felt>
addInvokeTransaction(...) async throws -> StarknetInvokeTransactionResponse
->addInvokeTransaction(...) -> StarknetRequest<StarknetInvokeTransactionResponse>
addDeployAccountTransaction(...) async throws -> StarknetDeployAccountResponse
->addDeployAccountTransaction(...) -> StarknetRequest<StarknetDeployAccountResponse>
getClassHashAt(...) async throws -> Felt
->getClassHashAt(...) -> StarknetRequest<Felt>
getBlockNumber() async throws -> UInt64
->getBlockNumber() -> StarknetRequest<UInt64>
getBlockHashAndNumber() async throws -> StarknetBlockHashAndNumber
->getBlockHashAndNumber() -> StarknetRequest<StarknetBlockHashAndNumber>
getEvents(...) async throws -> StarknetGetEventsResponse
->getEvents(...) -> StarknetRequest<StarknetGetEventsResponse>
getTransactionBy(...) async throws -> any StarknetTransaction
->getTransactionBy(...) -> StarknetRequest<StarknetTransaction>
getTransactionReceiptBy(...) async throws -> any StarknetTransactionReceipt
->getTransactionReceiptBy(...) -> StarknetRequest<StarknetTransactionReceipt>
getTransactionStatusBy(...) async throws -> StarknetGetTransactionStatusResponse
->getTransactionStatusBy(...) async throws -> StarknetRequest<StarknetGetTransactionStatusResponse>
getChainId() async throws -> StarknetChainId
->getChainId() -> StarknetRequest<StarknetChainId>
simulateTransactions(...) async throws -> [StarknetSimulatedTransaction]
->simulateTransactions(...) -> StarknetRequest<[StarknetSimulatedTransaction]>