Skip to content

Conversation

@jasonpaulos
Copy link
Contributor

@jasonpaulos jasonpaulos commented Jan 10, 2024

Relies on algorand/generator#72

Fixes #848 (that issue contains a good description of this work)

@jasonpaulos jasonpaulos changed the title Remove IntDecoding as a REST option & support native bigint types in models 3.0.0 Remove IntDecoding as a REST option & support native bigint types in models Jan 10, 2024
@jasonpaulos jasonpaulos changed the title 3.0.0 Remove IntDecoding as a REST option & support native bigint types in models 3.0.0: Remove IntDecoding as a REST option & support native bigint types in models Jan 10, 2024
@jasonpaulos jasonpaulos marked this pull request as ready for review February 14, 2024 22:22
Copy link
Contributor

@jannotti jannotti left a comment

Choose a reason for hiding this comment

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

I don't think I understand how everything fits together, but here are some comments before I'm ooo.


console.log(
`Account Info: ${JSON.stringify(acctInfo)} Auth Addr: ${
`Account Info: ${algosdk.stringifyJSON(acctInfo)} Auth Addr: ${
Copy link
Contributor

Choose a reason for hiding this comment

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

My js is very rusty, but isn't it the case that (in browser anyway) console.log is clever enough to give you a little UI to look at an object if you just log it separately? This is, isn't console.log("Account Info", acctInfo) going to be more helpful?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My experience is that, yes, console.log("Account Info", acctInfo) would expand acctInfo for you in browsers, and it's usually a drop down that you can interact with to see each field. However, if you're not on a browser, it's not a great experience as often you'll just get back a string like [object, object].

Comment on lines +1122 to +1125
this.extraProgramPages =
typeof extraProgramPages === 'undefined'
? undefined
: ensureSafeInteger(extraProgramPages);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why wouldn't we want to coerce to 0 instead of undefined? The question probably comes from me not having enough context to know where this type is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMO 0 would be preferable here. Since this is a generated file, all we know is that the REST API lists that field as optional. At this level we have no way of knowing if that's the field is omitempty, or if it's truly optional

this.budgetAdded =
typeof budgetAdded === 'undefined'
? undefined
: ensureSafeInteger(budgetAdded);
Copy link
Contributor

@jannotti jannotti Feb 15, 2024

Choose a reason for hiding this comment

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

This is a repeat of a previous question (why not coerce to 0). But more broadly, could ensureSafeInteger accept undefined and return 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ensureSafeInteger(undefined) will error. If you wanted it to coerce undefined to 0, you could do so with ensureSafeInteger(x ?? 0) (the ?? being the null coalescing operator, which is relatively new). The Transaction constructor uses this pattern a lot

Comment on lines +4741 to +4742
this.apps =
typeof apps === 'undefined' ? undefined : apps.map(ensureBigInt);
Copy link
Contributor

@jannotti jannotti Feb 15, 2024

Choose a reason for hiding this comment

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

I'm repeating myself somewhat as I think I'm understanding the issue better. I think we ought to be coercing all of the "omitEmpty" fields, to their "empty" values. So lists become [], integers become 0 or 0n. I've only been commenting on the places you've had to edit because of the bignum change, but this seems like something we ought to do for all of these types before handing them to the user. They shouldn't have to understand omitEmpty.

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 agree with this a lot. I'll think more about how this can be addresses

Copy link
Contributor

Choose a reason for hiding this comment

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

It feels like it can be another PR, but would be very nice to do for v3.


async do(headers = {}) {
const res = await this.c.post(this.path(), null, undefined, headers);
const res = await this.c.post({
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to the KmdClient.post suggestion but deeper down, should we change HTTPClient to make these call sites simpler, since they are the common case. Seems like parseBody and jsonOptions should default to these, so you can go back to simple call sites for most api calls (or add a new method like apiPost)

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'm also unhappy with the HTTPClient methods at the moment, though I didn't know whether I should address them in this PR.

My inclination is to simplify those methods so that they just return the raw Uint8Array bytes, and perhaps introduce new methods which would return parsed JSON.

So it would be something like HTTPClient.get and HTTPClient.getJSON -- still thinking through this

* Number.MAX_SAFE_INTEGER will lose precision.
*/
DEFAULT = 'default',
UNSAFE = 'unsafe',
Copy link
Contributor

Choose a reason for hiding this comment

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

github won't let me comment in the right place. Are we still using MIXED? I get the impression that you don't need it because you can use bigint, then your coerce routines will fix things up.

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 don't think we use currently using MIXED anywhere, but it's still a potentially useful option to have, especially since we now expose the JSON parsing to users

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think I followed why we should expose the json parsing to users. Is the idea that they may not want our models, but want to use the sdk to hit an endpoint then parse it (differently) themselves?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right now it's expected that many of our type representations can be encoded into JSON and msgpack and back, and not just by our code -- we expect the user to be able to perform these encoding operations if they want to persist things to disk, for instance. Many of our types have a get_object_for_encoding method which returns an object ready to be serialized into one of those formats. Unfortunately bigints aren't supported by the standard JSON encoder, so without exposing the additional utilities, there wouldn't be an easy way to encode these newer objects in v3.

Technically this was also a problem in v2, but due to how types stored internal representations (they'd store exactly what they got most of the time), it was only a problem if you created a type with a bigint.

Copy link
Contributor

@gmalouf gmalouf left a comment

Choose a reason for hiding this comment

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

I'd like to see discussion to JJ's questions around the right default types for not set/not existing (nils vs zero values). Outside of that, this largely aligns with your description of the issue.

});
}

interface StackValueResponse {
Copy link
Contributor

Choose a reason for hiding this comment

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

This file's changes feel somewhat unrelated to the stated goal of the PR, can you walk me through the intentions here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question. This code broke because algod responses now contain bigints for certain fields. I could have just changed those fields, but I noticed a lot of the definitions here were redundant and no longer necessary, since we have fully typed algod responses.

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 meant to comment this earlier, but this file is generated by https://github.com/algorand/generator. See algorand/generator#72 for the changes to the template

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is also generated in the same way: algorand/generator#72

Copy link
Contributor

@algorandskiy algorandskiy left a comment

Choose a reason for hiding this comment

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

LGTM but not sure about v2 client backward compatibility, please advise.

Copy link
Contributor

@gmalouf gmalouf left a comment

Choose a reason for hiding this comment

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

I'm good at this point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants