From c8e2b81031e7222c588b3b6eae508e738c8ddd22 Mon Sep 17 00:00:00 2001 From: Pavel Murygin Date: Wed, 16 Feb 2022 22:15:44 +0300 Subject: [PATCH 1/5] Add more builtins --- package-lock.json | 11 +++++++++++ package.json | 5 +++-- src/internal/builtins/common.ts | 29 ++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9907a45bb..de93b0108 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "cids": "0.8.1", "it-length-prefixed": "3.0.1", "it-pipe": "1.1.0", + "js-sha256": "^0.9.0", "libp2p": "=0.33.0", "libp2p-crypto": "=0.20.0", "libp2p-mplex": "=0.10.2", @@ -6108,6 +6109,11 @@ "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==", "dev": true }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -14956,6 +14962,11 @@ "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==", "dev": true }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", diff --git a/package.json b/package.json index a57e77788..6d5cae61c 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,13 @@ "@fluencelabs/avm-runner-background": "0.1.2", "@fluencelabs/avm-runner-interface": "^0.2.0", "async": "3.2.0", + "browser-or-node": "^2.0.0", "bs58": "4.0.1", "buffer": "^6.0.3", "cids": "0.8.1", "it-length-prefixed": "3.0.1", "it-pipe": "1.1.0", + "js-sha256": "^0.9.0", "libp2p": "=0.33.0", "libp2p-crypto": "=0.20.0", "libp2p-mplex": "=0.10.2", @@ -41,8 +43,7 @@ "peer-id": "=0.15.4", "rxjs": "^7.3.0", "ts-pattern": "^3.3.3", - "uuid": "8.3.0", - "browser-or-node": "^2.0.0" + "uuid": "8.3.0" }, "devDependencies": { "@fluencelabs/aqua": "^0.5.3-258", diff --git a/src/internal/builtins/common.ts b/src/internal/builtins/common.ts index 4d021be23..4c6a547f1 100644 --- a/src/internal/builtins/common.ts +++ b/src/internal/builtins/common.ts @@ -16,9 +16,8 @@ import { CallServiceResult } from '@fluencelabs/avm-runner-interface'; import { encode, decode } from 'bs58'; -import { PeerIdB58 } from 'src'; -import { GenericCallServiceHandler, ResultCodes } from '../commonTypes'; -import { KeyPair } from '../KeyPair'; +import { sha256 } from 'js-sha256'; +import { ResultCodes } from '../commonTypes'; const success = (result: any): CallServiceResult => { return { @@ -44,6 +43,14 @@ export const builtInServices = { return success(req.args); }, + array_length: (req) => { + if (req.args.length !== 1) { + return error('array_length accepts exactly one argument, found: ' + req.args.length); + } else { + return success(req.args[0].length); + } + }, + identity: (req) => { if (req.args.length > 1) { return error(`identity accepts up to 1 arguments, received ${req.args.length} arguments`); @@ -98,6 +105,22 @@ export const builtInServices = { return success(Array.from(decode(req.args[0]))); } }, + + sha256_string: (req) => { + if (req.args.length !== 1) { + return error('array_length accepts exactly one argument, found: ' + req.args.length); + } else { + const hash = sha256.create(); + hash.update(req.args[0]); + const buf = hash.arrayBuffer(); + return success(encode(buf)); + } + }, + + concat_strings: (req) => { + const res = ''.concat(...req.args); + return success(res); + }, }, peer: { From eea38963bc1c0f713816a51cba0d2c661428b6cc Mon Sep 17 00:00:00 2001 From: Pavel Murygin Date: Thu, 17 Feb 2022 01:20:52 +0300 Subject: [PATCH 2/5] unit tests --- src/__test__/unit/builtInHandler.spec.ts | 9 +++++++++ src/internal/builtins/common.ts | 7 ++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/__test__/unit/builtInHandler.spec.ts b/src/__test__/unit/builtInHandler.spec.ts index db06212f4..d8a8f8799 100644 --- a/src/__test__/unit/builtInHandler.spec.ts +++ b/src/__test__/unit/builtInHandler.spec.ts @@ -16,6 +16,9 @@ describe('Tests for default handler', () => { ${'op'} | ${'noop'} | ${[1, 2]} | ${0} | ${{}} ${'op'} | ${'array'} | ${[1, 2, 3]} | ${0} | ${[1, 2, 3]} + + ${'op'} | ${'array_length'} | ${[[1, 2, 3]]} | ${0} | ${3} + ${'op'} | ${'array_length'} | ${[]} | ${1} | ${'array_length accepts exactly one argument, found: 0'} ${'op'} | ${'concat'} | ${[[1, 2], [3, 4], [5, 6]]} | ${0} | ${[1, 2, 3, 4, 5, 6]} ${'op'} | ${'concat'} | ${[[1, 2]]} | ${0} | ${[1, 2]} @@ -33,6 +36,12 @@ describe('Tests for default handler', () => { ${'op'} | ${'bytes_from_b58'} | ${["3yZe7d"]} | ${0} | ${[116, 101, 115, 116]} ${'op'} | ${'bytes_from_b58'} | ${["3yZe7d", 1]} | ${1} | ${"bytes_from_b58 accepts only one string argument"} + + ${'op'} | ${'sha256_string'} | ${["hello, world!"]} | ${0} | ${"84V7ZxLW7qKsx1Qvbd63BdGaHxUc3TfT2MBPqAXM7Wyu"} + ${'op'} | ${'sha256_string'} | ${[]} | ${1} | ${"sha256_string accepts exactly one argument, found: 0"} + + ${'op'} | ${'concat_strings'} | ${[]} | ${0} | ${""} + ${'op'} | ${'concat_strings'} | ${["a", "b", "c"]} | ${0} | ${"abc"} ${'peer'} | ${'timeout'} | ${[200, []]} | ${0} | ${[]}} ${'peer'} | ${'timeout'} | ${[200, ['test']]} | ${0} | ${['test']}} diff --git a/src/internal/builtins/common.ts b/src/internal/builtins/common.ts index 4c6a547f1..ff6e9e0e4 100644 --- a/src/internal/builtins/common.ts +++ b/src/internal/builtins/common.ts @@ -18,6 +18,7 @@ import { CallServiceResult } from '@fluencelabs/avm-runner-interface'; import { encode, decode } from 'bs58'; import { sha256 } from 'js-sha256'; import { ResultCodes } from '../commonTypes'; +import Buffer from '../Buffer' const success = (result: any): CallServiceResult => { return { @@ -108,12 +109,12 @@ export const builtInServices = { sha256_string: (req) => { if (req.args.length !== 1) { - return error('array_length accepts exactly one argument, found: ' + req.args.length); + return error('sha256_string accepts exactly one argument, found: ' + req.args.length); } else { const hash = sha256.create(); hash.update(req.args[0]); - const buf = hash.arrayBuffer(); - return success(encode(buf)); + const outBuffer = Buffer.from(hash.arrayBuffer()); + return success(encode(outBuffer)); } }, From 9b4bad55d6323eba13f62a820c6912ff6f4ad0f8 Mon Sep 17 00:00:00 2001 From: Pavel Murygin Date: Thu, 17 Feb 2022 12:22:06 +0300 Subject: [PATCH 3/5] Fix implementation for sha builtin --- package-lock.json | 24 +++++++----------------- package.json | 2 +- src/__test__/unit/builtInHandler.spec.ts | 2 +- src/internal/builtins/common.ts | 13 ++++++------- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index de93b0108..94efcf0bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,13 +20,13 @@ "cids": "0.8.1", "it-length-prefixed": "3.0.1", "it-pipe": "1.1.0", - "js-sha256": "^0.9.0", "libp2p": "=0.33.0", "libp2p-crypto": "=0.20.0", "libp2p-mplex": "=0.10.2", "libp2p-websockets": "^0.16.2", "loglevel": "1.7.0", "multiaddr": "^10.0.1", + "multiformats": "^9.6.4", "peer-id": "=0.15.4", "rxjs": "^7.3.0", "ts-pattern": "^3.3.3", @@ -6109,11 +6109,6 @@ "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==", "dev": true }, - "node_modules/js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" - }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -7001,9 +6996,9 @@ "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" }, "node_modules/multiformats": { - "version": "9.4.6", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.4.6.tgz", - "integrity": "sha512-ngZRO82P7mPvw/3gu5NQ2QiUJGYTS0LAxvQnEAlWCJakvn7YpK2VAd9JWM5oosYUeqoVbkylH/FsqRc4fc2+ag==" + "version": "9.6.4", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.6.4.tgz", + "integrity": "sha512-fCCB6XMrr6CqJiHNjfFNGT0v//dxOBMrOMqUIzpPc/mmITweLEyhvMpY9bF+jZ9z3vaMAau5E8B68DW77QMXkg==" }, "node_modules/multihashes": { "version": "0.4.21", @@ -14962,11 +14957,6 @@ "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==", "dev": true }, - "js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" - }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -15707,9 +15697,9 @@ } }, "multiformats": { - "version": "9.4.6", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.4.6.tgz", - "integrity": "sha512-ngZRO82P7mPvw/3gu5NQ2QiUJGYTS0LAxvQnEAlWCJakvn7YpK2VAd9JWM5oosYUeqoVbkylH/FsqRc4fc2+ag==" + "version": "9.6.4", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.6.4.tgz", + "integrity": "sha512-fCCB6XMrr6CqJiHNjfFNGT0v//dxOBMrOMqUIzpPc/mmITweLEyhvMpY9bF+jZ9z3vaMAau5E8B68DW77QMXkg==" }, "multihashes": { "version": "0.4.21", diff --git a/package.json b/package.json index 6d5cae61c..c2aaa39c7 100644 --- a/package.json +++ b/package.json @@ -33,13 +33,13 @@ "cids": "0.8.1", "it-length-prefixed": "3.0.1", "it-pipe": "1.1.0", - "js-sha256": "^0.9.0", "libp2p": "=0.33.0", "libp2p-crypto": "=0.20.0", "libp2p-mplex": "=0.10.2", "libp2p-websockets": "^0.16.2", "loglevel": "1.7.0", "multiaddr": "^10.0.1", + "multiformats": "^9.6.4", "peer-id": "=0.15.4", "rxjs": "^7.3.0", "ts-pattern": "^3.3.3", diff --git a/src/__test__/unit/builtInHandler.spec.ts b/src/__test__/unit/builtInHandler.spec.ts index d8a8f8799..955f7fad8 100644 --- a/src/__test__/unit/builtInHandler.spec.ts +++ b/src/__test__/unit/builtInHandler.spec.ts @@ -37,7 +37,7 @@ describe('Tests for default handler', () => { ${'op'} | ${'bytes_from_b58'} | ${["3yZe7d"]} | ${0} | ${[116, 101, 115, 116]} ${'op'} | ${'bytes_from_b58'} | ${["3yZe7d", 1]} | ${1} | ${"bytes_from_b58 accepts only one string argument"} - ${'op'} | ${'sha256_string'} | ${["hello, world!"]} | ${0} | ${"84V7ZxLW7qKsx1Qvbd63BdGaHxUc3TfT2MBPqAXM7Wyu"} + ${'op'} | ${'sha256_string'} | ${["hello, world!"]} | ${0} | ${"QmVQ8pg6L1tpoWYeq6dpoWqnzZoSLCh7E96fCFXKvfKD3u"} ${'op'} | ${'sha256_string'} | ${[]} | ${1} | ${"sha256_string accepts exactly one argument, found: 0"} ${'op'} | ${'concat_strings'} | ${[]} | ${0} | ${""} diff --git a/src/internal/builtins/common.ts b/src/internal/builtins/common.ts index ff6e9e0e4..e4761852d 100644 --- a/src/internal/builtins/common.ts +++ b/src/internal/builtins/common.ts @@ -16,9 +16,9 @@ import { CallServiceResult } from '@fluencelabs/avm-runner-interface'; import { encode, decode } from 'bs58'; -import { sha256 } from 'js-sha256'; +import { sha256 } from 'multiformats/hashes/sha2'; import { ResultCodes } from '../commonTypes'; -import Buffer from '../Buffer' +import Buffer from '../Buffer'; const success = (result: any): CallServiceResult => { return { @@ -107,14 +107,13 @@ export const builtInServices = { } }, - sha256_string: (req) => { + sha256_string: async (req) => { if (req.args.length !== 1) { return error('sha256_string accepts exactly one argument, found: ' + req.args.length); } else { - const hash = sha256.create(); - hash.update(req.args[0]); - const outBuffer = Buffer.from(hash.arrayBuffer()); - return success(encode(outBuffer)); + const inBuffer = Buffer.from(req.args[0]); + const digest = await sha256.digest(inBuffer); + return success(encode(digest)); } }, From 8b4241e2c6f9702ec1ab84fa24bc8c1ba159c398 Mon Sep 17 00:00:00 2001 From: Pavel Murygin Date: Thu, 17 Feb 2022 12:24:42 +0300 Subject: [PATCH 4/5] fix typo --- src/internal/builtins/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/builtins/common.ts b/src/internal/builtins/common.ts index e4761852d..d4cd9d43b 100644 --- a/src/internal/builtins/common.ts +++ b/src/internal/builtins/common.ts @@ -113,7 +113,7 @@ export const builtInServices = { } else { const inBuffer = Buffer.from(req.args[0]); const digest = await sha256.digest(inBuffer); - return success(encode(digest)); + return success(encode(digest.bytes)); } }, From 2e363903a026750a84ebfe8a08e00eec68ab40b9 Mon Sep 17 00:00:00 2001 From: Pavel Murygin Date: Thu, 17 Feb 2022 12:59:44 +0300 Subject: [PATCH 5/5] Implement the same behaviour as on rust node --- src/__test__/unit/builtInHandler.spec.ts | 3 ++- src/internal/builtins/common.ts | 15 ++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/__test__/unit/builtInHandler.spec.ts b/src/__test__/unit/builtInHandler.spec.ts index 955f7fad8..491b94e94 100644 --- a/src/__test__/unit/builtInHandler.spec.ts +++ b/src/__test__/unit/builtInHandler.spec.ts @@ -38,7 +38,8 @@ describe('Tests for default handler', () => { ${'op'} | ${'bytes_from_b58'} | ${["3yZe7d", 1]} | ${1} | ${"bytes_from_b58 accepts only one string argument"} ${'op'} | ${'sha256_string'} | ${["hello, world!"]} | ${0} | ${"QmVQ8pg6L1tpoWYeq6dpoWqnzZoSLCh7E96fCFXKvfKD3u"} - ${'op'} | ${'sha256_string'} | ${[]} | ${1} | ${"sha256_string accepts exactly one argument, found: 0"} + ${'op'} | ${'sha256_string'} | ${["hello, world!", true]} | ${0} | ${"84V7ZxLW7qKsx1Qvbd63BdGaHxUc3TfT2MBPqAXM7Wyu"} + ${'op'} | ${'sha256_string'} | ${[]} | ${1} | ${"sha256_string accepts 1-3 arguments, found: 0"} ${'op'} | ${'concat_strings'} | ${[]} | ${0} | ${""} ${'op'} | ${'concat_strings'} | ${["a", "b", "c"]} | ${0} | ${"abc"} diff --git a/src/internal/builtins/common.ts b/src/internal/builtins/common.ts index d4cd9d43b..bbb7dee5c 100644 --- a/src/internal/builtins/common.ts +++ b/src/internal/builtins/common.ts @@ -108,12 +108,17 @@ export const builtInServices = { }, sha256_string: async (req) => { - if (req.args.length !== 1) { - return error('sha256_string accepts exactly one argument, found: ' + req.args.length); + if (req.args.length < 1 || req.args.length > 3) { + return error('sha256_string accepts 1-3 arguments, found: ' + req.args.length); } else { - const inBuffer = Buffer.from(req.args[0]); - const digest = await sha256.digest(inBuffer); - return success(encode(digest.bytes)); + const [input, digestOnly, asBytes] = req.args; + const inBuffer = Buffer.from(input); + const multihash = await sha256.digest(inBuffer); + + const outBytes = digestOnly ? multihash.digest : multihash.bytes; + const res = asBytes ? Array.from(outBytes) : encode(outBytes); + + return success(res); } },