Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

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
Contributor 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',
);
});
});