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

feat: add VersionedMessage.deserializeMessageVersion utility function #27415

Merged
merged 1 commit into from
Aug 29, 2022
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
15 changes: 12 additions & 3 deletions web3.js/src/message/versioned.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@ import {MessageV0} from './v0';
export type VersionedMessage = Message | MessageV0;
// eslint-disable-next-line no-redeclare
export const VersionedMessage = {
Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't checked how tree-shakers treat this. If I do:

import {VersionedMessage} from 'src/message/versioned';
// ...but then only use one function
if (VersionedMessage.deserializeMessageVersion(message) === 'legacy') {
  /* ... */
}

…does the compiler shake out the other methods I haven't used?

I know it definitely works if you export each function.

export function deserializeMessageVersion(...) { ... }

…then

import {deserializeMessageVersion} from 'src/message/versioned';
if (deserializeMessageVersion(message) === 'legacy') {
  /* ... */
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh good question, I'd like to punt on this for now and would happily accept / implement a change that's more tree-shaker friendly if it's an issue

deserialize: (serializedMessage: Uint8Array): VersionedMessage => {
deserializeMessageVersion(serializedMessage: Uint8Array): 'legacy' | number {
const prefix = serializedMessage[0];
const maskedPrefix = prefix & VERSION_PREFIX_MASK;

// if the highest bit of the prefix is not set, the message is not versioned
if (maskedPrefix === prefix) {
return Message.from(serializedMessage);
return 'legacy';
}

// the lower 7 bits of the prefix indicate the message version
const version = maskedPrefix;
return maskedPrefix;
},

deserialize: (serializedMessage: Uint8Array): VersionedMessage => {
const version =
VersionedMessage.deserializeMessageVersion(serializedMessage);
if (version === 'legacy') {
return Message.from(serializedMessage);
}

if (version === 0) {
return MessageV0.deserialize(serializedMessage);
} else {
Expand Down
28 changes: 28 additions & 0 deletions web3.js/test/message-tests/versioned.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {expect} from 'chai';

import {VersionedMessage} from '../../src/message';

describe('VersionedMessage', () => {
it('deserializeMessageVersion', () => {
const bufferWithLegacyPrefix = new Uint8Array([1]);
expect(
VersionedMessage.deserializeMessageVersion(bufferWithLegacyPrefix),
).to.eq('legacy');

for (const version of [0, 1, 127]) {
const bufferWithVersionPrefix = new Uint8Array([(1 << 7) + version]);
expect(
VersionedMessage.deserializeMessageVersion(bufferWithVersionPrefix),
).to.eq(version);
}
});

it('deserialize failure', () => {
const bufferWithV1Prefix = new Uint8Array([(1 << 7) + 1]);
expect(() => {
VersionedMessage.deserialize(bufferWithV1Prefix);
}).to.throw(
'Transaction message version 1 deserialization is not supported',
);
});
});