From dedde442dd8387727bf734b76c4a2e3781f5cfd0 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Tue, 11 Jun 2024 23:05:44 -0500 Subject: [PATCH] feat: vat-safe denomHash using noble sha256 - @noble/hashes dependency - unit test using bundle Co-Authored-By: Turadg Aleahmad --- packages/orchestration/package.json | 5 ++++- packages/orchestration/src/utils/denomHash.js | 22 +++++++++++++++++++ .../test/utils/denomHash.test.ts | 18 +++++++++++++++ .../orchestration/test/utils/denomHashEx.js | 6 +++++ yarn.lock | 5 +++++ 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 packages/orchestration/src/utils/denomHash.js create mode 100644 packages/orchestration/test/utils/denomHash.test.ts create mode 100644 packages/orchestration/test/utils/denomHashEx.js diff --git a/packages/orchestration/package.json b/packages/orchestration/package.json index 37bcc1834d3..98d8b3ee357 100644 --- a/packages/orchestration/package.json +++ b/packages/orchestration/package.json @@ -50,13 +50,16 @@ "@endo/errors": "^1.2.2", "@endo/far": "^1.1.2", "@endo/marshal": "^1.5.0", - "@endo/patterns": "^1.4.0" + "@endo/patterns": "^1.4.0", + "@noble/hashes": "^1.4.0" }, "devDependencies": { "@agoric/swingset-liveslots": "^0.10.2", "@chain-registry/client": "^1.47.4", "@cosmjs/amino": "^0.32.3", "@cosmjs/proto-signing": "^0.32.3", + "@endo/bundle-source": "^3.2.3", + "@endo/import-bundle": "^1.1.2", "@endo/ses-ava": "^1.2.2", "ava": "^5.3.1", "c8": "^9.1.0", diff --git a/packages/orchestration/src/utils/denomHash.js b/packages/orchestration/src/utils/denomHash.js new file mode 100644 index 00000000000..561ee4b512c --- /dev/null +++ b/packages/orchestration/src/utils/denomHash.js @@ -0,0 +1,22 @@ +// @ts-check +import { sha256 } from '@noble/hashes/sha256'; +import { bytesToHex } from '@noble/hashes/utils'; + +/** + * cf. https://tutorials.cosmos.network/tutorials/6-ibc-dev/ + * + * @param {object} opts + * @param {string} [opts.portId] + * @param {string} [opts.channelId] required unless `path` is supplied + * @param {string} [opts.path] alternative to portId, channelId + * @param {string} opts.denom base denom + */ +export const denomHash = ({ + portId = 'transfer', + channelId = /** @type {string | undefined} */ (undefined), + path = `${portId}/${channelId}`, + denom, +}) => { + const h = sha256.create().update(`${path}/${denom}`).digest(); + return bytesToHex(h).toUpperCase(); +}; diff --git a/packages/orchestration/test/utils/denomHash.test.ts b/packages/orchestration/test/utils/denomHash.test.ts new file mode 100644 index 00000000000..db1355e2fcf --- /dev/null +++ b/packages/orchestration/test/utils/denomHash.test.ts @@ -0,0 +1,18 @@ +import test from '@endo/ses-ava/prepare-endo.js'; + +import bundleSource from '@endo/bundle-source'; +import { importBundle } from '@endo/import-bundle'; +import { createRequire } from 'node:module'; +import { denomHash } from '../../src/utils/denomHash.js'; + +const nodeRequire = createRequire(import.meta.url); + +test('compartment use of denomHash', async t => { + const bundle = await bundleSource(nodeRequire.resolve('./denomHashEx.js')); + const { length } = JSON.stringify(bundle); + t.log('bundle length', length); + const expected = denomHash({ channelId: 'channel-0', denom: 'uatom' }); + + const { denomHashExample } = await importBundle(bundle); + t.deepEqual(denomHashExample(), expected); +}); diff --git a/packages/orchestration/test/utils/denomHashEx.js b/packages/orchestration/test/utils/denomHashEx.js new file mode 100644 index 00000000000..32782c162e9 --- /dev/null +++ b/packages/orchestration/test/utils/denomHashEx.js @@ -0,0 +1,6 @@ +import { denomHash } from '../../src/utils/denomHash.js'; + +export const denomHashExample = () => { + const h = denomHash({ channelId: 'channel-0', denom: 'uatom' }); + return h; +}; diff --git a/yarn.lock b/yarn.lock index 8762b87847b..6c732483aaa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2780,6 +2780,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== +"@noble/hashes@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"