diff --git a/.pnp.cjs b/.pnp.cjs index 708e5c0c6f7..fcffa1832f4 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -2895,6 +2895,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@dashevo/dpns-contract", "workspace:packages/dpns-contract"],\ ["@dashevo/dpp", "workspace:packages/js-dpp"],\ ["@dashevo/wasm-re2", "npm:1.0.2"],\ + ["@types/bs58", "npm:4.0.1"],\ ["@types/node", "npm:14.17.34"],\ ["ajv", "npm:8.8.1"],\ ["assert", "npm:2.0.0"],\ @@ -2930,7 +2931,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["stream-browserify", "npm:3.0.0"],\ ["stream-http", "npm:3.2.0"],\ ["string_decoder", "npm:1.3.0"],\ - ["terser-webpack-plugin", "virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:5.3.3"],\ ["ts-loader", "virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:8.3.0"],\ ["typescript", "patch:typescript@npm%3A3.9.10#~builtin::version=3.9.10&hash=3bd3d3"],\ ["url", "npm:0.11.0"],\ @@ -3981,6 +3981,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["@types/bs58", [\ + ["npm:4.0.1", {\ + "packageLocation": "./.yarn/cache/@types-bs58-npm-4.0.1-179273a650-5063fed6bb.zip/node_modules/@types/bs58/",\ + "packageDependencies": [\ + ["@types/bs58", "npm:4.0.1"],\ + ["base-x", "npm:3.0.9"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@types/cacheable-request", [\ ["npm:6.0.3", {\ "packageLocation": "./.yarn/cache/@types-cacheable-request-npm-6.0.3-770619032a-d9b26403fe.zip/node_modules/@types/cacheable-request/",\ @@ -16713,10 +16723,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "HARD"\ }],\ - ["virtual:ad53cff31b1dbd4927a99e71702e3b8b10338636eaff010987c27c9ccea2d52af36900a9e36a4231cbb6e5464248ccc9c1da5d1d24d9b0f4f95660296b1060a6#npm:5.3.3", {\ - "packageLocation": "./.yarn/__virtual__/terser-webpack-plugin-virtual-65e4fce360/0/cache/terser-webpack-plugin-npm-5.3.3-659a8e4514-4b8d508d8a.zip/node_modules/terser-webpack-plugin/",\ + ["virtual:a1758743d243877493a02719691b2bf5513261873450aca581311be1ead841af63c0be982c400355949a0dcad332960c6e3ed3885051f0427d191c70a7fc9856#npm:5.3.3", {\ + "packageLocation": "./.yarn/__virtual__/terser-webpack-plugin-virtual-00677cea6c/0/cache/terser-webpack-plugin-npm-5.3.3-659a8e4514-4b8d508d8a.zip/node_modules/terser-webpack-plugin/",\ "packageDependencies": [\ - ["terser-webpack-plugin", "virtual:ad53cff31b1dbd4927a99e71702e3b8b10338636eaff010987c27c9ccea2d52af36900a9e36a4231cbb6e5464248ccc9c1da5d1d24d9b0f4f95660296b1060a6#npm:5.3.3"],\ + ["terser-webpack-plugin", "virtual:a1758743d243877493a02719691b2bf5513261873450aca581311be1ead841af63c0be982c400355949a0dcad332960c6e3ed3885051f0427d191c70a7fc9856#npm:5.3.3"],\ ["@jridgewell/trace-mapping", "npm:0.3.15"],\ ["@swc/core", null],\ ["@types/esbuild", null],\ @@ -16729,7 +16739,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["serialize-javascript", "npm:6.0.0"],\ ["terser", "npm:5.14.2"],\ ["uglify-js", null],\ - ["webpack", "virtual:ad53cff31b1dbd4927a99e71702e3b8b10338636eaff010987c27c9ccea2d52af36900a9e36a4231cbb6e5464248ccc9c1da5d1d24d9b0f4f95660296b1060a6#npm:5.76.1"]\ + ["webpack", "virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:5.76.1"]\ ],\ "packagePeers": [\ "@swc/core",\ @@ -16743,10 +16753,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "HARD"\ }],\ - ["virtual:d33ae3339557a5a7f9578102570f67e936a4c1af78c1322b63541bc89dc24f419318f0ddd4e3241021a7e0be1ce717f7ffe8cc168317f38d8d886f6915b6482d#npm:5.3.3", {\ - "packageLocation": "./.yarn/__virtual__/terser-webpack-plugin-virtual-9f9f9cad8b/0/cache/terser-webpack-plugin-npm-5.3.3-659a8e4514-4b8d508d8a.zip/node_modules/terser-webpack-plugin/",\ + ["virtual:ad53cff31b1dbd4927a99e71702e3b8b10338636eaff010987c27c9ccea2d52af36900a9e36a4231cbb6e5464248ccc9c1da5d1d24d9b0f4f95660296b1060a6#npm:5.3.3", {\ + "packageLocation": "./.yarn/__virtual__/terser-webpack-plugin-virtual-65e4fce360/0/cache/terser-webpack-plugin-npm-5.3.3-659a8e4514-4b8d508d8a.zip/node_modules/terser-webpack-plugin/",\ "packageDependencies": [\ - ["terser-webpack-plugin", "virtual:d33ae3339557a5a7f9578102570f67e936a4c1af78c1322b63541bc89dc24f419318f0ddd4e3241021a7e0be1ce717f7ffe8cc168317f38d8d886f6915b6482d#npm:5.3.3"],\ + ["terser-webpack-plugin", "virtual:ad53cff31b1dbd4927a99e71702e3b8b10338636eaff010987c27c9ccea2d52af36900a9e36a4231cbb6e5464248ccc9c1da5d1d24d9b0f4f95660296b1060a6#npm:5.3.3"],\ ["@jridgewell/trace-mapping", "npm:0.3.15"],\ ["@swc/core", null],\ ["@types/esbuild", null],\ @@ -16759,7 +16769,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["serialize-javascript", "npm:6.0.0"],\ ["terser", "npm:5.14.2"],\ ["uglify-js", null],\ - ["webpack", "virtual:45f214395bc38640da4dc5e940482d5df0572c5384e0262802601d1973e71077ec8bbd76b77eafa4c0550b706b664abd84d63fd67a5897139f0b2675530fc84f#npm:5.76.1"]\ + ["webpack", "virtual:ad53cff31b1dbd4927a99e71702e3b8b10338636eaff010987c27c9ccea2d52af36900a9e36a4231cbb6e5464248ccc9c1da5d1d24d9b0f4f95660296b1060a6#npm:5.76.1"]\ ],\ "packagePeers": [\ "@swc/core",\ @@ -16773,10 +16783,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "HARD"\ }],\ - ["virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:5.3.3", {\ - "packageLocation": "./.yarn/__virtual__/terser-webpack-plugin-virtual-e7099d0e79/0/cache/terser-webpack-plugin-npm-5.3.3-659a8e4514-4b8d508d8a.zip/node_modules/terser-webpack-plugin/",\ + ["virtual:d33ae3339557a5a7f9578102570f67e936a4c1af78c1322b63541bc89dc24f419318f0ddd4e3241021a7e0be1ce717f7ffe8cc168317f38d8d886f6915b6482d#npm:5.3.3", {\ + "packageLocation": "./.yarn/__virtual__/terser-webpack-plugin-virtual-9f9f9cad8b/0/cache/terser-webpack-plugin-npm-5.3.3-659a8e4514-4b8d508d8a.zip/node_modules/terser-webpack-plugin/",\ "packageDependencies": [\ - ["terser-webpack-plugin", "virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:5.3.3"],\ + ["terser-webpack-plugin", "virtual:d33ae3339557a5a7f9578102570f67e936a4c1af78c1322b63541bc89dc24f419318f0ddd4e3241021a7e0be1ce717f7ffe8cc168317f38d8d886f6915b6482d#npm:5.3.3"],\ ["@jridgewell/trace-mapping", "npm:0.3.15"],\ ["@swc/core", null],\ ["@types/esbuild", null],\ @@ -16789,7 +16799,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["serialize-javascript", "npm:6.0.0"],\ ["terser", "npm:5.14.2"],\ ["uglify-js", null],\ - ["webpack", "virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:5.76.1"]\ + ["webpack", "virtual:45f214395bc38640da4dc5e940482d5df0572c5384e0262802601d1973e71077ec8bbd76b77eafa4c0550b706b664abd84d63fd67a5897139f0b2675530fc84f#npm:5.76.1"]\ ],\ "packagePeers": [\ "@swc/core",\ @@ -18026,7 +18036,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["neo-async", "npm:2.6.2"],\ ["schema-utils", "npm:3.1.1"],\ ["tapable", "npm:2.2.1"],\ - ["terser-webpack-plugin", "virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:5.3.3"],\ + ["terser-webpack-plugin", "virtual:a1758743d243877493a02719691b2bf5513261873450aca581311be1ead841af63c0be982c400355949a0dcad332960c6e3ed3885051f0427d191c70a7fc9856#npm:5.3.3"],\ ["watchpack", "npm:2.4.0"],\ ["webpack-cli", "virtual:e2d057e7cc143d3cb9bec864f4a2d862441b5a09f81f8e6c46e7a098cbc89e4d07017cc6e2e2142d5704bb55da853cbec2d025ebc0b30e8696c31380c00f2c7d#npm:4.9.1"],\ ["webpack-sources", "npm:3.2.3"]\ diff --git a/.yarn/cache/@types-bs58-npm-4.0.1-179273a650-5063fed6bb.zip b/.yarn/cache/@types-bs58-npm-4.0.1-179273a650-5063fed6bb.zip new file mode 100644 index 00000000000..1beab581df0 Binary files /dev/null and b/.yarn/cache/@types-bs58-npm-4.0.1-179273a650-5063fed6bb.zip differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 092419d0225..715e3616234 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,57 @@ +## [0.24.0-dev.17](https://github.com/dashpay/platform/compare/v0.24.0-dev.16...v0.24.0-dev.17) (2023-04-04) + + +### Features + +* **dashmate:** add new quroum in dashcore config ([#862](https://github.com/dashpay/platform/issues/862)) +* **dashmate:** enable platform option ([#853](https://github.com/dashpay/platform/issues/853)) +* **dashmate:** generate self-signed certificates in the `setup` command ([#869](https://github.com/dashpay/platform/issues/869)) +* **dashmate:** high-performance nodes registration with `setup` command ([#794](https://github.com/dashpay/platform/issues/794)) +* **dashmate:** hint to setup a node on start failure ([#866](https://github.com/dashpay/platform/issues/866)) +* **dpp:** add fees API to rust wasm bindings ([#830](https://github.com/dashpay/platform/issues/830)) +* **dpp:** optional execution context in rs-dpp ([#811](https://github.com/dashpay/platform/issues/811)) +* **dpp:** state transition applicator ([#878](https://github.com/dashpay/platform/issues/878)) +* **rs-dpp:** migrate fees from js-dpp v0.24 ([#851](https://github.com/dashpay/platform/issues/851)) +* state transition conversion ([#844](https://github.com/dashpay/platform/issues/844)) +* **wasm-dpp:** add tests for state transition basic validator ([#857](https://github.com/dashpay/platform/issues/857)) +* **wasm-dpp:** DashPlatformProtocol tests ([#841](https://github.com/dashpay/platform/issues/841)) +* **wasm-dpp:** identity transitions additional functionality ([#855](https://github.com/dashpay/platform/issues/855)) +* **wasm-dpp:** implement validateStateTransitionStateFactory tests ([#861](https://github.com/dashpay/platform/issues/861)) +* **wasm-dpp:** provide external entropy generator to document factory ([#845](https://github.com/dashpay/platform/issues/845)) +* **wasm-dpp:** validate_state_transition_identity_signature binding and test ([#865](https://github.com/dashpay/platform/issues/865)) + + +### Bug Fixes + +* **dashmate:** ambiguous validation errors for file certificates ([#870](https://github.com/dashpay/platform/issues/870)) +* **dashmate:** config.isPlatformEnabled is not a function ([#872](https://github.com/dashpay/platform/issues/872)) +* **dpp:** incorrect public key validator schema in ST Facade ([#854](https://github.com/dashpay/platform/issues/854)) +* **scripts:** update configure_test_network for hpmn ([#863](https://github.com/dashpay/platform/issues/863)) +* **wasm-dpp:** fix decoding protocol version varint error to match previous implementation ([#849](https://github.com/dashpay/platform/issues/849)) + + +### Tests + +* **rs-drive:** fix path to EntropyGenerator ([#856](https://github.com/dashpay/platform/issues/856)) + + +### Code Refactoring + +* **dashmate:** always keep platform config ([#868](https://github.com/dashpay/platform/issues/868)) +* **dashmate:** move core devnet options to subsection ([#867](https://github.com/dashpay/platform/issues/867)) + + +### Build System + +* **dashmate:** fix deb package release ([#864](https://github.com/dashpay/platform/issues/864)) +* operations in configure.sh script were in a wrong order ([#876](https://github.com/dashpay/platform/issues/876)) + + +### Miscellaneous Chores + +* `rs-dpp` and `wasm-dpp` updates for integration ([#875](https://github.com/dashpay/platform/issues/875)) +* **wasm-dpp:** proper identifier buffer inheritance ([#879](https://github.com/dashpay/platform/issues/879)) + ## [0.24.0-dev.16](https://github.com/dashpay/platform/compare/v0.24.0-dev.15...v0.24.0-dev.16) (2023-03-22) diff --git a/Cargo.lock b/Cargo.lock index 7b10e76a82b..986b8740f55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -360,7 +360,7 @@ dependencies = [ [[package]] name = "bls-dash-sys" version = "1.2.5" -source = "git+https://github.com/dashpay/bls-signatures?branch=feat/clone#ea2552b44b6403c153d1ea7f4556c1d576f1c547" +source = "git+https://github.com/dashpay/bls-signatures?branch=feat/clone#0a8919751fac9674413255e308359d2e72b17ccf" dependencies = [ "bindgen 0.65.1", "cc", @@ -370,7 +370,7 @@ dependencies = [ [[package]] name = "bls-signatures" version = "1.2.5" -source = "git+https://github.com/dashpay/bls-signatures?branch=feat/clone#ea2552b44b6403c153d1ea7f4556c1d576f1c547" +source = "git+https://github.com/dashpay/bls-signatures?branch=feat/clone#0a8919751fac9674413255e308359d2e72b17ccf" dependencies = [ "bls-dash-sys", "rand", diff --git a/package.json b/package.json index 813502242d9..87aad11ad10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/platform", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "private": true, "scripts": { "setup": "yarn install && yarn run build && yarn run configure", diff --git a/packages/bench-suite/package.json b/packages/bench-suite/package.json index f6133527ee2..946086cacaf 100644 --- a/packages/bench-suite/package.json +++ b/packages/bench-suite/package.json @@ -1,7 +1,7 @@ { "name": "@dashevo/bench-suite", "private": true, - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Dash Platform benchmark tool", "scripts": { "bench": "node ./bin/bench.js", diff --git a/packages/dapi-grpc/package.json b/packages/dapi-grpc/package.json index 54728641116..7410dda4a1b 100644 --- a/packages/dapi-grpc/package.json +++ b/packages/dapi-grpc/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dapi-grpc", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "DAPI GRPC definition file and generated clients", "browser": "browser.js", "main": "node.js", diff --git a/packages/dapi/package.json b/packages/dapi/package.json index 963e82ba036..19788940e5f 100644 --- a/packages/dapi/package.json +++ b/packages/dapi/package.json @@ -1,7 +1,7 @@ { "name": "@dashevo/dapi", "private": true, - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "A decentralized API for the Dash network", "scripts": { "api": "node scripts/api.js", diff --git a/packages/dash-spv/package.json b/packages/dash-spv/package.json index 0c957cb4204..bd1e930a67c 100644 --- a/packages/dash-spv/package.json +++ b/packages/dash-spv/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dash-spv", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Repository containing SPV functions used by @dashevo", "main": "index.js", "scripts": { diff --git a/packages/dashmate/package.json b/packages/dashmate/package.json index 0aad4173bf0..511bedebae8 100644 --- a/packages/dashmate/package.json +++ b/packages/dashmate/package.json @@ -1,6 +1,6 @@ { "name": "dashmate", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Distribution package for Dash node installation", "scripts": { "lint": "eslint .", diff --git a/packages/dashpay-contract/package.json b/packages/dashpay-contract/package.json index 9597174bb78..eb0d6f712a9 100644 --- a/packages/dashpay-contract/package.json +++ b/packages/dashpay-contract/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dashpay-contract", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Reference contract of the DashPay DPA on Dash Evolution", "scripts": { "lint": "eslint .", diff --git a/packages/dpns-contract/package.json b/packages/dpns-contract/package.json index 525c377d3b1..c0d2f79b968 100644 --- a/packages/dpns-contract/package.json +++ b/packages/dpns-contract/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dpns-contract", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "A contract and helper scripts for DPNS DApp", "scripts": { "lint": "eslint .", diff --git a/packages/feature-flags-contract/package.json b/packages/feature-flags-contract/package.json index c9dddae1441..ea38f9ad1a8 100644 --- a/packages/feature-flags-contract/package.json +++ b/packages/feature-flags-contract/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/feature-flags-contract", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Data Contract to store Dash Platform feature flags", "scripts": { "build": "", diff --git a/packages/js-dapi-client/package.json b/packages/js-dapi-client/package.json index 7aa27dcf185..7338949d80d 100644 --- a/packages/js-dapi-client/package.json +++ b/packages/js-dapi-client/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dapi-client", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Client library used to access Dash DAPI endpoints", "main": "lib/index.js", "contributors": [ diff --git a/packages/js-dash-sdk/package.json b/packages/js-dash-sdk/package.json index 5f7fbc456f3..ef3ba451c93 100644 --- a/packages/js-dash-sdk/package.json +++ b/packages/js-dash-sdk/package.json @@ -1,6 +1,6 @@ { "name": "dash", - "version": "3.24.0-dev.16", + "version": "3.24.0-dev.17", "description": "Dash library for JavaScript/TypeScript ecosystem (Wallet, DAPI, Primitives, BLS, ...)", "main": "build/src/index.js", "unpkg": "dist/dash.min.js", diff --git a/packages/js-dpp/package.json b/packages/js-dpp/package.json index 52c7bba1de6..ab3285372b1 100644 --- a/packages/js-dpp/package.json +++ b/packages/js-dpp/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dpp", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "The JavaScript implementation of the Dash Platform Protocol", "scripts": { "lint": "eslint .", diff --git a/packages/js-drive/package.json b/packages/js-drive/package.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/js-grpc-common/package.json b/packages/js-grpc-common/package.json index 8dcd9229853..3a2e8646ed2 100644 --- a/packages/js-grpc-common/package.json +++ b/packages/js-grpc-common/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/grpc-common", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Common GRPC library", "main": "index.js", "scripts": { diff --git a/packages/masternode-reward-shares-contract/package.json b/packages/masternode-reward-shares-contract/package.json index 35507b0c174..5038793e762 100644 --- a/packages/masternode-reward-shares-contract/package.json +++ b/packages/masternode-reward-shares-contract/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/masternode-reward-shares-contract", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "A contract and helper scripts for reward sharing", "scripts": { "lint": "eslint .", diff --git a/packages/platform-test-suite/package.json b/packages/platform-test-suite/package.json index 3394e19a01b..35039a27973 100644 --- a/packages/platform-test-suite/package.json +++ b/packages/platform-test-suite/package.json @@ -1,7 +1,7 @@ { "name": "@dashevo/platform-test-suite", "private": true, - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Dash Network end-to-end tests", "scripts": { "test": "yarn exec bin/test.sh", diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index ae4d1c718d6..b9f89b095e0 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -3,6 +3,7 @@ use crate::data_contract::validation::data_contract_validator::DataContractValid use crate::data_contract::{DataContract, DataContractFactory}; use crate::prelude::Identifier; +use crate::util::entropy_generator::EntropyGenerator; use crate::validation::SimpleConsensusValidationResult; use crate::version::ProtocolVersionValidator; use crate::ProtocolError; @@ -29,6 +30,22 @@ impl DataContractFacade { } } + pub fn new_with_entropy_generator( + protocol_version: u32, + protocol_version_validator: Arc, + entropy_generator: Box, + ) -> Self { + let validator = Arc::new(DataContractValidator::new(protocol_version_validator)); + Self { + factory: DataContractFactory::new_with_entropy_generator( + protocol_version, + validator.clone(), + entropy_generator, + ), + data_contract_validator: validator, + } + } + /// Create Data Contract pub fn create( &self, diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 5b8b9a6a0eb..7d8adb6ef9b 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -176,7 +176,7 @@ impl DataContractFactory { data_contract: DataContract, ) -> Result { //todo: is this right for entropy? - let entropy = data_contract.entropy.clone(); + let entropy = data_contract.entropy; Ok(DataContractCreateTransition { protocol_version: self.protocol_version, transition_type: StateTransitionType::DataContractCreate, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/apply_data_contract_create_transition_factory.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/apply_data_contract_create_transition_factory.rs index 66bf9546333..72e97600b8c 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/apply_data_contract_create_transition_factory.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/apply_data_contract_create_transition_factory.rs @@ -1,19 +1,21 @@ use anyhow::Result; +use std::sync::Arc; use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use super::DataContractCreateTransition; +#[derive(Clone)] pub struct ApplyDataContractCreateTransition where SR: StateRepositoryLike, { - state_repository: SR, + state_repository: Arc, } impl ApplyDataContractCreateTransition { - pub fn new(state_repository: SR) -> Self { + pub fn new(state_repository: Arc) -> Self { ApplyDataContractCreateTransition { state_repository } } } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/apply_data_contract_update_transition_factory.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/apply_data_contract_update_transition_factory.rs index 1e63d38175f..888954356ea 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/apply_data_contract_update_transition_factory.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/apply_data_contract_update_transition_factory.rs @@ -1,19 +1,21 @@ use anyhow::Result; +use std::sync::Arc; use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use super::DataContractUpdateTransition; +#[derive(Clone)] pub struct ApplyDataContractUpdateTransition where SR: StateRepositoryLike, { - state_repository: SR, + state_repository: Arc, } impl ApplyDataContractUpdateTransition { - pub fn new(state_repository: SR) -> Self { + pub fn new(state_repository: Arc) -> Self { ApplyDataContractUpdateTransition { state_repository } } } diff --git a/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs index c8511fb4b24..b354702e305 100644 --- a/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs @@ -98,7 +98,7 @@ where let identity = context .state_repository .fetch_identity( - &to_user_id.into(), + &to_user_id, Some(context.state_transition_execution_context), ) .await?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index f0f4f409e7f..179d7c1f799 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::sync::Arc; use crate::document::{Document, ExtendedDocument}; use crate::prelude::TimestampMillis; @@ -14,18 +15,19 @@ use super::{ DocumentsBatchTransition, }; +#[derive(Clone)] pub struct ApplyDocumentsBatchTransition where SR: StateRepositoryLike, { - state_repository: SR, + state_repository: Arc, } impl ApplyDocumentsBatchTransition where SR: StateRepositoryLike, { - pub fn new(state_repository: SR) -> ApplyDocumentsBatchTransition + pub fn new(state_repository: Arc) -> ApplyDocumentsBatchTransition where SR: StateRepositoryLike, { @@ -38,7 +40,7 @@ where execution_context: StateTransitionExecutionContext, ) -> Result<(), ProtocolError> { apply_documents_batch_transition( - &self.state_repository, + self.state_repository.as_ref(), state_transition, &execution_context, ) diff --git a/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs b/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs index 622195ec5e5..c50ef124550 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs @@ -32,3 +32,15 @@ impl From for ConsensusError { Self::SignatureError(SignatureError::WrongPublicKeyPurposeError(err)) } } + +// This is a separate error of the same name, but from ProtocolError +impl From for ConsensusError { + fn from(value: crate::state_transition::errors::WrongPublicKeyPurposeError) -> Self { + Self::SignatureError(SignatureError::WrongPublicKeyPurposeError( + WrongPublicKeyPurposeError::new( + value.public_key_purpose(), + value.key_purpose_requirement(), + ), + )) + } +} diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_public_key_hash_fetcher.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_public_key_hash_fetcher.rs index 43ba7b79b79..852ca2f758e 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_public_key_hash_fetcher.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_public_key_hash_fetcher.rs @@ -9,7 +9,7 @@ use crate::DPPError; pub struct AssetLockPublicKeyHashFetcher { state_repository: Arc, - asset_lock_transaction_output_fetcher: AssetLockTransactionOutputFetcher, + asset_lock_transaction_output_fetcher: Arc>, } impl AssetLockPublicKeyHashFetcher @@ -18,7 +18,7 @@ where { pub fn new( state_repository: Arc, - asset_lock_transaction_output_fetcher: AssetLockTransactionOutputFetcher, + asset_lock_transaction_output_fetcher: Arc>, ) -> Self { Self { state_repository, diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs index 1103013cc09..a96cbbaf21a 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs @@ -11,6 +11,7 @@ use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::DPPError; +#[derive(Clone)] pub struct AssetLockTransactionOutputFetcher { state_repository: Arc, } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/apply_identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/apply_identity_create_transition.rs index ed8d2f50189..c4dbde51b3a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/apply_identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/apply_identity_create_transition.rs @@ -9,6 +9,7 @@ use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::StateTransitionLike; +#[derive(Clone)] pub struct ApplyIdentityCreateTransition where SR: StateRepositoryLike, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 65e33f83c49..404dd783d85 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -191,6 +191,12 @@ impl IdentityCreateTransition { state_transition.set_asset_lock_proof(AssetLockProof::try_from(proof)?)?; } + if let Some(signature) = + transition_map.get_optional_binary_data(property_names::SIGNATURE)? + { + state_transition.set_signature(signature); + } + state_transition.protocol_version = transition_map.get_integer(property_names::PROTOCOL_VERSION)?; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs index ac55df6f3b7..9f7e4564006 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs @@ -68,7 +68,7 @@ pub async fn validate_identity_create_transition_state( .map_err(|e| { NonConsensusError::StateRepositoryFetchError(format!( "state repository fetch identity balance error: {}", - e.to_string() + e )) })?; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs index 319f5281715..40b52fe5db9 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs @@ -54,7 +54,7 @@ where .map_err(|e| { NonConsensusError::StateRepositoryFetchError(format!( "state repository fetch identity for credit withdrawal verification error: {}", - e.to_string() + e )) })?; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs index 8342bc3511a..23877a71c95 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs @@ -8,6 +8,7 @@ use crate::identity::state_transition::identity_topup_transition::IdentityTopUpT use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +#[derive(Clone)] pub struct ApplyIdentityTopUpTransition where SR: StateRepositoryLike, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs index 472b4510ddd..18caecc6a65 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs @@ -30,7 +30,7 @@ where ) -> Result, ProtocolError> { validate_identity_topup_transition_state(&self.state_repository, data, execution_context) .await - .map(|result| result.into()) + .map(|result| result) .map_err(|err| err.into()) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs index e9b4e74ccc2..cb84920747b 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs @@ -7,7 +7,8 @@ use crate::{state_repository::StateRepositoryLike, ProtocolError}; use super::identity_update_transition::IdentityUpdateTransition; -struct ApplyIdentityUpdateTransition { +#[derive(Clone)] +pub struct ApplyIdentityUpdateTransition { state_repository: Arc, } @@ -19,9 +20,9 @@ where Self { state_repository } } - async fn apply( + pub async fn apply( &self, - state_transition: IdentityUpdateTransition, + state_transition: &IdentityUpdateTransition, execution_context: &StateTransitionExecutionContext, ) -> Result<(), ProtocolError> { apply_identity_update_transition( @@ -36,7 +37,7 @@ where /// Apply Identity Update state transition pub async fn apply_identity_update_transition( state_repository: &impl StateRepositoryLike, - state_transition: IdentityUpdateTransition, + state_transition: &IdentityUpdateTransition, execution_context: &StateTransitionExecutionContext, ) -> Result<(), ProtocolError> { state_repository diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs index 315a0996d34..7382e1a856b 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs @@ -50,7 +50,7 @@ where .map_err(|e| { NonConsensusError::StateRepositoryFetchError(format!( "state repository fetch identity for identity update validation error: {}", - e.to_string() + e )) })?; @@ -113,7 +113,7 @@ where .map_err(|e| { NonConsensusError::StateRepositoryFetchError(format!( "state repository fetch latest platform block time error: {}", - e.to_string() + e )) })?; diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index aff18564950..63a9062c710 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -107,6 +107,7 @@ where bls: &impl BlsModule, ) -> Result<(), ProtocolError> { self.verify_public_key_level_and_purpose(public_key)?; + self.verify_public_key_is_enabled(public_key)?; let signature = self.get_signature(); if signature.is_empty() { diff --git a/packages/rs-dpp/src/state_transition/apply_state_transition.rs b/packages/rs-dpp/src/state_transition/apply_state_transition.rs new file mode 100644 index 00000000000..aeb77c0fb7d --- /dev/null +++ b/packages/rs-dpp/src/state_transition/apply_state_transition.rs @@ -0,0 +1,96 @@ +use std::sync::Arc; +use anyhow::anyhow; +use crate::data_contract::state_transition::data_contract_create_transition::apply_data_contract_create_transition_factory::ApplyDataContractCreateTransition; +use crate::data_contract::state_transition::data_contract_update_transition::apply_data_contract_update_transition_factory::ApplyDataContractUpdateTransition; +use crate::document::state_transition::documents_batch_transition::apply_documents_batch_transition_factory::ApplyDocumentsBatchTransition; +use crate::identity::state_transition::asset_lock_proof::AssetLockTransactionOutputFetcher; +use crate::identity::state_transition::identity_create_transition::ApplyIdentityCreateTransition; +use crate::identity::state_transition::identity_topup_transition::ApplyIdentityTopUpTransition; +use crate::identity::state_transition::identity_update_transition::apply_identity_update_transition::ApplyIdentityUpdateTransition; +use crate::ProtocolError; +use crate::state_repository::StateRepositoryLike; +use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use crate::state_transition::StateTransition; + +#[derive(Clone)] +pub struct ApplyStateTransition { + apply_data_contract_create_transition: ApplyDataContractCreateTransition, + apply_data_contract_update_transition: ApplyDataContractUpdateTransition, + apply_documents_batch_transition: ApplyDocumentsBatchTransition, + apply_identity_create_transition: ApplyIdentityCreateTransition, + apply_identity_top_up_transition: ApplyIdentityTopUpTransition, + apply_identity_update_transition: ApplyIdentityUpdateTransition, +} + +impl ApplyStateTransition +where + SR: StateRepositoryLike, +{ + pub fn new( + state_repository: Arc, + asset_lock_transaction_output_fetcher: Arc>, + ) -> Self { + Self { + apply_data_contract_create_transition: ApplyDataContractCreateTransition::new( + state_repository.clone(), + ), + apply_data_contract_update_transition: ApplyDataContractUpdateTransition::new( + state_repository.clone(), + ), + apply_documents_batch_transition: ApplyDocumentsBatchTransition::new( + state_repository.clone(), + ), + apply_identity_create_transition: ApplyIdentityCreateTransition::new( + state_repository.clone(), + ), + apply_identity_top_up_transition: ApplyIdentityTopUpTransition::new( + state_repository.clone(), + asset_lock_transaction_output_fetcher, + ), + apply_identity_update_transition: ApplyIdentityUpdateTransition::new( + state_repository.clone(), + ), + } + } + + pub async fn apply(&self, state_transition: &StateTransition) -> Result<(), ProtocolError> { + // TODO(v0.24-merge): is it fine using default context here? + // (Check if applier is actually used in the drive executor) + let execution_context = StateTransitionExecutionContext::default(); + match state_transition { + StateTransition::DataContractCreate(st) => self + .apply_data_contract_create_transition + .apply_data_contract_create_transition(st, Some(&execution_context)) + .await + .map_err(ProtocolError::from), + StateTransition::DataContractUpdate(st) => self + .apply_data_contract_update_transition + .apply_data_contract_update_transition(st, &execution_context) + .await + .map_err(ProtocolError::from), + StateTransition::DocumentsBatch(st) => { + self.apply_documents_batch_transition + .apply(st, execution_context) + .await + } + StateTransition::IdentityCreate(st) => self + .apply_identity_create_transition + .apply_identity_create_transition(st, &execution_context) + .await + .map_err(ProtocolError::from), + StateTransition::IdentityTopUp(st) => self + .apply_identity_top_up_transition + .apply(st, &execution_context) + .await + .map_err(ProtocolError::from), + StateTransition::IdentityCreditWithdrawal(_) => { + Err(ProtocolError::Error(anyhow!("Not implemented yet"))) + } + StateTransition::IdentityUpdate(st) => { + self.apply_identity_update_transition + .apply(st, &execution_context) + .await + } + } + } +} diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 0401f9a4c9a..b00868d980b 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -34,6 +34,7 @@ pub mod errors; pub mod fee; pub mod state_transition_execution_context; +pub mod apply_state_transition; mod example; mod serialization; mod state_transition_action; diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index 145b1fd0a23..2e8cdf7efd5 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -15,6 +15,7 @@ use crate::identity::state_transition::validate_public_key_signatures::PublicKey use crate::identity::validation::{PUBLIC_KEY_SCHEMA_FOR_TRANSITION, PublicKeysValidator}; use crate::state_repository::StateRepositoryLike; +use crate::state_transition::apply_state_transition::ApplyStateTransition; use crate::state_transition::{ StateTransition, StateTransitionAction, StateTransitionConvert, StateTransitionFactory, StateTransitionFactoryOptions, @@ -47,6 +48,7 @@ where fee_validator: Arc>, bls: BLS, factory: Arc>, + apply_state_transition: ApplyStateTransition, } impl StateTransitionFacade @@ -163,13 +165,14 @@ where state_transition_basic_validator.clone(), ); - let state_transition_key_signature_validator = { - let asset_lock_transaction_output_fetcher = - AssetLockTransactionOutputFetcher::new(wrapped_state_repository.clone()); + let asset_lock_transaction_output_fetcher = Arc::new( + AssetLockTransactionOutputFetcher::new(wrapped_state_repository.clone()), + ); + let state_transition_key_signature_validator = { let asset_public_key_hash_fetcher = AssetLockPublicKeyHashFetcher::new( wrapped_state_repository.clone(), - asset_lock_transaction_output_fetcher, + asset_lock_transaction_output_fetcher.clone(), ); StateTransitionKeySignatureValidator::new( @@ -184,13 +187,17 @@ where let state_transition_state_validator = StateTransitionStateValidator::new(state_repository); Ok(Self { - state_repository: wrapped_state_repository, + state_repository: wrapped_state_repository.clone(), factory: Arc::new(state_transition_factory), basic_validator: state_transition_basic_validator, key_signature_validator: Arc::new(state_transition_key_signature_validator), fee_validator: Arc::new(state_transition_fee_validator), state_validator: Arc::new(state_transition_state_validator), bls: adapter, + apply_state_transition: ApplyStateTransition::new( + wrapped_state_repository, + asset_lock_transaction_output_fetcher, + ), }) } @@ -361,6 +368,10 @@ where .validate(state_transition, execution_context) .await } + + pub async fn apply(&self, state_transition: &StateTransition) -> Result<(), ProtocolError> { + self.apply_state_transition.apply(state_transition).await + } } pub struct ValidateOptions { diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs index 6321b63bba3..0f1dc228ddc 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs @@ -136,6 +136,7 @@ pub fn convert_to_consensus_signature_error( InvalidIdentityPublicKeyTypeError::new(err.public_key_type()), )), ), + ProtocolError::WrongPublicKeyPurposeError(err) => Ok(err.into()), ProtocolError::Error(_) => Err(error), _ => Ok(ConsensusError::SignatureError( SignatureError::InvalidStateTransitionSignatureError, diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index d5f0697677a..6de52ada7ed 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -177,8 +177,9 @@ mod test { fn setup_test() -> TestData { let state_repository_mock = MockStateRepositoryLike::new(); let shared_state_repository = Arc::new(state_repository_mock); - let asset_lock_transaction_output_fetcher = - AssetLockTransactionOutputFetcher::new(shared_state_repository.clone()); + let asset_lock_transaction_output_fetcher = Arc::new( + AssetLockTransactionOutputFetcher::new(shared_state_repository.clone()), + ); let asset_lock_public_key_hash_fetcher = AssetLockPublicKeyHashFetcher::new( shared_state_repository, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/apply_identity_udpate_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/apply_identity_udpate_transition_spec.rs index 428823d5bc7..a16e43a8ebe 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/apply_identity_udpate_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/apply_identity_udpate_transition_spec.rs @@ -77,7 +77,7 @@ async fn should_add_and_disable_public_keys() { let result = apply_identity_update_transition( &state_repository_mock, - state_transition, + &state_transition, &execution_context, ) .await; @@ -135,7 +135,7 @@ async fn should_add_and_disable_public_keys_on_dry_run() { let result = apply_identity_update_transition( &state_repository_mock, - state_transition, + &state_transition, &execution_context, ) .await; diff --git a/packages/rs-drive-nodejs/package.json b/packages/rs-drive-nodejs/package.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/wallet-lib/package.json b/packages/wallet-lib/package.json index 219490feee5..b3dec403d46 100644 --- a/packages/wallet-lib/package.json +++ b/packages/wallet-lib/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/wallet-lib", - "version": "7.24.0-dev.16", + "version": "7.24.0-dev.17", "description": "Light wallet library for Dash", "main": "src/index.js", "unpkg": "dist/wallet-lib.min.js", diff --git a/packages/wasm-dpp/index.ts b/packages/wasm-dpp/index.ts new file mode 100644 index 00000000000..46ce7b21547 --- /dev/null +++ b/packages/wasm-dpp/index.ts @@ -0,0 +1 @@ +export { default } from './lib/index'; \ No newline at end of file diff --git a/packages/wasm-dpp/karma.conf.js b/packages/wasm-dpp/karma.conf.js index c8f1887aae1..cf2abf0f6a2 100644 --- a/packages/wasm-dpp/karma.conf.js +++ b/packages/wasm-dpp/karma.conf.js @@ -1,3 +1,4 @@ +const webpack = require('webpack'); const karmaMocha = require('karma-mocha'); const karmaMochaReporter = require('karma-mocha-reporter'); const karmaChai = require('karma-chai'); @@ -5,8 +6,6 @@ const karmaChromeLauncher = require('karma-chrome-launcher'); const karmaFirefoxLauncher = require('karma-firefox-launcher'); const karmaWebpack = require('karma-webpack'); -const webpackConfig = require('./webpack.config'); - module.exports = (config) => { config.set({ client: { @@ -24,13 +23,36 @@ module.exports = (config) => { 'lib/test/karma/loader.js': ['webpack'], }, webpack: { + entry: './build/lib/index.js', mode: 'development', optimization: { minimize: false, moduleIds: 'named', }, - plugins: webpackConfig.plugins, - resolve: webpackConfig.resolve, + plugins: [ + new webpack.ProvidePlugin({ + Buffer: [require.resolve('buffer/'), 'Buffer'], + process: require.resolve('process/browser'), + }), + ], + resolve: { + extensions: ['.js'], + fallback: { + fs: false, + ws: false, + crypto: require.resolve('crypto-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + stream: require.resolve('stream-browserify'), + path: require.resolve('path-browserify'), + url: require.resolve('url/'), + util: require.resolve('util/'), + buffer: require.resolve('buffer/'), + events: require.resolve('events/'), + assert: require.resolve('assert/'), + string_decoder: require.resolve('string_decoder/'), + }, + }, }, reporters: ['mocha'], port: 9876, diff --git a/packages/wasm-dpp/lib/dpp.ts b/packages/wasm-dpp/lib/dpp.ts index 8e3fd34920c..6ffb68ae3dc 100644 --- a/packages/wasm-dpp/lib/dpp.ts +++ b/packages/wasm-dpp/lib/dpp.ts @@ -1,5 +1,7 @@ import * as dpp_module from '../wasm/wasm_dpp'; import { patchConsensusErrors } from './errors/patchConsensusErrors'; +import _Identifier from "./identifier/Identifier"; +import _IdentifierError from "./identifier/errors/IdentifierError"; patchConsensusErrors(); @@ -11,6 +13,10 @@ dpp_module.IdentityPublicKey.TYPES = dpp_module.KeyType; dpp_module.IdentityPublicKey.PURPOSES = dpp_module.KeyPurpose; // @ts-ignore dpp_module.IdentityPublicKey.SECURITY_LEVELS = dpp_module.KeySecurityLevel; +// @ts-ignore +dpp_module.Identifier = _Identifier; +// @ts-ignore +dpp_module.IdentifierError = _IdentifierError; export * from '../wasm/wasm_dpp'; export * from './errors/AbstractConsensusError'; @@ -22,3 +28,7 @@ export declare class IdentityPublicKey extends dpp_module.IdentityPublicKey { static PURPOSES: typeof dpp_module.KeyPurpose; static SECURITY_LEVELS: typeof dpp_module.KeySecurityLevel; } + +// TypeScript voodoo to ensure Identifier and IdentifierError are exported +export declare class Identifier extends _Identifier {} +export declare class IdentifierError extends _IdentifierError {} \ No newline at end of file diff --git a/packages/wasm-dpp/lib/identifier/Identifier.ts b/packages/wasm-dpp/lib/identifier/Identifier.ts new file mode 100644 index 00000000000..c77e09176ae --- /dev/null +++ b/packages/wasm-dpp/lib/identifier/Identifier.ts @@ -0,0 +1,122 @@ +import bs58 from 'bs58'; +import IdentifierError from './errors/IdentifierError'; + +// Buffer extending is not a trivial thing: +// * https://github.com/nodejs/node/commit/651a5b51eb838e8e23a5b94ba34e8e06630a004a +// * https://github.com/nodejs/node/issues/4701 +// * https://github.com/nodejs/help/issues/1300 +// * https://github.com/nodejs/node/issues/2882 + +type CborEncoder = { + pushAny: (buffer: Buffer) => void; +} + +type IdentifierEncoding = BufferEncoding | 'base58'; + +/** + * @param {Buffer} buffer + * @returns {Identifier} + * @constructor + */ +export class Identifier { + static MEDIA_TYPE = 'application/x.dash.dpp.identifier'; + + constructor(buffer: Buffer) { + if (!Buffer.isBuffer(buffer)) { + throw new IdentifierError('Identifier expects Buffer'); + } + + if (buffer.length !== 32) { + throw new IdentifierError('Identifier must be 32 long'); + } + + const patchedBuffer = Buffer.from(buffer); + + Object.setPrototypeOf(patchedBuffer, Identifier.prototype); + + // noinspection JSValidateTypes + // @ts-ignore + return patchedBuffer; + } + + /** + * Convert to Buffer + * + * @return {Buffer} + */ + toBuffer(): Buffer { + // @ts-ignore + return Buffer.from(this); + } + + /** + * Encode to CBOR + * + * @param {CborEncoder} encoder + * @return {boolean} + */ + encodeCBOR(encoder: CborEncoder): boolean { + encoder.pushAny(this.toBuffer()); + + return true; + } + + /** + * Convert to JSON + * + * @return {string} + */ + toJSON(): string { + return this.toString(); + } + + /** + * Encode to string + * + * @param {string} [encoding=base58] + * @return {string} + */ + toString(encoding: IdentifierEncoding = 'base58'): string { + if (encoding === 'base58') { + return bs58.encode(this.toBuffer()); + } + + return this.toBuffer().toString(encoding); + } + + /** + * Create Identifier from buffer or encoded string + * + * @param {string|Buffer} value + * @param {string} encoding + * @return {Identifier} + */ + static from(value: string | Buffer, encoding: string = undefined): Identifier { + let buffer; + + if (typeof value === 'string') { + if (encoding === undefined) { + // eslint-disable-next-line no-param-reassign + encoding = 'base58'; + } + + if (encoding === 'base58') { + buffer = bs58.decode(value); + } else { + buffer = Buffer.from(value, 'base64'); + } + } else { + if (encoding !== undefined) { + throw new IdentifierError('encoding accepted only with type string'); + } + + buffer = value; + } + + return new Identifier(buffer); + } +} + +Object.setPrototypeOf(Identifier.prototype, Buffer.prototype); + +export default Identifier; diff --git a/packages/wasm-dpp/lib/identifier/errors/IdentifierError.ts b/packages/wasm-dpp/lib/identifier/errors/IdentifierError.ts new file mode 100644 index 00000000000..08de630d957 --- /dev/null +++ b/packages/wasm-dpp/lib/identifier/errors/IdentifierError.ts @@ -0,0 +1,9 @@ +import {DPPError} from "../../errors/DPPError"; + +class IdentifierError extends DPPError { + constructor(message: string) { + super(message); + } +} + +export default IdentifierError; diff --git a/packages/wasm-dpp/lib/identifier/patchIdentifier.ts b/packages/wasm-dpp/lib/identifier/patchIdentifier.ts deleted file mode 100644 index ca7f166ad5f..00000000000 --- a/packages/wasm-dpp/lib/identifier/patchIdentifier.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as dpp_module from "../dpp"; -// import { inspect } from 'util'; - -export default function (dppModule: typeof dpp_module) { - // As Identifier is now exported from WASM, it can no longer - // patched the same way as JS implementation did. This module - // adds everything that's currently missing from Identifier that can't - // be implemented in Rust directly. - const { Identifier } = dppModule; - - //@ts-ignore - Object.setPrototypeOf(Identifier.prototype, Buffer.prototype); - - Identifier.prototype.valueOf = function () { - return Buffer.from(this.toBytes()); - } - - // @ts-ignore - Identifier.prototype.encodeCBOR = function encodeCBOR(encoder) { - // @ts-ignore - encoder.pushAny(this.valueOf()); - - return true; - }; - - // @ts-ignore - Identifier.prototype.inspect = function (...args) { - return this.valueOf().inspect(...args); - } - - // TODO: THIS MAKES BUFFERS PRINTABLE IN NODE.JS, BUT FOR THIS TO WORK - // target: node has to be specified and utils have to be included __without__ using - // polyfills. This in turn will make web version not work. The code is as follows: - // console.log("custom:", inspect.custom); - // //@ts-ignore - // Identifier.prototype[inspect.custom] = Identifier.prototype.inspect; -} - diff --git a/packages/wasm-dpp/lib/index.ts b/packages/wasm-dpp/lib/index.ts index 396fcf87944..6c35b08fd7d 100644 --- a/packages/wasm-dpp/lib/index.ts +++ b/packages/wasm-dpp/lib/index.ts @@ -2,30 +2,35 @@ import init from '../wasm/wasm_dpp'; import * as dpp_module from './dpp'; // @ts-ignore import wasmBase from '../wasm/wasm_dpp_bg.js'; -import patchIdentifier from "./identifier/patchIdentifier"; let isInitialized = false; +let loadingPromise: Promise | null = null; export default async function loadDpp() { if (isInitialized) { - return dpp_module; - } else { - // @ts-ignore - let bytes = Buffer.from(wasmBase, 'base64'); + return dpp_module + } - if (typeof fetch !== 'undefined') { - let blob = new Blob([bytes], { type: "application/wasm" }); - let wasmUrl = URL.createObjectURL(blob); - await init(wasmUrl); - isInitialized = true; - } else { - dpp_module.initSync(bytes); - isInitialized = true; - } + if (!loadingPromise) { + loadingPromise = loadDppModule() + } - patchIdentifier(dpp_module); + await loadingPromise; + isInitialized = true; + loadingPromise = null; + return dpp_module; +}; - return dpp_module; +const loadDppModule = async () => { + // @ts-ignore + let bytes = Buffer.from(wasmBase, 'base64'); + + if (typeof window !== 'undefined') { + let blob = new Blob([bytes], { type: "application/wasm" }); + let wasmUrl = URL.createObjectURL(blob); + await init(wasmUrl); + } else { + dpp_module.initSync(bytes); } -}; +} diff --git a/packages/wasm-dpp/lib/test/fixtures/getPrivateAndPublicKeyForSigningFixture.js b/packages/wasm-dpp/lib/test/fixtures/getPrivateAndPublicKeyForSigningFixture.js index 1a3f02d51ab..a09c40e6761 100644 --- a/packages/wasm-dpp/lib/test/fixtures/getPrivateAndPublicKeyForSigningFixture.js +++ b/packages/wasm-dpp/lib/test/fixtures/getPrivateAndPublicKeyForSigningFixture.js @@ -9,7 +9,7 @@ module.exports = async function getPrivateAndPublicKeyForSigningFixture(privateK const publicKey = privateKey.toPublicKey(); const rawPublicKey = { - id: 1, + id: 2, type: IdentityPublicKey.TYPES.ECDSA_SECP256K1, data: publicKey.toBuffer(), purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, diff --git a/packages/wasm-dpp/package.json b/packages/wasm-dpp/package.json index 8e7eea69fe6..b3e998f386b 100644 --- a/packages/wasm-dpp/package.json +++ b/packages/wasm-dpp/package.json @@ -1,15 +1,14 @@ { "name": "@dashevo/wasm-dpp", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "The JavaScript implementation of the Dash Platform Protocol", "main": "dist/index.js", "types": "dist/lib/index.d.ts", "scripts": { - "build": "yarn exec scripts/build.sh && webpack", + "build": "yarn exec scripts/build.sh && tsc", "test": "yarn run test:node && yarn run test:browsers", "test:browsers": "karma start ./karma.conf.js --single-run", "test:node": "NODE_ENV=test mocha", - "webpack": "webpack", "lint": "eslint .", "lint:fix": "eslint . --fix", "clean": "yarn exec scripts/clean.sh" @@ -31,6 +30,7 @@ "license": "MIT", "dependencies": { "@dashevo/bls": "~1.2.9", + "bs58": "^4.0.1", "lodash": "^4.17.21", "varint": "^6.0.0" }, @@ -40,10 +40,10 @@ "@dashevo/dpns-contract": "workspace:*", "@dashevo/dpp": "workspace:*", "@dashevo/wasm-re2": "~1.0.2", + "@types/bs58": "^4.0.1", "@types/node": "^14.6.0", "ajv": "^8.6.0", "assert": "^2.0.0", - "bs58": "^4.0.1", "buffer": "^6.0.3", "chai": "^4.3.4", "chai-as-promised": "^7.1.1", @@ -75,7 +75,6 @@ "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "string_decoder": "^1.3.0", - "terser-webpack-plugin": "^5.3.1", "ts-loader": "^8.0.2", "typescript": "^3.9.5", "url": "^0.11.0", diff --git a/packages/wasm-dpp/scripts/build.sh b/packages/wasm-dpp/scripts/build.sh index 8c8400943be..cab572ac793 100755 --- a/packages/wasm-dpp/scripts/build.sh +++ b/packages/wasm-dpp/scripts/build.sh @@ -57,7 +57,7 @@ fi #fi # Converting wasm into base64 so it can be bundled -echo "Converting wasm binary into base64 module for bundling with Webpack" +echo "Converting wasm binary into base64 module for building with TypeScript" WASM_BUILD_BASE_64=$(base64 -i "$OUTPUT_FILE") echo 'module.exports = "'${WASM_BUILD_BASE_64}'"' > "$OUTPUT_FILE_JS" diff --git a/packages/wasm-dpp/src/dash_platform_protocol.rs b/packages/wasm-dpp/src/dash_platform_protocol.rs index 24253c0ae33..c92ace32451 100644 --- a/packages/wasm-dpp/src/dash_platform_protocol.rs +++ b/packages/wasm-dpp/src/dash_platform_protocol.rs @@ -14,6 +14,7 @@ use dpp::identity::validation::PublicKeysValidator; use crate::state_transition_facade::StateTransitionFacadeWasm; use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; +use crate::entropy_generator::ExternalEntropyGenerator; use serde::{Deserialize, Serialize}; #[wasm_bindgen(js_name=DashPlatformProtocol)] @@ -26,6 +27,7 @@ pub struct DashPlatformProtocol { state_repository: ExternalStateRepositoryLike, public_keys_validator: Arc>, bls: BlsAdapter, + entropy_generator: ExternalEntropyGenerator, } #[derive(Serialize, Deserialize)] @@ -40,6 +42,7 @@ impl DashPlatformProtocol { pub fn new( bls_adapter: JsBlsAdapter, state_repository: ExternalStateRepositoryLike, + entropy_generator: ExternalEntropyGenerator, maybe_protocol_version: Option, ) -> Result { let bls = BlsAdapter(bls_adapter); @@ -52,6 +55,7 @@ impl DashPlatformProtocol { protocol_version, state_repository.clone(), bls.clone(), + entropy_generator.clone(), )?; Ok(Self { @@ -63,6 +67,7 @@ impl DashPlatformProtocol { state_repository, public_keys_validator, bls, + entropy_generator, }) } @@ -102,6 +107,7 @@ impl DashPlatformProtocol { protocol_version, self.state_repository.clone(), self.bls.clone(), + self.entropy_generator.clone(), ) } @@ -110,7 +116,12 @@ impl DashPlatformProtocol { &mut self, state_repository: ExternalStateRepositoryLike, ) -> Result<(), JsValue> { - self.init(self.protocol_version, state_repository, self.bls.clone()) + self.init( + self.protocol_version, + state_repository, + self.bls.clone(), + self.entropy_generator.clone(), + ) } #[wasm_bindgen(js_name = getStateRepository)] @@ -123,6 +134,7 @@ impl DashPlatformProtocol { protocol_version: u32, state_repository: ExternalStateRepositoryLike, bls_adapter: BlsAdapter, + entropy_generator: ExternalEntropyGenerator, ) -> Result<(), JsValue> { let (identity_facade, document_facade, data_contract_facade, state_transition_facade) = create_facades( @@ -130,6 +142,7 @@ impl DashPlatformProtocol { protocol_version, state_repository.clone(), bls_adapter, + entropy_generator, )?; self.protocol_version = protocol_version; @@ -148,6 +161,7 @@ fn create_facades( protocol_version: u32, state_repository: ExternalStateRepositoryLike, bls_adapter: BlsAdapter, + entropy_generator: ExternalEntropyGenerator, ) -> Result< ( IdentityFacadeWasm, @@ -172,10 +186,14 @@ fn create_facades( protocol_version, protocol_version_validator.clone(), wrapped_state_repository, + entropy_generator.clone(), ); - let data_contract_facade = - DataContractFacadeWasm::new(protocol_version, protocol_version_validator.clone()); + let data_contract_facade = DataContractFacadeWasm::new( + protocol_version, + protocol_version_validator.clone(), + entropy_generator, + ); let state_transition_facade = StateTransitionFacadeWasm::new(state_repository, bls_adapter, protocol_version_validator)?; @@ -192,12 +210,14 @@ fn init_document_facade( protocol_version: u32, protocol_version_validator: Arc, state_repository: ExternalStateRepositoryLikeWrapper, + entropy_generator: ExternalEntropyGenerator, ) -> DocumentFacadeWasm { let document_validator = DocumentValidatorWasm::new_with_arc(protocol_version_validator); let document_factory = DocumentFactoryWASM::new_with_state_repository_wrapper( protocol_version, document_validator.clone(), + entropy_generator, state_repository.clone(), ); diff --git a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs index d15ab415d07..11227b95e86 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs @@ -8,6 +8,7 @@ use dpp::data_contract::DataContractFacade; use dpp::identifier::Identifier; use dpp::version::ProtocolVersionValidator; +use crate::entropy_generator::ExternalEntropyGenerator; use crate::utils::{get_bool_from_options, WithJsError, SKIP_VALIDATION_PROPERTY_NAME}; use crate::validation::ValidationResultWasm; use dpp::platform_value::Value; @@ -23,8 +24,13 @@ impl DataContractFacadeWasm { pub fn new( protocol_version: u32, protocol_version_validator: Arc, + entropy_generator: ExternalEntropyGenerator, ) -> Self { - let inner = DataContractFacade::new(protocol_version, protocol_version_validator); + let inner = DataContractFacade::new_with_entropy_generator( + protocol_version, + protocol_version_validator, + Box::new(entropy_generator), + ); Self(Arc::new(inner)) } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs index ed26c6742b0..136ba2d115b 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs @@ -1,4 +1,5 @@ use std::ops::Deref; +use std::sync::Arc; use dpp::data_contract::state_transition::data_contract_create_transition::apply_data_contract_create_transition_factory::ApplyDataContractCreateTransition; use wasm_bindgen::prelude::*; @@ -28,7 +29,7 @@ impl ApplyDataContractCreateTransitionWasm { state_repository: ExternalStateRepositoryLike, ) -> ApplyDataContractCreateTransitionWasm { let pinned_js_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); - ApplyDataContractCreateTransition::new(pinned_js_state_repository).into() + ApplyDataContractCreateTransition::new(Arc::new(pinned_js_state_repository)).into() } #[wasm_bindgen(js_name=applyDataContractCreateTransition)] diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 268b931d925..5c0ccebe786 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -6,6 +6,8 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; +use dpp::consensus::signature::SignatureError; +use dpp::consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant; use dpp::{ data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition, platform_value, @@ -156,6 +158,7 @@ impl DataContractCreateTransitionWasm { bls: JsBlsAdapter, ) -> Result<(), JsValue> { let bls_adapter = BlsAdapter(bls); + self.0 .sign( &identity_public_key.to_owned().into(), @@ -164,4 +167,31 @@ impl DataContractCreateTransitionWasm { ) .with_js_error() } + + #[wasm_bindgen(js_name=verifySignature)] + pub fn verify_signature( + &self, + identity_public_key: &IdentityPublicKeyWasm, + bls: JsBlsAdapter, + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() + } } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs index 3981d0c6909..541d1a79edf 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs @@ -1,4 +1,5 @@ use std::ops::Deref; +use std::sync::Arc; use dpp::data_contract::state_transition::data_contract_update_transition::apply_data_contract_update_transition_factory::ApplyDataContractUpdateTransition; use wasm_bindgen::prelude::*; @@ -28,7 +29,7 @@ impl ApplyDataContractUpdateTransitionWasm { state_repository: ExternalStateRepositoryLike, ) -> ApplyDataContractUpdateTransitionWasm { let pinned_js_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); - ApplyDataContractUpdateTransition::new(pinned_js_state_repository).into() + ApplyDataContractUpdateTransition::new(Arc::new(pinned_js_state_repository)).into() } #[wasm_bindgen(js_name=applyDataContractUpdateTransition)] diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 44a4763e15f..28ffb8426a3 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -6,7 +6,10 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; +use dpp::consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant; + use dpp::{ + consensus::signature::SignatureError, data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition, platform_value, state_transition::{ @@ -17,7 +20,11 @@ use dpp::{ use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -use crate::utils::WithJsError; +use crate::{ + bls_adapter::{BlsAdapter, JsBlsAdapter}, + utils::WithJsError, + IdentityPublicKeyWasm, +}; use crate::{ buffer::Buffer, errors::protocol_error::from_protocol_error, identifier::IdentifierWrapper, with_js_error, DataContractParameters, DataContractWasm, StateTransitionExecutionContextWasm, @@ -154,4 +161,31 @@ impl DataContractUpdateTransitionWasm { .serialize(&serde_wasm_bindgen::Serializer::json_compatible()) .map_err(|e| e.into()) } + + #[wasm_bindgen(js_name=verifySignature)] + pub fn verify_signature( + &self, + identity_public_key: &IdentityPublicKeyWasm, + bls: JsBlsAdapter, + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() + } } diff --git a/packages/wasm-dpp/src/data_trigger/data_trigger_execution_context.rs b/packages/wasm-dpp/src/data_trigger/data_trigger_execution_context.rs index 9336e5fd78a..8660ef7b734 100644 --- a/packages/wasm-dpp/src/data_trigger/data_trigger_execution_context.rs +++ b/packages/wasm-dpp/src/data_trigger/data_trigger_execution_context.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use dpp::identifier::Identifier; use dpp::{data_trigger::DataTriggerExecutionContext, state_repository::StateRepositoryLike}; use wasm_bindgen::prelude::*; @@ -82,13 +83,14 @@ impl DataTriggerExecutionContextWasm { pub(crate) fn data_trigger_context_from_wasm<'a, SR>( value: &'a DataTriggerExecutionContextWasm, external_state_repository: &'a SR, + owner_id: &'a Identifier, ) -> DataTriggerExecutionContext<'a, SR> where SR: StateRepositoryLike, { DataTriggerExecutionContext { data_contract: value.data_contract.inner(), - owner_id: value.owner_id.inner(), + owner_id, state_transition_execution_context: value.state_transition_execution_context.inner(), state_repository: external_state_repository, } diff --git a/packages/wasm-dpp/src/data_trigger/execute_data_triggers_factory.rs b/packages/wasm-dpp/src/data_trigger/execute_data_triggers_factory.rs index 4f918fa786f..fa6a6d9377b 100644 --- a/packages/wasm-dpp/src/data_trigger/execute_data_triggers_factory.rs +++ b/packages/wasm-dpp/src/data_trigger/execute_data_triggers_factory.rs @@ -1,4 +1,5 @@ use dpp::document::validation::state::execute_data_triggers::execute_data_triggers_with_custom_list; +use dpp::prelude::Identifier; use dpp::prelude::{DataTrigger, DocumentTransition}; use js_sys::Array; use wasm_bindgen::prelude::*; @@ -25,7 +26,8 @@ pub async fn execute_data_triggers_wasm( ) -> Result { let st_wrapper = ExternalStateRepositoryLikeWrapper::new_with_arc(js_context.state_repository()); - let context = data_trigger_context_from_wasm(&js_context, &st_wrapper); + let identifier: Identifier = js_context.get_owner_id().into(); + let context = data_trigger_context_from_wasm(&js_context, &st_wrapper, &identifier); let document_transitions = js_document_transitions .iter() .map(|v| { diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 724bf1db2c0..e8c86d410bb 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -17,7 +17,7 @@ use crate::document::BinaryType; use crate::errors::RustConversionError; use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; -use crate::utils::{with_serde_to_platform_value, Inner, ToSerdeJSONExt, WithJsError}; +use crate::utils::{with_serde_to_platform_value, ToSerdeJSONExt, WithJsError}; use crate::{with_js_error, ConversionOptions, DocumentWasm}; use crate::{DataContractWasm, MetadataWasm}; @@ -77,7 +77,7 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=setId)] pub fn set_id(&mut self, js_id: IdentifierWrapper) { - self.0.document.id = js_id.into_inner(); + self.0.document.id = js_id.into(); } #[wasm_bindgen(js_name=getType)] @@ -109,7 +109,7 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=setOwnerId)] pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { - self.0.document.owner_id = owner_id.into_inner(); + self.0.document.owner_id = owner_id.into(); } #[wasm_bindgen(js_name=getOwnerId)] @@ -273,7 +273,7 @@ impl ExtendedDocumentWasm { if !options.skip_identifiers_conversion { lodash_set(&js_value, path, buffer.into()); } else { - let id = IdentifierWrapper::new(buffer.into())?; + let id = IdentifierWrapper::new(buffer.into()); lodash_set(&js_value, path, id.into()); } } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 3e94d4fe93b..bd4bf8993a0 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -67,12 +67,14 @@ impl DocumentFactoryWASM { pub(crate) fn new_with_state_repository_wrapper( protocol_version: u32, document_validator: DocumentValidatorWasm, + entropy_generator: ExternalEntropyGenerator, state_repository: ExternalStateRepositoryLikeWrapper, ) -> Self { - let factory = DocumentFactory::new( + let factory = DocumentFactory::new_with_entropy_generator( protocol_version, document_validator.into(), DataContractFetcherAndValidator::new(Arc::new(state_repository)), + Box::new(entropy_generator), ); DocumentFactoryWASM(factory) diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 07f55c36bb5..1f251c229da 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -12,7 +12,7 @@ use crate::buffer::Buffer; use crate::identifier::IdentifierWrapper; use crate::lodash::lodash_set; use crate::utils::{try_to_u64, WithJsError}; -use crate::utils::{with_serde_to_json_value, Inner, ToSerdeJSONExt}; +use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; use crate::with_js_error; use crate::DataContractWasm; @@ -106,12 +106,12 @@ impl DocumentWasm { #[wasm_bindgen(js_name=setId)] pub fn set_id(&mut self, js_id: IdentifierWrapper) { - self.0.id = js_id.into_inner(); + self.0.id = js_id.into(); } #[wasm_bindgen(js_name=setOwnerId)] pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { - self.0.owner_id = owner_id.into_inner(); + self.0.owner_id = owner_id.into(); } #[wasm_bindgen(js_name=getOwnerId)] @@ -254,7 +254,7 @@ impl DocumentWasm { if !options.skip_identifiers_conversion { lodash_set(&js_value, path, buffer.into()); } else { - let id = IdentifierWrapper::new(buffer.into())?; + let id = IdentifierWrapper::new(buffer.into()); lodash_set(&js_value, path, id.into()); } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index 428ac8d7685..48e6f6dc98e 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -311,7 +311,7 @@ pub(crate) fn to_object<'a>( if !options.skip_identifiers_conversion { lodash_set(&js_value, path, buffer.into()); } else { - let id = IdentifierWrapper::new(buffer.into())?; + let id = IdentifierWrapper::new(buffer.into()); lodash_set(&js_value, path, id.into()); } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 5f586880736..8ea0034d0f3 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,5 +1,8 @@ use dpp::identity::KeyID; + use dpp::{ + consensus::signature::SignatureError, + consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant, document::{ document_transition::document_base_transition, state_transition::documents_batch_transition::property_names, DocumentsBatchTransition, @@ -210,7 +213,7 @@ impl DocumentsBatchTransitionWasm { if !options.skip_identifiers_conversion { lodash_set(&js_value, path, buffer.into()); } else { - let id = IdentifierWrapper::new(buffer.into())?; + let id = IdentifierWrapper::new(buffer.into()); lodash_set(&js_value, path, id.into()); } } @@ -296,12 +299,28 @@ impl DocumentsBatchTransitionWasm { #[wasm_bindgen(js_name=verifySignature)] pub fn verify_signature( &self, - public_key: &IdentityPublicKeyWasm, + identity_public_key: &IdentityPublicKeyWasm, bls: JsBlsAdapter, - ) -> Result<(), JsValue> { - self.0 - .verify_signature(public_key.inner(), &BlsAdapter(bls)) - .with_js_error() + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() } #[wasm_bindgen(js_name=setSignaturePublicKey)] diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index 271cf462316..f96670ce427 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -3,13 +3,13 @@ use dpp::document::{ validation::basic::find_duplicates_by_indices::find_duplicates_by_indices, }; use dpp::platform_value::{ReplacementType, Value}; +use dpp::prelude::Identifier; use dpp::ProtocolError; use itertools::Itertools; use js_sys::Array; use wasm_bindgen::prelude::*; use crate::identifier::IdentifierWrapper; -use crate::utils::Inner; use crate::{ document_batch_transition::document_transition::to_object, utils::{ToSerdeJSONExt, WithJsError}, @@ -22,7 +22,8 @@ pub fn find_duplicates_by_indices_wasm( data_contract: &DataContractWasm, owner_id: &IdentifierWrapper, ) -> Result, JsValue> { - let owner_id_value: Value = Value::Identifier(owner_id.inner().to_buffer()); + let identifier: Identifier = owner_id.into(); + let owner_id_value: Value = Value::Identifier(identifier.to_buffer()); let raw_transitions: Vec = js_raw_transitions .iter() .map(|transition| { diff --git a/packages/wasm-dpp/src/entropy_generator.rs b/packages/wasm-dpp/src/entropy_generator.rs index 7e6d18d340c..21101d6b3a0 100644 --- a/packages/wasm-dpp/src/entropy_generator.rs +++ b/packages/wasm-dpp/src/entropy_generator.rs @@ -6,6 +6,7 @@ use wasm_bindgen::JsValue; #[wasm_bindgen] extern "C" { + #[derive(Clone)] pub type ExternalEntropyGenerator; #[wasm_bindgen(catch, structural, method)] diff --git a/packages/wasm-dpp/src/errors/consensus/basic/invalid_signature_public_key_security_level_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/invalid_signature_public_key_security_level_error.rs index 7268ed64944..1509dd99b5d 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/invalid_signature_public_key_security_level_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/invalid_signature_public_key_security_level_error.rs @@ -29,7 +29,7 @@ impl InvalidSignaturePublicKeySecurityLevelErrorWasm { self.public_key_security_level as u8 } - #[wasm_bindgen(js_name=getRequiredKeySecurityLevel)] + #[wasm_bindgen(js_name=getKeySecurityLevelRequirement)] pub fn get_allowed_key_security_levels(&self) -> Vec { self.allowed_key_security_levels .iter() diff --git a/packages/wasm-dpp/src/errors/consensus/basic/public_key_security_level_not_met_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/public_key_security_level_not_met_error.rs index d06d7d848e0..084efda73d2 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/public_key_security_level_not_met_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/public_key_security_level_not_met_error.rs @@ -1,6 +1,8 @@ +use crate::Serialize; use dpp::identity::SecurityLevel; use wasm_bindgen::prelude::*; +#[derive(Serialize)] #[wasm_bindgen(js_name=PublicKeySecurityLevelNotMetError)] pub struct PublicKeySecurityLevelNotMetErrorWasm { public_key_security_level: SecurityLevel, @@ -29,8 +31,8 @@ impl PublicKeySecurityLevelNotMetErrorWasm { self.public_key_security_level as u8 } - #[wasm_bindgen(js_name=getRequiredSecurityLevel)] - pub fn get_required_security_level(&self) -> u8 { + #[wasm_bindgen(js_name=getKeySecurityLevelRequirement)] + pub fn get_key_security_level_requirement(&self) -> u8 { self.required_security_level as u8 } @@ -38,4 +40,14 @@ impl PublicKeySecurityLevelNotMetErrorWasm { pub fn get_code(&self) -> u32 { self.code } + + #[wasm_bindgen(js_name=toString)] + pub fn to_string(&self) -> Result { + let json_string = + serde_json::ser::to_string(self).map_err(|e| JsValue::from(e.to_string()))?; + Ok(JsValue::from(format!( + "PublicKeySecurityLevelNotMetError: {}", + json_string + ))) + } } diff --git a/packages/wasm-dpp/src/errors/from.rs b/packages/wasm-dpp/src/errors/from.rs index d3ccda31b7b..ca14a36cff9 100644 --- a/packages/wasm-dpp/src/errors/from.rs +++ b/packages/wasm-dpp/src/errors/from.rs @@ -6,7 +6,6 @@ use dpp::errors::ProtocolError; use crate::data_contract::errors::from_data_contract_to_js_error; use crate::document::errors::from_document_to_js_error; use crate::errors::value_error::PlatformValueErrorWasm; -use crate::identifier::errors::IdentifierErrorWasm; use super::consensus_error::from_consensus_error; use super::data_contract_not_present_error::DataContractNotPresentNotConsensusErrorWasm; @@ -32,7 +31,6 @@ pub fn from_dpp_err(pe: ProtocolError) -> JsValue { DataContractNotPresentNotConsensusErrorWasm::new(err.data_contract_id()).into() } ProtocolError::ValueError(value_error) => PlatformValueErrorWasm::new(value_error).into(), - ProtocolError::IdentifierError(err) => IdentifierErrorWasm::new(err).into(), _ => JsValue::from_str(&format!("Error conversion not implemented: {pe:#}",)), } } diff --git a/packages/wasm-dpp/src/identifier/errors.rs b/packages/wasm-dpp/src/identifier/errors.rs deleted file mode 100644 index b8a04ded40e..00000000000 --- a/packages/wasm-dpp/src/identifier/errors.rs +++ /dev/null @@ -1,30 +0,0 @@ -use thiserror::Error; -use wasm_bindgen::prelude::*; - -#[derive(Error, Debug)] -#[wasm_bindgen(js_name=IdentifierError)] -#[error("{message}")] -pub struct IdentifierErrorWasm { - message: String, -} - -impl IdentifierErrorWasm { - pub fn new(message: impl Into) -> Self { - Self { - message: message.into(), - } - } -} - -#[wasm_bindgen(js_class=IdentifierError)] -impl IdentifierErrorWasm { - #[wasm_bindgen(js_name=getDataContractId)] - pub fn get_message(&self) -> String { - self.message.clone() - } - - #[wasm_bindgen(js_name=toString)] - pub fn print(&self) -> String { - format!("IdentifierError: {0}", { &self.message }) - } -} diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index e1556b3db84..c9648ecdf4b 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -1,168 +1,44 @@ -pub mod errors; - use dpp::prelude::Identifier; use itertools::Itertools; pub use serde::{Deserialize, Serialize}; use serde_json::Value; use wasm_bindgen::prelude::*; -use wasm_bindgen::JsCast; use crate::bail_js; use crate::buffer::Buffer; -use crate::identifier::errors::IdentifierErrorWasm; -use crate::utils::Inner; use crate::utils::ToSerdeJSONExt; use crate::utils::WithJsError; use dpp::platform_value::string_encoding::Encoding; -use dpp::{identifier, ProtocolError}; - -#[derive(Serialize, Deserialize, PartialEq, Eq)] -enum IdentifierSource { - String(String), - Buffer(Vec), -} +use dpp::ProtocolError; -#[wasm_bindgen] +#[wasm_bindgen(raw_module = "../lib/identifier/Identifier.js")] extern "C" { - fn alert(s: &str); - - #[wasm_bindgen(js_namespace = console, js_name=log)] - fn log(a: &str); -} - -#[derive(Clone, Debug)] -#[wasm_bindgen(js_name=Identifier, inspectable)] -pub struct IdentifierWrapper { - wrapped: identifier::Identifier, -} + #[derive(Debug, Clone)] + #[wasm_bindgen(js_name = default)] + pub type IdentifierWrapper; // Rename to IdentifierJS? -impl std::convert::From for IdentifierWrapper { - fn from(s: identifier::Identifier) -> Self { - IdentifierWrapper { wrapped: s } - } -} + #[wasm_bindgen(constructor, js_class=default)] + pub fn new(buffer: JsValue) -> IdentifierWrapper; -impl std::convert::From<[u8; 32]> for IdentifierWrapper { - fn from(s: [u8; 32]) -> Self { - IdentifierWrapper { - wrapped: Identifier::new(s), - } - } + #[wasm_bindgen(method, js_name=toBuffer)] + pub fn to_buffer(this: &IdentifierWrapper) -> Vec; } -impl std::convert::From<&IdentifierWrapper> for identifier::Identifier { - fn from(s: &IdentifierWrapper) -> Self { - s.wrapped +impl From for IdentifierWrapper { + fn from(s: Identifier) -> Self { + IdentifierWrapper::new(Buffer::from_bytes(s.as_slice()).into()) } } -impl std::convert::From for Identifier { +impl From for Identifier { fn from(s: IdentifierWrapper) -> Self { - s.wrapped - } -} - -#[wasm_bindgen(js_class=Identifier)] -impl IdentifierWrapper { - #[wasm_bindgen(constructor)] - pub fn new(js_value: JsValue) -> Result { - // Can be possible reworked with Buffer::is_buffer(&js_value) - // but until we use Buffer shim for both Node and Web, - // it will return false negative in Node.JS environment - if !js_value.has_type::() { - return Err(IdentifierErrorWasm::new("Identifier expects Buffer").into()); - } - - let vec = js_value.dyn_into::()?.to_vec(); - - let identifier = Identifier::from_bytes(&vec) - .map_err(ProtocolError::ValueError) - .with_js_error()?; - - Ok(IdentifierWrapper { - wrapped: identifier, - }) - } - - pub fn from(value: JsValue, encoding: Option) -> Result { - if value.is_string() { - let string = value.as_string().unwrap(); - Ok(IdentifierWrapper::from_string(string, encoding)) - } else if value.has_type::() && encoding.is_none() { - IdentifierWrapper::new(value) - } else if value.has_type::() && encoding.is_some() { - Err(IdentifierErrorWasm::new("encoding accepted only with type string").into()) - } else { - Err(IdentifierErrorWasm::new("Identifier.from received an unexpected value").into()) - } - } - - #[wasm_bindgen(js_name=fromString)] - pub fn from_string(value: String, encoding: Option) -> IdentifierWrapper { - // TODO: remove unwrap - let identifier = identifier::Identifier::from_string_with_encoding_string( - &value[..], - encoding.as_deref(), - ) - .unwrap(); - - IdentifierWrapper { - wrapped: identifier, - } - } - - #[wasm_bindgen(js_name=toBuffer)] - pub fn to_buffer(&self) -> Buffer { - Buffer::from_bytes_owned(self.wrapped.to_vec()) - } - - #[wasm_bindgen(js_name=toJSON)] - pub fn to_json(&self) -> String { - self.to_string(None) - } - - #[wasm_bindgen(js_name=toString)] - pub fn to_string(&self, encoding: Option) -> String { - // Converting string to a string slice. Rust interfaces work - // with immutable string slices more often, while js interop accepts mutable String. - // as_deref dereferences value in the Option - // dereferencing is accessing the underlying value of the reference, which in - // case of the string would be a string slice - self.wrapped - .to_string_with_encoding_string(encoding.as_deref()) - } - - #[wasm_bindgen(getter)] - pub fn length(&self) -> usize { - self.wrapped.to_buffer().len() - } - - #[wasm_bindgen(js_name=toBytes)] - pub fn to_bytes(&self) -> Vec { - self.wrapped.to_vec() - } - - #[wasm_bindgen(js_name=clone)] - pub fn deep_clone(&self) -> IdentifierWrapper { - IdentifierWrapper { - wrapped: self.wrapped, - } + Identifier::from_bytes(&s.to_buffer()).unwrap() } } -impl Inner for IdentifierWrapper { - type InnerItem = Identifier; - - fn into_inner(self) -> Identifier { - self.wrapped - } - - fn inner(&self) -> &Identifier { - &self.wrapped - } - - fn inner_mut(&mut self) -> &mut Identifier { - &mut self.wrapped +impl From<&IdentifierWrapper> for Identifier { + fn from(s: &IdentifierWrapper) -> Self { + Identifier::from_bytes(&s.to_buffer()).unwrap() } } diff --git a/packages/wasm-dpp/src/identity/identity_facade.rs b/packages/wasm-dpp/src/identity/identity_facade.rs index d0f44847420..91b63f437f5 100644 --- a/packages/wasm-dpp/src/identity/identity_facade.rs +++ b/packages/wasm-dpp/src/identity/identity_facade.rs @@ -116,8 +116,8 @@ impl IdentityFacadeWasm { } #[wasm_bindgen] - pub fn validate(&self, identity: IdentityWasm) -> Result { - let identity: Identity = identity.into(); + pub fn validate(&self, identity: &IdentityWasm) -> Result { + let identity: Identity = identity.to_owned().into(); let identity_json = identity.to_cleaned_object().with_js_error()?; let validation_result = self diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index e34af93ec89..1230c689ebb 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -20,6 +20,7 @@ use crate::MetadataWasm; use crate::{utils, with_js_error}; pub use identity_public_key::*; +use crate::buffer::Buffer; pub use state_transition::*; pub mod errors; @@ -185,13 +186,9 @@ impl IdentityWasm { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_object = with_js_error!(value.serialize(&serializer))?; - let id: IdentifierWrapper = self.0.id.into(); + let id = Buffer::from_bytes(self.0.id.as_slice()); - js_sys::Reflect::set( - &js_object, - &"id".to_owned().into(), - &JsValue::from(id.to_buffer()), - )?; + js_sys::Reflect::set(&js_object, &"id".to_owned().into(), &id)?; js_sys::Reflect::set( &js_object, diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index c312b95e12b..812dbb70b0c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -258,7 +258,7 @@ pub async fn fetch_asset_lock_public_key_hash( AssetLockTransactionOutputFetcher::new(state_repository_wrapper.clone()); let public_key_hash_fetcher = - AssetLockPublicKeyHashFetcher::new(state_repository_wrapper, tx_output_fetcher); + AssetLockPublicKeyHashFetcher::new(state_repository_wrapper, Arc::new(tx_output_fetcher)); let fetch_result = public_key_hash_fetcher .fetch_public_key_hash(asset_lock_proof, execution_context.into()) diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 27cb9e3e844..d8293cfe876 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -26,7 +26,6 @@ use crate::utils::{generic_of_js_val, ToSerdeJSONExt, WithJsError}; use dpp::platform_value::string_encoding::Encoding; use dpp::platform_value::{string_encoding, BinaryData}; use dpp::{ - identifier::Identifier, identity::state_transition::{ asset_lock_proof::AssetLockProof, identity_create_transition::IdentityCreateTransition, identity_public_key_transitions::IdentityPublicKeyInCreationWithWitness, @@ -299,12 +298,10 @@ impl IdentityCreateTransitionWasm { } #[wasm_bindgen(js_name=getModifiedDataIds)] - pub fn get_modified_data_ids(&self) -> Vec { + pub fn get_modified_data_ids(&self) -> Vec { let ids = self.0.get_modified_data_ids(); - ids.into_iter() - .map(|id| >::from(id).into()) - .collect() + ids.into_iter().map(IdentifierWrapper::from).collect() } #[wasm_bindgen(js_name=isDataContractStateTransition)] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs index 4afbc53745d..a74dc45bbe6 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/apply_identity_update_transition.rs @@ -16,7 +16,7 @@ pub async fn apply_identity_update_transition_wasm( apply_identity_update_transition( &wrapped_state_repository, - state_transition.to_owned().into(), + &state_transition.to_owned().into(), &execution_context.to_owned().into(), ) .await diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index d9bdb0d0360..2c75eba4bc0 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -1,6 +1,7 @@ use std::convert::TryInto; use std::default::Default; +use dpp::consensus::signature::SignatureError; use serde::{Deserialize, Serialize}; use wasm_bindgen::__rt::Ref; use wasm_bindgen::prelude::*; @@ -18,6 +19,9 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; use crate::utils::{generic_of_js_val, WithJsError}; + +use dpp::consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant; + use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyInCreationWithWitness; use dpp::identity::{KeyID, TimestampMillis}; use dpp::platform_value::string_encoding::Encoding; @@ -473,4 +477,31 @@ impl IdentityUpdateTransitionWasm { ) .with_js_error() } + + #[wasm_bindgen(js_name=verifySignature)] + pub fn verify_signature( + &self, + identity_public_key: &IdentityPublicKeyWasm, + bls: JsBlsAdapter, + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() + } } diff --git a/packages/wasm-dpp/src/state_transition/conversion.rs b/packages/wasm-dpp/src/state_transition/conversion.rs index 8ad03a49e51..87cb3ff8a50 100644 --- a/packages/wasm-dpp/src/state_transition/conversion.rs +++ b/packages/wasm-dpp/src/state_transition/conversion.rs @@ -3,16 +3,50 @@ use crate::utils::generic_of_js_val; use crate::{ DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, DocumentsBatchTransitionWasm, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, - IdentityUpdateTransitionWasm, + IdentityUpdateTransitionWasm, PreCalculatedOperationWasm, ReadOperationWasm, + SignatureVerificationOperationWasm, }; use dpp::consensus::basic::state_transition::InvalidStateTransitionTypeError; use dpp::consensus::basic::BasicError; use dpp::consensus::ConsensusError; +use dpp::state_transition::fee::operations::Operation; use dpp::state_transition::{StateTransition, StateTransitionType}; use std::convert::TryInto; use wasm_bindgen::__rt::Ref; use wasm_bindgen::{JsCast, JsError, JsValue}; +pub fn create_operation_from_wasm_instance(js_value: &JsValue) -> Result { + let maybe_signature_verification_operation: Result< + Ref, + JsValue, + > = generic_of_js_val::( + js_value, + "SignatureVerificationOperation", + ); + + if let Ok(operation) = maybe_signature_verification_operation { + return Ok(Operation::SignatureVerification( + operation.to_owned().into(), + )); + } + + let maybe_read_operation: Result, JsValue> = + generic_of_js_val::(js_value, "ReadOperation"); + + if let Ok(operation) = maybe_read_operation { + return Ok(Operation::Read(operation.to_owned().into())); + } + + let maybe_precalculated_operation: Result, JsValue> = + generic_of_js_val::(js_value, "PreCalculatedOperation"); + + if let Ok(operation) = maybe_precalculated_operation { + return Ok(Operation::PreCalculated(operation.to_owned().into())); + } + + Err(JsError::new("Unknown operation").into()) +} + pub fn create_state_transition_from_wasm_instance( js_value: &JsValue, ) -> Result { diff --git a/packages/wasm-dpp/src/state_transition/fee/mod.rs b/packages/wasm-dpp/src/state_transition/fee/mod.rs index 7f787f119d6..c87ea551280 100644 --- a/packages/wasm-dpp/src/state_transition/fee/mod.rs +++ b/packages/wasm-dpp/src/state_transition/fee/mod.rs @@ -9,6 +9,8 @@ mod fee_result; mod operations; mod refunds; +pub use operations::*; + #[wasm_bindgen(js_name=Operation)] #[derive(Clone)] pub struct OperationWasm(Operation); diff --git a/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs b/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs index 59bce03f0af..0ba6380d95d 100644 --- a/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs +++ b/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs @@ -21,6 +21,12 @@ impl From for PreCalculatedOperationWasm { } } +impl From for PreCalculatedOperation { + fn from(value: PreCalculatedOperationWasm) -> Self { + value.0 + } +} + #[wasm_bindgen(js_class=PreCalculatedOperation)] impl PreCalculatedOperationWasm { #[wasm_bindgen(constructor)] diff --git a/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs b/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs index 6971d484b0a..abb657d07cd 100644 --- a/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs +++ b/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs @@ -17,6 +17,12 @@ impl From for ReadOperationWasm { } } +impl From for ReadOperation { + fn from(value: ReadOperationWasm) -> Self { + value.0 + } +} + #[wasm_bindgen(js_class=ReadOperation)] impl ReadOperationWasm { #[wasm_bindgen(constructor)] diff --git a/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs b/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs index b09d6005000..ffa27dc4723 100644 --- a/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs +++ b/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs @@ -23,6 +23,12 @@ impl From for SignatureVerificationOperationWasm } } +impl From for SignatureVerificationOperation { + fn from(value: SignatureVerificationOperationWasm) -> Self { + value.0 + } +} + #[wasm_bindgen(js_class=SignatureVerificationOperation)] impl SignatureVerificationOperationWasm { #[wasm_bindgen(constructor)] diff --git a/packages/wasm-dpp/src/state_transition/fee/refunds.rs b/packages/wasm-dpp/src/state_transition/fee/refunds.rs index a54bcb46dbd..10cbd37b5cd 100644 --- a/packages/wasm-dpp/src/state_transition/fee/refunds.rs +++ b/packages/wasm-dpp/src/state_transition/fee/refunds.rs @@ -51,9 +51,9 @@ impl Inner for RefundsWasm { } pub fn convert_hashmap_to_jsmap(map: &HashMap) -> js_sys::Map { - let mut js_map = js_sys::Map::new(); + let js_map = js_sys::Map::new(); for (key, value) in map { - js_map.set(&JsValue::from_str(&key), &BigInt::from(*value)); + js_map.set(&JsValue::from_str(key), &BigInt::from(*value)); } js_map } diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 2916d16696f..1dc022b9d63 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -1,5 +1,6 @@ use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use dpp::state_transition::fee::operations::Operation; use wasm_bindgen::prelude::*; pub mod errors; @@ -8,7 +9,9 @@ pub mod state_transition_factory; pub mod fee; pub mod validation; +use crate::state_transition::conversion::create_operation_from_wasm_instance; use crate::utils::Inner; +pub use fee::*; pub use validation::*; pub(crate) mod conversion; @@ -69,6 +72,30 @@ impl StateTransitionExecutionContextWasm { pub fn disable_dry_run(&self) { self.0.disable_dry_run(); } + + #[wasm_bindgen(js_name=addOperation)] + pub fn add_operation(&self, operation: JsValue) -> Result<(), JsValue> { + let operation = create_operation_from_wasm_instance(&operation)?; + self.0.add_operation(operation); + Ok(()) + } + + #[wasm_bindgen(js_name=getOperations)] + pub fn get_operation(&self) -> Vec { + let operations = self.0.get_operations(); + operations + .iter() + .map(|operation| match operation { + Operation::PreCalculated(operation) => { + PreCalculatedOperationWasm::from(operation.to_owned()).into() + } + Operation::Read(operation) => ReadOperationWasm::from(operation.to_owned()).into(), + Operation::SignatureVerification(operation) => { + SignatureVerificationOperationWasm::from(operation.to_owned()).into() + } + }) + .collect() + } } impl Inner for StateTransitionExecutionContextWasm { diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index a65b543c3b5..8ac041e16db 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -12,6 +12,7 @@ use dpp::state_transition::{ use dpp::version::ProtocolVersionValidator; use serde::Deserialize; +use crate::errors::protocol_error::from_protocol_error; use std::sync::Arc; use wasm_bindgen::prelude::*; use wasm_bindgen::JsValue; @@ -217,6 +218,20 @@ impl StateTransitionFacadeWasm { Ok(validation_result.map(|_| JsValue::undefined()).into()) } + + #[wasm_bindgen] + pub async fn apply(&self, state_transition_js: JsValue) -> Result { + let state_transition = + super::super::conversion::create_state_transition_from_wasm_instance( + &state_transition_js, + )?; + + self.0 + .apply(&state_transition) + .await + .map(|_| JsValue::undefined()) + .map_err(from_protocol_error) + } } #[derive(Deserialize, Default)] diff --git a/packages/wasm-dpp/src/state_transition/validation/mod.rs b/packages/wasm-dpp/src/state_transition/validation/mod.rs index 5d88fff9cb9..63594754391 100644 --- a/packages/wasm-dpp/src/state_transition/validation/mod.rs +++ b/packages/wasm-dpp/src/state_transition/validation/mod.rs @@ -1 +1,2 @@ +pub mod validate_state_transition_identity_signature; pub mod validate_state_transition_key_signature; diff --git a/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs b/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs new file mode 100644 index 00000000000..ad9367e6a7b --- /dev/null +++ b/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs @@ -0,0 +1,87 @@ +use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; +use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; +use crate::utils::WithJsError; +use crate::validation::ValidationResultWasm; + +use crate::errors::consensus_error::from_consensus_error; +use dpp::consensus::basic::state_transition::InvalidStateTransitionTypeError; +use dpp::consensus::basic::BasicError; +use dpp::consensus::ConsensusError; +use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use dpp::state_transition::validation::validate_state_transition_identity_signature::validate_state_transition_identity_signature; +use dpp::state_transition::{StateTransition, StateTransitionIdentitySigned}; +use std::sync::Arc; +use wasm_bindgen::prelude::wasm_bindgen; +use wasm_bindgen::JsValue; + +struct StValidator { + bls: BlsAdapter, + state_repository: Arc, +} + +impl StValidator { + pub async fn validate( + &self, + state_transition: &mut impl StateTransitionIdentitySigned, + ) -> Result { + let result = validate_state_transition_identity_signature( + self.state_repository.clone(), + state_transition, + &self.bls, + &StateTransitionExecutionContext::default(), // TODO(v0.24-merge): is it fine using default context here? + ) + .await + .with_js_error()?; + Ok(ValidationResultWasm::from( + result.map(|_v| JsValue::undefined()), + )) + } +} + +#[wasm_bindgen(js_name=validateStateTransitionIdentitySignature)] +pub async fn validate_state_transition_identity_signature_wasm( + external_state_repository: ExternalStateRepositoryLike, + js_state_transition: &JsValue, + bls_adapter: JsBlsAdapter, +) -> Result { + let bls = BlsAdapter(bls_adapter); + let state_repository = Arc::new(ExternalStateRepositoryLikeWrapper::new( + external_state_repository, + )); + + let validator = StValidator { + bls, + state_repository, + }; + + let state_transition = + super::super::conversion::create_state_transition_from_wasm_instance(js_state_transition)?; + + match state_transition { + StateTransition::DataContractCreate(mut state_transition) => { + validator.validate(&mut state_transition).await + } + StateTransition::DataContractUpdate(mut state_transition) => { + validator.validate(&mut state_transition).await + } + StateTransition::DocumentsBatch(mut state_transition) => { + validator.validate(&mut state_transition).await + } + StateTransition::IdentityCreate(state_transition) => Err(from_consensus_error( + ConsensusError::BasicError(Box::new(BasicError::InvalidStateTransitionTypeError( + InvalidStateTransitionTypeError::new(state_transition.transition_type as u8), + ))), + )), + StateTransition::IdentityTopUp(state_transition) => Err(from_consensus_error( + ConsensusError::BasicError(Box::new(BasicError::InvalidStateTransitionTypeError( + InvalidStateTransitionTypeError::new(state_transition.transition_type as u8), + ))), + )), + StateTransition::IdentityCreditWithdrawal(mut state_transition) => { + validator.validate(&mut state_transition).await + } + StateTransition::IdentityUpdate(mut state_transition) => { + validator.validate(&mut state_transition).await + } + } +} diff --git a/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index e295ac7e7d0..bf0179a912d 100644 --- a/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -36,8 +36,10 @@ impl StateTransitionKeySignatureValidatorWasm { let tx_output_fetcher = AssetLockTransactionOutputFetcher::new(state_repository_wrapper.clone()); - let public_key_hash_fetcher = - AssetLockPublicKeyHashFetcher::new(state_repository_wrapper.clone(), tx_output_fetcher); + let public_key_hash_fetcher = AssetLockPublicKeyHashFetcher::new( + state_repository_wrapper.clone(), + Arc::new(tx_output_fetcher), + ); StateTransitionKeySignatureValidator::new(state_repository_wrapper, public_key_hash_fetcher) .into() diff --git a/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js b/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js index ac0a4d484d0..8124b8c688f 100644 --- a/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js @@ -1,4 +1,5 @@ const getDataContractJSFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); +const crypto = require('crypto'); const getBlsAdapterMock = require('../../../lib/test/mocks/getBlsAdapterMock'); const { default: loadWasmDpp } = require('../../..'); @@ -24,7 +25,9 @@ describe('DataContractFacade', () => { beforeEach(async () => { blsAdapter = await getBlsAdapterMock(); - dpp = new DashPlatformProtocol(1, blsAdapter); + dpp = new DashPlatformProtocol( + blsAdapter, {}, { generate: () => crypto.randomBytes(32) }, 1, + ); dataContractJs = await getDataContractJSFixture(); rawDataContract = dataContractJs.toObject(); diff --git a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js index 860f8c20f29..a330bef2fd4 100644 --- a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js +++ b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js @@ -1,3 +1,4 @@ +const crypto = require('crypto'); const generateRandomIdentifier = require('@dashevo/dpp/lib/test/utils/generateRandomIdentifier'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); @@ -45,7 +46,12 @@ describe('DocumentFacade', () => { stateRepositoryMock.fetchDataContract.resolves(dataContract); blsAdapter = await getBlsAdapterMock(); - dpp = new DashPlatformProtocol(blsAdapter, stateRepositoryMock, 1); + dpp = new DashPlatformProtocol( + blsAdapter, + stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, + 1, + ); documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { diff --git a/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js b/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js index 2b873a88062..734b8f7bb60 100644 --- a/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js +++ b/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js @@ -1,3 +1,4 @@ +const crypto = require('crypto'); const getIdentityFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityFixture'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); @@ -43,7 +44,12 @@ describe('IdentityFacade', () => { height: 42, }); - dpp = new DashPlatformProtocol(getBlsAdapterMock(), stateRepositoryMock, 1); + dpp = new DashPlatformProtocol( + getBlsAdapterMock(), + stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, + 1, + ); const chainAssetLockProofJS = getChainAssetLockProofFixture(); const instantAssetLockProofJS = getInstantAssetLockProofFixture(); diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 5b8017c2031..8e08caa7e0d 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -1,4 +1,5 @@ const { PrivateKey } = require('@dashevo/dashcore-lib'); +const crypto = require('crypto'); const getIdentityCreateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityCreateTransitionFixture'); @@ -113,7 +114,12 @@ describe('StateTransitionFacade', () => { const blsAdapter = await getBlsAdapterMock(); - dpp = new DashPlatformProtocol(blsAdapter, stateRepositoryMock, 1); + dpp = new DashPlatformProtocol( + blsAdapter, + stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, + 1, + ); }); describe('createFromObject', () => { diff --git a/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js b/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js index 4e84d029075..05e88638cdc 100644 --- a/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js +++ b/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js @@ -1,3 +1,4 @@ +const crypto = require('crypto'); const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); const createStateRepositoryMock = require('../../lib/test/mocks/createStateRepositoryMock'); @@ -16,6 +17,7 @@ describe('DashPlatformProtocol', () => { dpp = new DashPlatformProtocol( getBlsAdapterMock(), stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, protocolVersion.latestVersion, ); }); diff --git a/packages/wasm-dpp/test/unit/Identifier.spec.js b/packages/wasm-dpp/test/unit/Identifier.spec.js index 0013fb812c0..1e5cdb50fdd 100644 --- a/packages/wasm-dpp/test/unit/Identifier.spec.js +++ b/packages/wasm-dpp/test/unit/Identifier.spec.js @@ -1,6 +1,6 @@ const crypto = require('crypto'); const bs58 = require('bs58'); -let { Identifier, IdentifierError, PlatformValueError } = require('../..'); +let { Identifier, IdentifierError } = require('../..'); const { default: loadWasmDpp } = require('../..'); describe('Identifier', () => { @@ -9,7 +9,7 @@ describe('Identifier', () => { beforeEach(async () => { buffer = crypto.randomBytes(32); - ({ Identifier, IdentifierError, PlatformValueError } = await loadWasmDpp()); + ({ Identifier, IdentifierError } = await loadWasmDpp()); }); describe('#constructor', () => { @@ -39,8 +39,8 @@ describe('Identifier', () => { expect.fail('Expected to throw error'); } catch (e) { - expect(e).to.be.instanceOf(PlatformValueError); - expect(e.getMessage()).to.equal('byte length not 32 bytes error: Identifier must be 32 bytes long'); + expect(e).to.be.instanceOf(IdentifierError); + expect(e.toString()).to.equal('IdentifierError: Identifier must be 32 long'); } }); }); diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index 2356a795354..c366066d243 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -7,7 +7,6 @@ const DocumentCreateTransition = require( const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); const createDPPMock = require('@dashevo/dpp/lib/test/mocks/createDPPMock'); const generateRandomIdentifier = require('@dashevo/dpp/lib/test/utils/generateRandomIdentifier'); -const lodash = require('lodash'); const generateRandomIdentifierAsync = require('../../../lib/test/utils/generateRandomIdentifierAsync'); const { default: loadWasmDpp } = require('../../../dist'); @@ -36,7 +35,7 @@ describe('Document', () => { const now = new Date().getTime(); const id = await generateRandomIdentifierAsync(); - const jsId = new JsIdentifier(Buffer.from(id.toBuffer())); + const jsId = new JsIdentifier(id.toBuffer()); const ownerId = await generateRandomIdentifierAsync(); const jsOwnerId = new JsIdentifier(Buffer.from(ownerId.toBuffer())); @@ -77,7 +76,7 @@ describe('Document', () => { }, }; - dataContract = dataContractFactory.create(ownerId.clone(), rawDataContract); + dataContract = dataContractFactory.create(ownerId, rawDataContract); dataContractJs = jsDataContractFactory.create(jsOwnerId, rawDataContract); rawDocument = { @@ -103,7 +102,7 @@ describe('Document', () => { }; document = new ExtendedDocument(rawDocument, dataContract); - rawDocumentJs = lodash.cloneDeepWith(rawDocument); + rawDocumentJs = { ...rawDocument }; rawDocumentJs.$id = jsId; rawDocumentJs.$ownerId = jsOwnerId; @@ -307,7 +306,7 @@ describe('Document', () => { it('should return ID', async () => { const id = await generateRandomIdentifierAsync(); - document.setId(id.clone()); + document.setId(id); const actualId = document.getId(); diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionExecutionContext.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionExecutionContext.spec.js new file mode 100644 index 00000000000..7975bd4690c --- /dev/null +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionExecutionContext.spec.js @@ -0,0 +1,52 @@ +const { expect } = require('chai'); +const { default: loadWasmDpp } = require('../../../dist'); + +describe('StateTransitionExecutionContext', () => { + let ReadOperation; + let PreCalculatedOperation; + let SignatureVerificationOperation; + let StateTransitionExecutionContext; + + let executionContext; + + before(async () => { + ({ + ReadOperation, + PreCalculatedOperation, + SignatureVerificationOperation, + StateTransitionExecutionContext, + } = await loadWasmDpp()); + }); + + beforeEach(() => { + executionContext = new StateTransitionExecutionContext(); + }); + + describe('should add operation', () => { + it('should add ReadOperation', () => { + executionContext.addOperation(new ReadOperation(100)); + const operations = executionContext.getOperations(); + expect(operations[0]).to.be.instanceOf(ReadOperation); + }); + + it('should add SignatureVerificationOperation', () => { + executionContext.addOperation(new SignatureVerificationOperation(0)); + const operations = executionContext.getOperations(); + expect(operations[0]).to.be.instanceOf(SignatureVerificationOperation); + }); + + it('should add PreCalculatedOperation', () => { + executionContext.addOperation(new PreCalculatedOperation(1, 1, [])); + const operations = executionContext.getOperations(); + expect(operations[0]).to.be.instanceOf(PreCalculatedOperation); + }); + + it('should throw Error for unknown operation', () => { + try { + executionContext.addOperation({}); + } catch (e) { + expect(e.message).to.equal('Unknown operation'); + } + }); + }); +}); diff --git a/packages/wasm-dpp/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js index 24d583a10dc..6ea8d48c3ea 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js @@ -1,28 +1,28 @@ -const validateStateTransitionSignatureFactory = require('@dashevo/dpp/lib/stateTransition/validation/validateStateTransitionIdentitySignatureFactory'); -const ValidationResult = require('@dashevo/dpp/lib/validation/ValidationResult'); -const IdentityPublicKey = require('@dashevo/dpp/lib/identity/IdentityPublicKey'); -const InvalidStateTransitionSignatureError = require('@dashevo/dpp/lib/errors/consensus/signature/InvalidStateTransitionSignatureError'); -const MissingPublicKeyError = require('@dashevo/dpp/lib/errors/consensus/signature/MissingPublicKeyError'); -const generateRandomIdentifier = require('@dashevo/dpp/lib/test/utils/generateRandomIdentifier'); - -const { expectValidationError } = require('@dashevo/dpp/lib/test/expect/expectError'); -const stateTransitionTypes = require('@dashevo/dpp/lib/stateTransition/stateTransitionTypes'); -const StateTransitionExecutionContext = require('@dashevo/dpp/lib/stateTransition/StateTransitionExecutionContext'); -const PublicKeyIsDisabledConsensusError = require('@dashevo/dpp/lib/errors/consensus/signature/PublicKeyIsDisabledError'); -const WrongPublicKeyPurposeConsensusError = require('@dashevo/dpp/lib/errors/consensus/signature/WrongPublicKeyPurposeError'); -const PublicKeySecurityLevelNotMetConsensusError = require('@dashevo/dpp/lib/errors/consensus/signature/PublicKeySecurityLevelNotMetError'); -const InvalidSignaturePublicKeySecurityLevelConsensusError = require('@dashevo/dpp/lib/errors/consensus/signature/InvalidSignaturePublicKeySecurityLevelError'); -const InvalidIdentityPublicKeyTypeConsensusError = require('@dashevo/dpp/lib/errors/consensus/signature/InvalidIdentityPublicKeyTypeError'); -const InvalidSignaturePublicKeySecurityLevelError = require('@dashevo/dpp/lib/stateTransition/errors/InvalidSignaturePublicKeySecurityLevelError'); -const PublicKeySecurityLevelNotMetError = require('@dashevo/dpp/lib/stateTransition/errors/PublicKeySecurityLevelNotMetError'); -const WrongPublicKeyPurposeError = require('@dashevo/dpp/lib/stateTransition/errors/WrongPublicKeyPurposeError'); -const PublicKeyIsDisabledError = require('@dashevo/dpp/lib/stateTransition/errors/PublicKeyIsDisabledError'); -const DPPError = require('@dashevo/dpp/lib/errors/DPPError'); -const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); -const IdentityNotFoundError = require('@dashevo/dpp/lib/errors/consensus/signature/IdentityNotFoundError'); +const { expectValidationError } = require('../../../../lib/test/expect/expectError'); +const getDataContractFixture = require('../../../../lib/test/fixtures/getDataContractFixture'); +const getIdentityFixture = require('../../../../lib/test/fixtures/getIdentityFixture'); +const getPrivateAndPublicKeyForSigningFixture = require('../../../../lib/test/fixtures/getPrivateAndPublicKeyForSigningFixture'); + +const { default: loadWasmDpp } = require('../../../..'); +let { + DashPlatformProtocol, + validateStateTransitionIdentitySignature: validate, + ValidationResult, + StateTransitionExecutionContext, + IdentityNotFoundError, + MissingPublicKeyError, + InvalidIdentityPublicKeyTypeError, + InvalidStateTransitionSignatureError, + InvalidSignaturePublicKeySecurityLevelError, + PublicKeySecurityLevelNotMetError, + WrongPublicKeyPurposeError, + PublicKeyIsDisabledError, + IdentityPublicKey, +} = require('../../../..'); +const getBlsMock = require('../../../../lib/test/mocks/getBlsAdapterMock'); +const createStateRepositoryMock = require('../../../../lib/test/mocks/createStateRepositoryMock'); describe('validateStateTransitionIdentitySignatureFactory', () => { - let validateStateTransitionIdentitySignature; let stateTransition; let ownerId; let identity; @@ -30,40 +30,52 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { let publicKeyId; let executionContext; let stateRepositoryMock; + let dpp; + let validateStateTransitionIdentitySignature; + let privateKey; + + beforeEach(async function beforeEach() { + ({ + DashPlatformProtocol, + ValidationResult, + validateStateTransitionIdentitySignature: validate, + StateTransitionExecutionContext, + IdentityNotFoundError, + MissingPublicKeyError, + InvalidIdentityPublicKeyTypeError, + InvalidStateTransitionSignatureError, + InvalidSignaturePublicKeySecurityLevelError, + PublicKeySecurityLevelNotMetError, + WrongPublicKeyPurposeError, + PublicKeyIsDisabledError, + IdentityPublicKey, + } = await loadWasmDpp()); + stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); + stateRepositoryMock.fetchDataContract.resolves(); + const blsMock = getBlsMock(); + + dpp = new DashPlatformProtocol(blsMock, stateRepositoryMock); - beforeEach(function beforeEach() { executionContext = new StateTransitionExecutionContext(); - ownerId = generateRandomIdentifier(); - publicKeyId = 1; - stateTransition = { - verifySignature: this.sinonSandbox.stub().returns(true), - getSignaturePublicKeyId: this.sinonSandbox.stub().returns(publicKeyId), - getSignature: this.sinonSandbox.stub(), - getOwnerId: this.sinonSandbox.stub().returns(ownerId), - getType: this.sinonSandbox.stub().returns(stateTransitionTypes.IDENTITY_CREATE), - getExecutionContext: this.sinonSandbox.stub().returns(executionContext), - }; - - identityPublicKey = { - getType: this.sinonSandbox.stub().returns(IdentityPublicKey.TYPES.ECDSA_SECP256K1), - getSecurityLevel: this.sinonSandbox.stub(), - getId: this.sinonSandbox.stub().returns(publicKeyId), - }; - - const getPublicKeyById = this.sinonSandbox.stub().returns(identityPublicKey); - - identity = { - getPublicKeyById, - getId: this.sinonSandbox.stub().returns(ownerId), - }; + publicKeyId = 2; + + identity = await getIdentityFixture(); + ownerId = identity.getId(); + const dataContract = await getDataContractFixture(identity.getId()); + + stateTransition = await dpp.dataContract.createDataContractCreateTransition(dataContract); + + ({ privateKey, identityPublicKey } = await getPrivateAndPublicKeyForSigningFixture()); + identity.addPublicKey(identityPublicKey); + + stateTransition.sign(identity.getPublicKeyById(2), privateKey, getBlsMock()); + stateTransition.setExecutionContext(executionContext); stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); stateRepositoryMock.fetchIdentity.resolves(identity); - validateStateTransitionIdentitySignature = validateStateTransitionSignatureFactory( - stateRepositoryMock, - ); + validateStateTransitionIdentitySignature = (st) => validate(stateRepositoryMock, st, blsMock); }); it('should pass properly signed state transition', async () => { @@ -77,48 +89,43 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(result.getErrors()).to.be.an('array'); expect(result.getErrors()).to.be.empty(); - expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly( - ownerId, - new StateTransitionExecutionContext(), + // For this validator we always use default execution context, + // as there's no dry run + expect(stateRepositoryMock.fetchIdentity).to.be.calledOnce(); + expect( + stateRepositoryMock.fetchIdentity.getCall(0).args[0].toBuffer(), + ).to.be.deep.equal( + ownerId.toBuffer(), ); - expect(identity.getPublicKeyById).to.be.calledOnceWithExactly(publicKeyId); - expect(identityPublicKey.getType).to.be.calledTwice(); - expect(stateTransition.getSignaturePublicKeyId).to.be.calledOnce(); - expect(stateTransition.verifySignature).to.be.calledOnceWithExactly(identityPublicKey); - expect(stateTransition.getOwnerId).to.be.calledOnceWithExactly(); }); it('should return invalid result if owner id doesn\'t exist', async () => { - stateRepositoryMock.fetchIdentity.resolves(null); + stateRepositoryMock.fetchIdentity.resolves(undefined); const result = await validateStateTransitionIdentitySignature( stateTransition, ); - expectValidationError(result); + await expectValidationError(result); const [error] = result.getErrors(); expect(error).to.be.an.instanceOf(IdentityNotFoundError); expect(error.getCode()).to.equal(2000); - expect(Buffer.isBuffer(error.getIdentityId())).to.be.true(); expect(error.getIdentityId()).to.deep.equal(identity.getId().toBuffer()); - expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly( - ownerId, - new StateTransitionExecutionContext(), + expect(stateRepositoryMock.fetchIdentity).to.be.calledOnce(); + expect( + stateRepositoryMock.fetchIdentity.getCall(0).args[0].toBuffer(), + ).to.be.deep.equal( + ownerId.toBuffer(), ); - expect(identity.getPublicKeyById).to.not.be.called(); - expect(identityPublicKey.getType).to.not.be.called(); - expect(stateTransition.getSignaturePublicKeyId).to.not.be.called(); - expect(stateTransition.verifySignature).to.not.be.called(); - expect(stateTransition.getOwnerId).to.be.calledOnceWithExactly(); }); it("should return MissingPublicKeyError if the identity doesn't have a matching public key", async () => { - const type = IdentityPublicKey.TYPES.ECDSA_SECP256K1 + 1; - identityPublicKey.getType.returns(type); - identity.getPublicKeyById.returns(undefined); + const { identityPublicKey: publicKey } = await getPrivateAndPublicKeyForSigningFixture(); + publicKey.setId(99); + identity.setPublicKeys([publicKey]); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -126,13 +133,12 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(result).to.be.instanceOf(ValidationResult); expect(result.isValid()).to.be.false(); - expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly( - ownerId, - new StateTransitionExecutionContext(), + expect(stateRepositoryMock.fetchIdentity).to.be.calledOnce(); + expect( + stateRepositoryMock.fetchIdentity.getCall(0).args[0].toBuffer(), + ).to.be.deep.equal( + ownerId.toBuffer(), ); - expect(identity.getPublicKeyById).to.be.calledOnceWithExactly(publicKeyId); - expect(stateTransition.getSignaturePublicKeyId).to.be.calledTwice(); - expect(stateTransition.verifySignature).to.not.be.called(); expect(result.getErrors()).to.be.an('array'); expect(result.getErrors()).to.have.lengthOf(1); @@ -143,9 +149,14 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(error.getPublicKeyId()).to.equal(publicKeyId); }); - it('should return InvalidIdentityPublicKeyTypeError if type is not exist', async () => { - const type = Math.max(...Object.values(IdentityPublicKey.TYPES)) + 1; - identityPublicKey.getType.returns(type); + it('should return InvalidIdentityPublicKeyTypeError if type does not exist', async () => { + // It is physically impossible to create an identity with the type out + // of allowed type range, since rust implementation uses enum, and it's + // impossible to create an enum from an invalid key type + const type = IdentityPublicKey.TYPES.BIP13_SCRIPT_HASH; + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setType(type); + identity.setPublicKeys(publicKeys); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -153,26 +164,26 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(result).to.be.instanceOf(ValidationResult); expect(result.isValid()).to.be.false(); - expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly( - ownerId, - new StateTransitionExecutionContext(), + expect(stateRepositoryMock.fetchIdentity).to.be.calledOnce(); + expect( + stateRepositoryMock.fetchIdentity.getCall(0).args[0].toBuffer(), + ).to.be.deep.equal( + ownerId.toBuffer(), ); - expect(identity.getPublicKeyById).to.be.calledOnceWithExactly(publicKeyId); - expect(identityPublicKey.getType).to.be.calledTwice(); - expect(stateTransition.getSignaturePublicKeyId).to.be.calledOnce(); - expect(stateTransition.verifySignature).to.not.be.called(); expect(result.getErrors()).to.be.an('array'); expect(result.getErrors()).to.have.lengthOf(1); const [error] = result.getErrors(); - expect(error).to.be.instanceOf(InvalidIdentityPublicKeyTypeConsensusError); + expect(error).to.be.instanceOf(InvalidIdentityPublicKeyTypeError); expect(error.getPublicKeyType()).to.equal(type); }); it('should return InvalidStateTransitionSignatureError if signature is invalid', async () => { - stateTransition.verifySignature.resolves(false); + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setData(Buffer.from('00'.repeat(32), 'hex')); + identity.setPublicKeys(publicKeys); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -188,21 +199,19 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(error).to.be.instanceOf(InvalidStateTransitionSignatureError); - expect(stateRepositoryMock.fetchIdentity).to.be.calledOnceWithExactly( - ownerId, - new StateTransitionExecutionContext(), + expect(stateRepositoryMock.fetchIdentity).to.be.calledOnce(); + expect( + stateRepositoryMock.fetchIdentity.getCall(0).args[0].toBuffer(), + ).to.be.deep.equal( + ownerId.toBuffer(), ); - expect(identity.getPublicKeyById).to.be.calledOnceWithExactly(publicKeyId); - expect(identityPublicKey.getType).to.be.calledTwice(); - expect(stateTransition.getSignaturePublicKeyId).to.be.calledOnce(); - expect(stateTransition.verifySignature).to.be.calledOnceWithExactly(identityPublicKey); }); describe('Consensus errors', () => { it('should return InvalidSignaturePublicKeySecurityLevelConsensusError if InvalidSignaturePublicKeySecurityLevelError was thrown', async () => { - const e = new InvalidSignaturePublicKeySecurityLevelError(1, 0); - - stateTransition.verifySignature.throws(e); + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.MASTER); + identity.setPublicKeys(publicKeys); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -215,15 +224,16 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(result.getErrors()).to.have.lengthOf(1); const [error] = result.getErrors(); - expect(error).to.be.instanceOf(InvalidSignaturePublicKeySecurityLevelConsensusError); - expect(error.getPublicKeySecurityLevel()).to.equal(1); - expect(error.getKeySecurityLevelRequirement()).to.equal(0); + + expect(error).to.be.instanceOf(InvalidSignaturePublicKeySecurityLevelError); + expect(error.getPublicKeySecurityLevel()).to.equal(IdentityPublicKey.SECURITY_LEVELS.MASTER); + expect(error.getKeySecurityLevelRequirement()).to.equal(2); }); it('should return PublicKeySecurityLevelNotMetConsensusError if PublicKeySecurityLevelNotMetError was thrown', async () => { - const e = new PublicKeySecurityLevelNotMetError(1, 2); - - stateTransition.verifySignature.throws(e); + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.MEDIUM); + identity.setPublicKeys(publicKeys); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -236,15 +246,15 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(result.getErrors()).to.have.lengthOf(1); const [error] = result.getErrors(); - expect(error).to.be.instanceOf(PublicKeySecurityLevelNotMetConsensusError); - expect(error.getPublicKeySecurityLevel()).to.equal(1); + expect(error).to.be.instanceOf(PublicKeySecurityLevelNotMetError); + expect(error.getPublicKeySecurityLevel()).to.equal(3); expect(error.getKeySecurityLevelRequirement()).to.equal(2); }); it('should return WrongPublicKeyPurposeConsensusError if WrongPublicKeyPurposeError was thrown', async () => { - const e = new WrongPublicKeyPurposeError(4, 2); - - stateTransition.verifySignature.throws(e); + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setPurpose(IdentityPublicKey.PURPOSES.ENCRYPTION); + identity.setPublicKeys(publicKeys); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -257,16 +267,16 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(result.getErrors()).to.have.lengthOf(1); const [error] = result.getErrors(); - expect(error).to.be.instanceOf(WrongPublicKeyPurposeConsensusError); + expect(error).to.be.instanceOf(WrongPublicKeyPurposeError); - expect(error.getPublicKeyPurpose()).to.equal(4); - expect(error.getKeyPurposeRequirement()).to.equal(2); + expect(error.getPublicKeyPurpose()).to.equal(IdentityPublicKey.PURPOSES.ENCRYPTION); + expect(error.getKeyPurposeRequirement()).to.equal(IdentityPublicKey.PURPOSES.AUTHENTICATION); }); it('should return PublicKeyIsDisabledConsensusError if PublicKeyIsDisabledError was thrown', async () => { - const e = new PublicKeyIsDisabledError(identityPublicKey); - - stateTransition.verifySignature.throws(e); + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setDisabledAt(Date.now()); + identity.setPublicKeys(publicKeys); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -279,14 +289,14 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(result.getErrors()).to.have.lengthOf(1); const [error] = result.getErrors(); - expect(error).to.be.instanceOf(PublicKeyIsDisabledConsensusError); + expect(error).to.be.instanceOf(PublicKeyIsDisabledError); expect(error.getPublicKeyId()).to.deep.equal(publicKeyId); }); it('should return InvalidStateTransitionSignatureError if DPPError was thrown', async () => { - const e = new DPPError('Dpp error'); - - stateTransition.verifySignature.throws(e); + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setData(Buffer.from('00'.repeat(32), 'hex')); + identity.setPublicKeys(publicKeys); const result = await validateStateTransitionIdentitySignature( stateTransition, @@ -302,26 +312,11 @@ describe('validateStateTransitionIdentitySignatureFactory', () => { expect(error).to.be.instanceOf(InvalidStateTransitionSignatureError); }); - it('should throw unknown error', async () => { - const e = new Error('unknown error'); - - stateTransition.verifySignature.throws(e); - - try { - await validateStateTransitionIdentitySignature( - stateTransition, - ); - - expect.fail('should throw an error'); - } catch (error) { - expect(error).to.equal(e); - } - }); - it('should not verify signature on dry run', async () => { - const e = new DPPError('Dpp error'); - - stateTransition.verifySignature.throws(e); + // This will produce an error during signature validation + const publicKeys = identity.getPublicKeys(); + publicKeys[2].setDisabledAt(Date.now()); + identity.setPublicKeys(publicKeys); executionContext.enableDryRun(); diff --git a/packages/wasm-dpp/tsconfig.json b/packages/wasm-dpp/tsconfig.json index 17eeea3831b..e948a245bd1 100644 --- a/packages/wasm-dpp/tsconfig.json +++ b/packages/wasm-dpp/tsconfig.json @@ -1,18 +1,17 @@ { "compilerOptions": { - "outDir": "./dist/", + "outDir": "./dist", "noImplicitAny": true, - "module": "es6", - "target": "es5", + "module": "commonjs", + "target": "es2015", "allowJs": true, "moduleResolution": "node", + "esModuleInterop": true, "declaration": true, "lib": [ "es2015", "dom" ] }, - "include": [ - "lib/**/*.ts", "wasm/wasm_dpp.js" - ], + "include": ["index.ts", "lib/**/*.ts", "wasm/wasm_dpp.js"], } \ No newline at end of file diff --git a/packages/wasm-dpp/webpack.config.js b/packages/wasm-dpp/webpack.config.js deleted file mode 100644 index 3f6e278d4a1..00000000000 --- a/packages/wasm-dpp/webpack.config.js +++ /dev/null @@ -1,61 +0,0 @@ -const path = require('path'); -const webpack = require('webpack'); -const TerserPlugin = require('terser-webpack-plugin'); - -module.exports = { - entry: './lib/index.ts', - output: { - path: path.resolve(__dirname, 'dist'), - filename: 'index.js', - library: { - type: 'umd', - }, - publicPath: '', - // This is needed to prevent ReferenceError: self is not defined, - // as webpack names global object "self" for some reason - globalObject: 'this', - }, - mode: 'production', - optimization: { - minimize: true, - minimizer: [new TerserPlugin({ - terserOptions: { - keep_classnames: true, - }, - })], - }, - module: { - rules: [ - { - test: /\.tsx?$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - fallback: { - fs: false, - ws: false, - crypto: require.resolve('crypto-browserify'), - http: require.resolve('stream-http'), - https: require.resolve('https-browserify'), - stream: require.resolve('stream-browserify'), - path: require.resolve('path-browserify'), - url: require.resolve('url/'), - util: require.resolve('util/'), - buffer: require.resolve('buffer/'), - events: require.resolve('events/'), - assert: require.resolve('assert/'), - string_decoder: require.resolve('string_decoder/'), - }, - }, - plugins: [ - new webpack.ProvidePlugin({ - Buffer: [require.resolve('buffer/'), 'Buffer'], - process: require.resolve('process/browser'), - }), - ], - // target: 'node' -}; diff --git a/packages/withdrawals-contract/package.json b/packages/withdrawals-contract/package.json index c87afbb5f96..db99137e814 100644 --- a/packages/withdrawals-contract/package.json +++ b/packages/withdrawals-contract/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/withdrawals-contract", - "version": "0.24.0-dev.16", + "version": "0.24.0-dev.17", "description": "Data Contract to manipulate and track withdrawals", "scripts": { "build": "", diff --git a/yarn.lock b/yarn.lock index 5a245765a17..09d29c4d1e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1869,6 +1869,7 @@ __metadata: "@dashevo/dpns-contract": "workspace:*" "@dashevo/dpp": "workspace:*" "@dashevo/wasm-re2": ~1.0.2 + "@types/bs58": ^4.0.1 "@types/node": ^14.6.0 ajv: ^8.6.0 assert: ^2.0.0 @@ -1904,7 +1905,6 @@ __metadata: stream-browserify: ^3.0.0 stream-http: ^3.2.0 string_decoder: ^1.3.0 - terser-webpack-plugin: ^5.3.1 ts-loader: ^8.0.2 typescript: ^3.9.5 url: ^0.11.0 @@ -2785,6 +2785,15 @@ __metadata: languageName: node linkType: hard +"@types/bs58@npm:^4.0.1": + version: 4.0.1 + resolution: "@types/bs58@npm:4.0.1" + dependencies: + base-x: ^3.0.6 + checksum: 5063fed6bb3816f28eef3e689a05f8f85d03ce7c2e3ceefe77c349ed147023999eb024e863bf3fa81ba2bded690e5296efe4d34864c875097bd261614e37f786 + languageName: node + linkType: hard + "@types/cacheable-request@npm:^6.0.1": version: 6.0.3 resolution: "@types/cacheable-request@npm:6.0.3" @@ -4137,7 +4146,7 @@ __metadata: languageName: node linkType: hard -"base-x@npm:^3.0.2": +"base-x@npm:^3.0.2, base-x@npm:^3.0.6": version: 3.0.9 resolution: "base-x@npm:3.0.9" dependencies: