Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

changed startLedger and endLedger of getEvents to be string types #36

Merged
merged 4 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/jsonrpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export interface Error<E = any> {
data?: E;
}

/**
* Sends the jsonrpc 'params' as an array.
*/
export async function post<T>(
url: string,
method: string,
Expand All @@ -45,3 +48,25 @@ export async function post<T>(
return response.data?.result;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, is this trying to handle when params is an object? Or, I'm not sure what this is doing...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@paulbellamy , yes, I cleaned up the code here, i ran into two errors when trying the client against rpc server:

  • params.endLedger and params.startLedger need to be strings
  • params needs to be object not array for getEvents, otherwise jsronrpc had unmarshal error on it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, but as it is, I suspect this change might break methods with a single parameter. For example, I pass [xdr.ScVal(...)], but then that get's converted to just xdr.ScVal(...), and the call fails. I expect object/array thing is because the pagination param at the end is required (not optional, bug in the docs). Was that what you were hitting?

Could we just do the startLedger/endLedger change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will still get error due to the params being an array, was getting error from rpc getEventsserver handler,

 "error": {
        "code": -32602,
        "message": "invalid parameters: [-32602] invalid parameters"
    }

the jrpc2 lib has json unmarsal errors with this params json when it introspects and tries to marshal it into GetEventsRequest struct, both for number types on startLedger/endLedger, and the params being an array with a single object.

the jsonrpc spec allows array or object type for the params, and i saw jrpc2 tries to handle both, but ends up in error anyways which I didn't step through deeper to see why. but it seems that params:[jsObj] and params:jsObj are both valid forms and should resolve to same jsObj , which covers your example such as [xdr.ScVal(...)]

Looking at the other server.ts methods, none are passing arrays with single js objects yet, they are mostly passing arrays with single scalar value, and the change introduced here , would leave that as-is.

I would need to execute all the server.ts methods from this pr against current rpc server manually to validate your concern. We need an integration test between js client and rpc to verify these two are compliant with each other, maybe can automate by adding those calls to the existing integration client_headers_test.js? In parallel, I think system-test will start to establish that coverage with stellar/system-test#5

How about i just create a jsonrpc.postObject() method and have getEvents use that form, to isolate this for now to getEvents, which can confirm it will work in that scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I created issue #38 , has curl examples of the getEvents call with params formats that error and work.

Copy link
Contributor

@paulbellamy paulbellamy Jan 20, 2023

Choose a reason for hiding this comment

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

Oh that's true it would only affect soroban-rpc methods with a single arg. I was mixing that up with contract fns with a single arg. Separate postObject used by getEvents to be more explicit (with a note about why it's needed) would be good, IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, added jsonrpc.postObject - 4cb61f2

}

/**
* Sends the jsonrpc 'params' as the single 'param' obj, no array wrapper is applied.
*/
export async function postObject<T>(
url: string,
method: string,
param: any,
): Promise<T> {
const response = await axios.post<Response<T>>(url, {
jsonrpc: "2.0",
// TODO: Generate a unique request id
id: 1,
method,
params: param,
});
if (hasOwnProperty(response.data, "error")) {
throw response.data.error;
} else {
return response.data?.result;
}
}
10 changes: 5 additions & 5 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ export class Server {
*
* @example
* server.getEvents(
* 1000,
* 1010,
* "1000",
* "1010",
* [
* {
* type: "contract",
Expand Down Expand Up @@ -243,9 +243,9 @@ export class Server {
// The difficulty comes in matching up the correct integer primitives.
//
// It also means this library will rely on the XDR definitions.
return await jsonrpc.post(this.serverURL.toString(), "getEvents", {
startLedger,
endLedger,
return await jsonrpc.postObject(this.serverURL.toString(), "getEvents", {
startLedger: String(startLedger),
endLedger: String(endLedger),
filters: filters ?? [],
pagination: {
...(cursor && { cursor }), // add fields only if defined
Expand Down
22 changes: 11 additions & 11 deletions test/unit/server/get_events_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ describe("Server#getEvents", function() {
setupMock(
this.axiosMock,
{
endLedger: 2,
endLedger: "2",
filters: [],
pagination: {},
startLedger: 1,
startLedger: "1",
},
result,
);
Expand All @@ -41,8 +41,8 @@ describe("Server#getEvents", function() {
setupMock(
this.axiosMock,
{
startLedger: 1,
endLedger: 10,
startLedger: "1",
endLedger: "10",
filters: [
{
topics: [["*", "*"]],
Expand Down Expand Up @@ -76,8 +76,8 @@ describe("Server#getEvents", function() {
setupMock(
this.axiosMock,
{
startLedger: 1,
endLedger: 10,
startLedger: "1",
endLedger: "10",
filters: [
{
topics: [["AAAABQAAAAh0cmFuc2Zlcg==", "AAAAAQB6Mcc="]],
Expand Down Expand Up @@ -109,8 +109,8 @@ describe("Server#getEvents", function() {
setupMock(
this.axiosMock,
{
startLedger: 1,
endLedger: 2,
startLedger: "1",
endLedger: "2",
filters: [
{
topics: [["AAAABQAAAAh0cmFuc2Zlcg==", "*"]],
Expand Down Expand Up @@ -142,8 +142,8 @@ describe("Server#getEvents", function() {
setupMock(
this.axiosMock,
{
startLedger: 1,
endLedger: 2,
startLedger: "1",
endLedger: "2",
filters: [
{
topics: [["*", "*"]],
Expand Down Expand Up @@ -196,7 +196,7 @@ function setupMock(axiosMock, params, result) {
jsonrpc: "2.0",
id: 1,
method: "getEvents",
params: [params],
params: params,
})
.returns(Promise.resolve({ data: { result } }));
}
Expand Down