Skip to content
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

improve proto3 JSON types and utils #9219

Merged
merged 4 commits into from
Apr 22, 2024
Merged

improve proto3 JSON types and utils #9219

merged 4 commits into from
Apr 22, 2024

Conversation

turadg
Copy link
Member

@turadg turadg commented Apr 10, 2024

Description

Spurred by some recent reviews.

  • clarify the Any protobuf encoding
  • use it where we can, to align with external types.
  • move the vat-safe encoding concern lower than orchestration (applicable to all inter-vat comms)

Security Considerations

none

Scaling Considerations

none

Documentation Considerations

Less to document

Testing Considerations

CI

Upgrade Considerations

not yet in production

packages/vats/tools/protobuf-utils.js Outdated Show resolved Hide resolved
packages/orchestration/src/utils/tx.js Outdated Show resolved Hide resolved
Comment on lines 4 to 10
/** @typedef {{ typeUrl: string; valueBase64: string }} Proto3MsgBase64 */
/**
* base64 encode `value` (possibly binary ) for cross-vat communication
*
* @param {Any} msg
* @returns {Proto3MsgBase64}
*/
Copy link
Member

@michaelfig michaelfig Apr 11, 2024

Choose a reason for hiding this comment

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

I think this change requires more explicit understanding of why Base64 is required:

  • If you declare a Golang struct to have a []byte member, then when you json.Marshal or json.Unmarshal it, the encoding/json Golang module converts []byte to and from base64.
  • AnyKindOfProtoCodec.toJSON(object), including Any.toJSON(object) returns a "message" with byte arrays converted to Base64
  • AnyKindOfProtoCodec.fromJSON(message), including Any.fromJSON(message) returns an object with Base64 converted to byte arrays
  • That, to me, suggests that the type should be named something like AnyJson and defined as { typeUrl: string, value: string }, since that is just the Jsonable version of type Any = { typeUrl: string, value: Uint8Array }

Copy link
Member

Choose a reason for hiding this comment

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

cf cosmic-proto/dist/codegen/google/protobuf/any.js

Copy link
Member Author

Choose a reason for hiding this comment

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

The names Any and AnyJson make sense to me. I was hoping to distinguish between them structurely by their keys, but I forgot about this precedence that should be maintained:

toJSON(message: Any): unknown {
const obj: any = {};
message.typeUrl !== undefined && (obj.typeUrl = message.typeUrl);
message.value !== undefined &&
(obj.value = base64FromBytes(
message.value !== undefined ? message.value : new Uint8Array(),
));
return obj;
},
fromPartial(object: Partial<Any>): Any {

Fortunately TS can still distinguish between them.

I wonder why that method returns unknown instead of { typeUrl: string, value: string }.

The two codecs in this file, we don't need them, right? It's just Any.fromJSON and Any.toJSON. I'll give that a whirl

Copy link
Member

Choose a reason for hiding this comment

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

I wonder why that method returns unknown

Maybe because just because the transpiler is being slothful. A proper toJSON return type would need to be prepared to either introduce a new type, or inline the type for an object that could potentially have many properties.

The two codecs in this file, we don't need them, right? It's just Any.fromJSON and Any.toJSON.

That's correct.

Copy link
Member Author

@turadg turadg Apr 22, 2024

Choose a reason for hiding this comment

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

Meanwhile I've added a helper:

// TODO make codegen toJSON() return these instead of unknown
/**
 * Proto Any with arrays encoded as base64
 */
export type Base64Any<T> = {
  [Prop in keyof T]: T[Prop] extends Uint8Array ? string : T[Prop];
};

Copy link

cloudflare-workers-and-pages bot commented Apr 22, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: c77c1be
Status: ✅  Deploy successful!
Preview URL: https://2f88cbbf.agoric-sdk.pages.dev
Branch Preview URL: https://ta-json3.agoric-sdk.pages.dev

View logs

@turadg turadg marked this pull request as ready for review April 22, 2024 19:57
@@ -34,3 +41,11 @@ export const typedJson = <T extends keyof Proto3Shape>(
...obj,
} as TypedJson<T>;
};

// TODO make codegen toJSON() return these instead of unknown
Copy link
Member

@0xpatrickdev 0xpatrickdev Apr 22, 2024

Choose a reason for hiding this comment

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

We will also need this for RequestQuery.toJSON() (/tendermint/abci/types.js). Any chance it can fit in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

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

that would require patching the codegen. out of scope, thus the TODO

seat: ZCFSeat,
offerArgs?: OA,
) => OR;
type HandleOffer<OR extends unknown, OA> = (seat: ZCFSeat, offerArgs: OA) => OR;
Copy link
Member

Choose a reason for hiding this comment

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

Not sure how this is related to the rest of the changes

Copy link
Member Author

Choose a reason for hiding this comment

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

type bug discovered in the course of the work: d68596cb8d1d84db4c4eb9af754b132af1ce1649

@turadg turadg added the automerge:rebase Automatically rebase updates, then merge label Apr 22, 2024
@mergify mergify bot merged commit 4c65fc2 into master Apr 22, 2024
67 checks passed
@mergify mergify bot deleted the ta/json3 branch April 22, 2024 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants