From a99793424815e5b43eb67f7422cb42459636d7af Mon Sep 17 00:00:00 2001 From: stringhandler Date: Mon, 4 Jul 2022 10:09:50 +0200 Subject: [PATCH] feat: add tari engine for flow and wasm functions (#4237) A prototype and stub for a potential WASM and flow engine for DAN layer smart contracts. Not fully functional, but wanted to get the code in. Most of the work is moving the StateDb and Instructions into the engine crate. The idea is that the `engine` crate can be referenced by template creators as a `dev_dependency` in their projects so that they can run tests without all the HotStuff consensus code. --- .../workflows/dan_layer_integration_tests.yml | 2 +- Cargo.lock | 966 +++++++++++++++--- Cargo.toml | 5 +- applications/tari_validator_node/Cargo.toml | 1 + .../src/contract_worker_manager.rs | 3 + .../src/grpc/services/wallet_client.rs | 3 +- .../src/grpc/validator_node_grpc_server.rs | 2 +- .../src/p2p/proto/conversions.rs | 42 +- .../src/p2p/rpc/service_impl.rs | 6 +- .../src/p2p/services/rpc_client.rs | 4 +- dan_layer/common_types/src/lib.rs | 4 + dan_layer/common_types/src/storage/mod.rs | 6 + .../src/storage/unit_of_work_tracker.rs | 47 + dan_layer/common_types/src/template_id.rs | 70 ++ dan_layer/core/Cargo.toml | 4 +- dan_layer/core/src/digital_assets_error.rs | 3 + dan_layer/core/src/models/asset_definition.rs | 34 +- .../core/src/models/hot_stuff_tree_node.rs | 3 +- dan_layer/core/src/models/instruction_set.rs | 3 +- dan_layer/core/src/models/mod.rs | 78 +- dan_layer/core/src/models/op_log.rs | 69 -- dan_layer/core/src/models/state_root.rs | 44 - dan_layer/core/src/models/tari_dan_payload.rs | 3 +- .../core/src/services/asset_processor.rs | 58 +- dan_layer/core/src/services/asset_proxy.rs | 3 +- .../core/src/services/checkpoint_manager.rs | 7 +- .../core/src/services/mempool_service.rs | 6 +- dan_layer/core/src/services/mocks/mod.rs | 25 +- .../core/src/services/payload_processor.rs | 4 +- .../src/services/service_specification.rs | 10 +- .../src/services/validator_node_rpc_client.rs | 4 +- dan_layer/core/src/services/wallet_client.rs | 3 +- .../storage/chain/chain_db_unit_of_work.rs | 5 +- .../core/src/storage/chain/db_instruction.rs | 4 +- dan_layer/core/src/storage/db_factory.rs | 2 +- dan_layer/core/src/storage/error.rs | 6 +- dan_layer/core/src/storage/lmdb/asset_db.rs | 24 - dan_layer/core/src/storage/lmdb/helpers.rs | 46 - .../src/storage/lmdb/lmdb_asset_backend.rs | 74 -- .../core/src/storage/lmdb/lmdb_asset_store.rs | 130 --- dan_layer/core/src/storage/lmdb/mod.rs | 35 - dan_layer/core/src/storage/lmdb/test.rs | 59 -- dan_layer/core/src/storage/mocks/mod.rs | 9 +- dan_layer/core/src/storage/mocks/state_db.rs | 106 -- dan_layer/core/src/storage/mod.rs | 5 - .../core/src/storage/state/db_key_value.rs | 28 - dan_layer/core/src/storage/state/mod.rs | 35 - dan_layer/core/src/storage/state/state_db.rs | 58 -- .../storage/state/state_db_backend_adapter.rs | 66 -- .../core/src/storage/state/state_op_log.rs | 77 -- .../core/src/storage/unit_of_work_tracker.rs | 66 -- dan_layer/core/src/template_command.rs | 4 +- .../core/src/templates/tip002_template.rs | 12 +- .../core/src/templates/tip004_template.rs | 7 +- .../core/src/templates/tip721_template.rs | 7 +- .../core/src/workers/consensus_worker.rs | 2 +- .../core/src/workers/state_sync/error.rs | 4 + dan_layer/core/src/workers/state_sync/mod.rs | 15 +- .../core/src/workers/states/next_view.rs | 3 +- dan_layer/core/src/workers/states/prepare.rs | 3 +- .../core/src/workers/states/synchronizing.rs | 3 +- dan_layer/engine/Cargo.toml | 22 + dan_layer/engine/src/flow/error.rs | 9 + dan_layer/engine/src/flow/flow_factory.rs | 48 + dan_layer/engine/src/flow/flow_instance.rs | 127 +++ dan_layer/engine/src/flow/mod.rs | 33 + .../engine/src/flow/workers/arg_worker.rs | 53 + .../src/flow/workers/create_bucket_worker.rs | 110 ++ .../src/flow/workers/has_role_worker.rs | 42 + .../src/flow/workers/mint_bucket_worker.rs | 61 ++ dan_layer/engine/src/flow/workers/mod.rs | 19 + .../engine/src/flow/workers/sender_worker.rs | 33 + .../engine/src/flow/workers/start_worker.rs | 22 + .../src/flow/workers/store_bucket_worker.rs | 84 ++ .../engine/src/flow/workers/text_worker.rs | 24 + .../flow_function_definition.rs | 13 + .../function_arg_definition.rs | 20 + .../engine/src/function_definitions/mod.rs | 11 + .../wasm_function_definition.rs | 13 + .../src/instructions}/instruction.rs | 26 +- dan_layer/engine/src/instructions/mod.rs | 6 + dan_layer/engine/src/lib.rs | 9 + dan_layer/engine/src/models/bucket.rs | 33 + dan_layer/engine/src/models/mod.rs | 6 + dan_layer/engine/src/state/db_key_value.rs | 9 + dan_layer/engine/src/state/error.rs | 28 + dan_layer/engine/src/state/mocks/mod.rs | 4 + dan_layer/engine/src/state/mocks/state_db.rs | 70 ++ dan_layer/engine/src/state/mod.rs | 22 + .../engine/src/state/models/key_value.rs | 10 + dan_layer/engine/src/state/models/mod.rs | 14 + dan_layer/engine/src/state/models/op_log.rs | 50 + .../engine/src/state/models/schema_state.rs | 23 + .../engine/src/state/models/state_root.rs | 25 + dan_layer/engine/src/state/state_db.rs | 39 + .../src/state/state_db_backend_adapter.rs | 35 + .../src}/state/state_db_unit_of_work.rs | 75 +- dan_layer/engine/src/state/state_op_log.rs | 60 ++ dan_layer/engine/src/wasm/error.rs | 10 + dan_layer/engine/src/wasm/mod.rs | 10 + .../engine/src/wasm/wasm_module_definition.rs | 12 + .../engine/src/wasm/wasm_module_factory.rs | 148 +++ dan_layer/storage_sqlite/Cargo.toml | 4 +- dan_layer/storage_sqlite/src/error.rs | 25 +- .../storage_sqlite/src/models/instruction.rs | 7 +- dan_layer/storage_sqlite/src/models/mod.rs | 1 - .../storage_sqlite/src/models/state_op_log.rs | 14 +- .../storage_sqlite/src/models/state_tree.rs | 38 - .../storage_sqlite/src/sqlite_db_factory.rs | 3 +- .../src/sqlite_state_db_backend_adapter.rs | 76 +- 110 files changed, 2584 insertions(+), 1469 deletions(-) create mode 100644 dan_layer/common_types/src/storage/mod.rs create mode 100644 dan_layer/common_types/src/storage/unit_of_work_tracker.rs create mode 100644 dan_layer/common_types/src/template_id.rs delete mode 100644 dan_layer/core/src/models/op_log.rs delete mode 100644 dan_layer/core/src/models/state_root.rs delete mode 100644 dan_layer/core/src/storage/lmdb/asset_db.rs delete mode 100644 dan_layer/core/src/storage/lmdb/helpers.rs delete mode 100644 dan_layer/core/src/storage/lmdb/lmdb_asset_backend.rs delete mode 100644 dan_layer/core/src/storage/lmdb/lmdb_asset_store.rs delete mode 100644 dan_layer/core/src/storage/lmdb/mod.rs delete mode 100644 dan_layer/core/src/storage/lmdb/test.rs delete mode 100644 dan_layer/core/src/storage/mocks/state_db.rs delete mode 100644 dan_layer/core/src/storage/state/db_key_value.rs delete mode 100644 dan_layer/core/src/storage/state/mod.rs delete mode 100644 dan_layer/core/src/storage/state/state_db.rs delete mode 100644 dan_layer/core/src/storage/state/state_db_backend_adapter.rs delete mode 100644 dan_layer/core/src/storage/state/state_op_log.rs delete mode 100644 dan_layer/core/src/storage/unit_of_work_tracker.rs create mode 100644 dan_layer/engine/Cargo.toml create mode 100644 dan_layer/engine/src/flow/error.rs create mode 100644 dan_layer/engine/src/flow/flow_factory.rs create mode 100644 dan_layer/engine/src/flow/flow_instance.rs create mode 100644 dan_layer/engine/src/flow/mod.rs create mode 100644 dan_layer/engine/src/flow/workers/arg_worker.rs create mode 100644 dan_layer/engine/src/flow/workers/create_bucket_worker.rs create mode 100644 dan_layer/engine/src/flow/workers/has_role_worker.rs create mode 100644 dan_layer/engine/src/flow/workers/mint_bucket_worker.rs create mode 100644 dan_layer/engine/src/flow/workers/mod.rs create mode 100644 dan_layer/engine/src/flow/workers/sender_worker.rs create mode 100644 dan_layer/engine/src/flow/workers/start_worker.rs create mode 100644 dan_layer/engine/src/flow/workers/store_bucket_worker.rs create mode 100644 dan_layer/engine/src/flow/workers/text_worker.rs create mode 100644 dan_layer/engine/src/function_definitions/flow_function_definition.rs create mode 100644 dan_layer/engine/src/function_definitions/function_arg_definition.rs create mode 100644 dan_layer/engine/src/function_definitions/mod.rs create mode 100644 dan_layer/engine/src/function_definitions/wasm_function_definition.rs rename dan_layer/{core/src/models => engine/src/instructions}/instruction.rs (58%) create mode 100644 dan_layer/engine/src/instructions/mod.rs create mode 100644 dan_layer/engine/src/lib.rs create mode 100644 dan_layer/engine/src/models/bucket.rs create mode 100644 dan_layer/engine/src/models/mod.rs create mode 100644 dan_layer/engine/src/state/db_key_value.rs create mode 100644 dan_layer/engine/src/state/error.rs create mode 100644 dan_layer/engine/src/state/mocks/mod.rs create mode 100644 dan_layer/engine/src/state/mocks/state_db.rs create mode 100644 dan_layer/engine/src/state/mod.rs create mode 100644 dan_layer/engine/src/state/models/key_value.rs create mode 100644 dan_layer/engine/src/state/models/mod.rs create mode 100644 dan_layer/engine/src/state/models/op_log.rs create mode 100644 dan_layer/engine/src/state/models/schema_state.rs create mode 100644 dan_layer/engine/src/state/models/state_root.rs create mode 100644 dan_layer/engine/src/state/state_db.rs create mode 100644 dan_layer/engine/src/state/state_db_backend_adapter.rs rename dan_layer/{core/src/storage => engine/src}/state/state_db_unit_of_work.rs (79%) create mode 100644 dan_layer/engine/src/state/state_op_log.rs create mode 100644 dan_layer/engine/src/wasm/error.rs create mode 100644 dan_layer/engine/src/wasm/mod.rs create mode 100644 dan_layer/engine/src/wasm/wasm_module_definition.rs create mode 100644 dan_layer/engine/src/wasm/wasm_module_factory.rs delete mode 100644 dan_layer/storage_sqlite/src/models/state_tree.rs diff --git a/.github/workflows/dan_layer_integration_tests.yml b/.github/workflows/dan_layer_integration_tests.yml index 8c61df48a6..2c121cd221 100644 --- a/.github/workflows/dan_layer_integration_tests.yml +++ b/.github/workflows/dan_layer_integration_tests.yml @@ -7,7 +7,7 @@ on: - reopened - synchronize env: - toolchain: nightly-2021-11-20 + toolchain: nightly-2022-05-01 jobs: dan-layer-integration-tests: diff --git a/Cargo.lock b/Cargo.lock index 2c7e5c4e73..cb2d958ca3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -299,6 +308,21 @@ dependencies = [ "cc", ] +[[package]] +name = "backtrace" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base58-monero" version = "0.3.2" @@ -512,7 +536,7 @@ dependencies = [ "hyper", "hyperlocal", "log", - "pin-project 1.0.10", + "pin-project 1.0.11", "serde", "serde_derive", "serde_json", @@ -602,6 +626,27 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +[[package]] +name = "bytecheck" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a31f923c2db9513e4298b72df143e6e655a759b3d6a0966df18f81223fff54f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb17c862a905d912174daa27ae002326fff56dc8b8ada50a0a5f0976cb174f0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "bytecodec" version = "0.4.15" @@ -616,9 +661,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" +checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a" [[package]] name = "byteorder" @@ -643,9 +688,9 @@ dependencies = [ [[package]] name = "cairo-rs" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62be3562254e90c1c6050a72aa638f6315593e98c5cdaba9017cedbabf0a5dee" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" dependencies = [ "bitflags 1.3.2", "cairo-sys-rs", @@ -727,7 +772,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb" dependencies = [ - "clap 3.2.6", + "clap 3.2.8", "heck 0.4.0", "indexmap", "log", @@ -942,9 +987,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.6" +version = "3.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a" +checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83" dependencies = [ "atty", "bitflags 1.3.2", @@ -959,9 +1004,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.6" +version = "3.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6db9e867166a43a53f7199b5e4d1f522a1e5bd626654be263c999ce59df39a" +checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -972,9 +1017,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] @@ -1146,6 +1191,19 @@ dependencies = [ "memchr", ] +[[package]] +name = "corosensei" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +dependencies = [ + "autocfg 1.1.0", + "cfg-if 1.0.0", + "libc", + "scopeguard", + "windows-sys 0.33.0", +] + [[package]] name = "cpufeatures" version = "0.1.5" @@ -1170,6 +1228,65 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" +[[package]] +name = "cranelift-bforest" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +dependencies = [ + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-entity", + "gimli", + "log", + "regalloc", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" + +[[package]] +name = "cranelift-entity" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" + +[[package]] +name = "cranelift-frontend" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + [[package]] name = "crc24" version = "0.1.6" @@ -1445,9 +1562,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "5999502d32b9c48d492abe66392408144895020ec4709e549e840799f3bb74c0" dependencies = [ "generic-array 0.14.5", "typenum", @@ -1590,6 +1707,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "d3ne" +version = "0.7.4" +source = "git+https://github.com/stringhandler/d3ne-rs.git?branch=st-fixes2#ad2b0dfca267c9466251780aecb78bab139846e5" +dependencies = [ + "anyhow", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "darling" version = "0.10.2" @@ -1679,9 +1807,9 @@ dependencies = [ [[package]] name = "decimal-rs" -version = "0.1.38" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3ab4f7b3df4f77b57f228261f2761db6d9bb0b803d5b9d5dee3d84f9a67439" +checksum = "b2492291a982ad198a2c3b84b091b48348372ffe8a9f7194cc90a2d8b901762c" dependencies = [ "ethnum", "fast-float", @@ -1936,9 +2064,9 @@ dependencies = [ [[package]] name = "either" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" [[package]] name = "embed-resource" @@ -1986,6 +2114,47 @@ dependencies = [ "syn", ] +[[package]] +name = "enum-iterator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "enumset" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4799cdb24d48f1f8a7a98d06b7fde65a85a2d1e42b25a889f5406aa1fbefe074" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea83a3fbdc1d999ccfbcbee717eab36f8edf2d71693a23ce0d7cca19e085304c" +dependencies = [ + "darling 0.13.4", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -2055,6 +2224,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + [[package]] name = "fast-float" version = "0.2.0" @@ -2078,7 +2253,7 @@ checksum = "e11dcc7e4d79a8c89b9ab4c6f5c30b1fc4a83c420792da3542fd31179ed5f517" dependencies = [ "cfg-if 1.0.0", "rustix", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -2093,14 +2268,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" +checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall 0.2.13", - "winapi 0.3.9", + "windows-sys 0.36.1", ] [[package]] @@ -2123,9 +2298,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "fixedbitset" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" @@ -2332,7 +2507,7 @@ dependencies = [ "futures-sink", "futures-task", "futures-util", - "pin-project 1.0.10", + "pin-project 1.0.11", "pin-utils", ] @@ -2512,11 +2687,22 @@ dependencies = [ "polyval 0.5.3", ] +[[package]] +name = "gimli" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + [[package]] name = "gio" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f132be35e05d9662b9fa0fee3f349c6621f7782e0105917f4cc73c1bf47eceb" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" dependencies = [ "bitflags 1.3.2", "futures-channel", @@ -2559,9 +2745,9 @@ dependencies = [ [[package]] name = "glib" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124026a2fa8c33a3d17a3fe59c103f2d9fa5bd92c19e029e037736729abeab" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" dependencies = [ "bitflags 1.3.2", "futures-channel", @@ -2712,6 +2898,15 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.12.1" @@ -2919,7 +3114,7 @@ dependencies = [ "futures-util", "hex", "hyper", - "pin-project 1.0.10", + "pin-project 1.0.11", "tokio 1.19.2", ] @@ -3014,7 +3209,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg 1.1.0", - "hashbrown", + "hashbrown 0.12.1", + "serde", ] [[package]] @@ -3261,6 +3457,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + [[package]] name = "libc" version = "0.2.126" @@ -3396,6 +3598,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "line-wrap" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" +dependencies = [ + "safemem", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3493,7 +3704,28 @@ dependencies = [ "serde", "serde_json", "tracing", - "tracing-subscriber 0.3.11", + "tracing-subscriber 0.3.14", +] + +[[package]] +name = "loupe" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" +dependencies = [ + "indexmap", + "loupe-derive", + "rustversion", +] + +[[package]] +name = "loupe-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" +dependencies = [ + "quote", + "syn", ] [[package]] @@ -3515,6 +3747,15 @@ dependencies = [ "time 0.3.11", ] +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -3585,6 +3826,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memmap2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.6.5" @@ -3699,7 +3949,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -3740,6 +3990,12 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "more-asserts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" + [[package]] name = "multiaddr" version = "0.14.0" @@ -4125,6 +4381,18 @@ dependencies = [ "objc", ] +[[package]] +name = "object" +version = "0.28.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +dependencies = [ + "crc32fast", + "hashbrown 0.11.2", + "indexmap", + "memchr", +] + [[package]] name = "once_cell" version = "1.12.0" @@ -4156,7 +4424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "360bcc8316bf6363aa3954c3ccc4de8add167b087e0259190a043c9514f910fe" dependencies = [ "pathdiff", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -4214,7 +4482,7 @@ dependencies = [ "js-sys", "lazy_static", "percent-encoding 2.1.0", - "pin-project 1.0.10", + "pin-project 1.0.11", "rand 0.8.5", "thiserror", "tokio 1.19.2", @@ -4288,7 +4556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" dependencies = [ "dlv-list", - "hashbrown", + "hashbrown 0.12.1", ] [[package]] @@ -4428,7 +4696,7 @@ dependencies = [ "libc", "redox_syscall 0.2.13", "smallvec", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -4557,7 +4825,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" dependencies = [ - "fixedbitset 0.4.1", + "fixedbitset 0.4.2", "indexmap", ] @@ -4709,27 +4977,27 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909" +checksum = "3ef0f924a5ee7ea9cbcea77529dba45f8a9ba9f622419fe3386ca581a3ae9d5a" dependencies = [ - "pin-project-internal 0.4.29", + "pin-project-internal 0.4.30", ] [[package]] name = "pin-project" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260" dependencies = [ - "pin-project-internal 1.0.10", + "pin-project-internal 1.0.11", ] [[package]] name = "pin-project-internal" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a" +checksum = "851c8d0ce9bebe43790dedfc86614c23494ac9f423dd618d3a61fc693eafe61e" dependencies = [ "proc-macro2", "quote", @@ -4738,9 +5006,9 @@ dependencies = [ [[package]] name = "pin-project-internal" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" dependencies = [ "proc-macro2", "quote", @@ -4795,6 +5063,20 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "plist" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225" +dependencies = [ + "base64 0.13.0", + "indexmap", + "line-wrap", + "serde", + "time 0.3.11", + "xml-rs", +] + [[package]] name = "plotters" version = "0.3.1" @@ -5016,6 +5298,26 @@ version = "2.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96" +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "qrcode" version = "0.12.0" @@ -5260,6 +5562,17 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regalloc" +version = "0.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +dependencies = [ + "log", + "rustc-hash", + "smallvec", +] + [[package]] name = "regex" version = "1.5.6" @@ -5286,6 +5599,18 @@ version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +[[package]] +name = "region" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach", + "winapi 0.3.9", +] + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -5295,6 +5620,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "rend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.11.11" @@ -5383,6 +5717,31 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "rkyv" +version = "0.7.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +dependencies = [ + "bytecheck", + "hashbrown 0.12.1", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ron" version = "0.7.1" @@ -5434,6 +5793,12 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -5461,21 +5826,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.10", + "semver 1.0.12", ] [[package]] name = "rustix" -version = "0.35.6" +version = "0.35.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef258c11e17f5c01979a10543a30a4e12faef6aab217a74266e747eefa3aed88" +checksum = "d51cc38aa10f6bbb377ed28197aa052aa4e2b762c22be9d3153d01822587e787" dependencies = [ "bitflags 1.3.2", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -5567,7 +5932,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -5601,6 +5966,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "security-framework" version = "2.6.1" @@ -5655,9 +6026,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" +checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" dependencies = [ "serde", ] @@ -5673,9 +6044,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.137" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47" dependencies = [ "serde_derive", ] @@ -5699,6 +6070,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_bytes" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" +dependencies = [ + "serde", +] + [[package]] name = "serde_cbor" version = "0.11.2" @@ -5711,9 +6091,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c" dependencies = [ "proc-macro2", "quote", @@ -5722,9 +6102,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa 1.0.2", "ryu", @@ -5985,9 +6365,9 @@ checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "smallvec" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "snow" @@ -6269,9 +6649,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bfe4c782f0543f667ee3b732d026b2f1c64af39cd52e726dec1ea1f2d8f6b80" +checksum = "a71c32c2fa7bba46b01becf9cf470f6a781573af7e376c5e317a313ecce27545" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -6306,7 +6686,6 @@ dependencies = [ "raw-window-handle", "scopeguard", "serde", - "tao-core-video-sys", "unicode-segmentation", "uuid 0.8.2", "windows 0.37.0", @@ -6314,18 +6693,6 @@ dependencies = [ "x11-dl", ] -[[package]] -name = "tao-core-video-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" -dependencies = [ - "cfg-if 1.0.0", - "core-foundation-sys", - "libc", - "objc", -] - [[package]] name = "tar" version = "0.4.38" @@ -6337,6 +6704,12 @@ dependencies = [ "xattr", ] +[[package]] +name = "target-lexicon" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" + [[package]] name = "tari_app_grpc" version = "0.33.0" @@ -6359,7 +6732,7 @@ dependencies = [ name = "tari_app_utilities" version = "0.33.0" dependencies = [ - "clap 3.2.6", + "clap 3.2.8", "config", "dirs-next 1.0.2", "futures 0.3.21", @@ -6386,7 +6759,7 @@ dependencies = [ "async-trait", "bincode", "chrono", - "clap 3.2.6", + "clap 3.2.8", "config", "crossterm 0.23.2", "derive_more", @@ -6475,7 +6848,7 @@ name = "tari_collectibles" version = "0.1.0" dependencies = [ "blake2 0.9.2", - "clap 3.2.6", + "clap 3.2.8", "derivative", "diesel", "diesel_migrations", @@ -6577,7 +6950,7 @@ dependencies = [ "multiaddr", "nom 5.1.2", "once_cell", - "pin-project 1.0.10", + "pin-project 1.0.11", "prost", "prost-types", "rand 0.8.5", @@ -6626,7 +6999,7 @@ dependencies = [ "log", "log-mdc", "petgraph 0.5.1", - "pin-project 0.4.29", + "pin-project 0.4.30", "prost", "prost-types", "rand 0.8.5", @@ -6670,7 +7043,7 @@ version = "0.33.0" dependencies = [ "bitflags 1.3.2", "chrono", - "clap 3.2.6", + "clap 3.2.8", "config", "crossterm 0.17.7", "digest 0.9.0", @@ -6817,15 +7190,13 @@ dependencies = [ "anyhow", "async-trait", "blake2 0.9.2", - "bytecodec", - "clap 3.2.6", + "clap 3.2.8", "digest 0.9.0", "futures 0.3.21", "lmdb-zero", "log", "num-derive", "num-traits", - "patricia_tree", "prost", "prost-types", "rand 0.8.5", @@ -6839,6 +7210,7 @@ dependencies = [ "tari_core", "tari_crypto", "tari_dan_common_types", + "tari_dan_engine", "tari_mmr", "tari_p2p", "tari_service_framework", @@ -6852,19 +7224,37 @@ dependencies = [ "tonic", ] +[[package]] +name = "tari_dan_engine" +version = "0.1.0" +dependencies = [ + "anyhow", + "d3ne", + "digest 0.9.0", + "log", + "serde", + "serde_json", + "tari_common_types", + "tari_crypto", + "tari_dan_common_types", + "tari_mmr", + "tari_utilities", + "thiserror", + "wasmer", +] + [[package]] name = "tari_dan_storage_sqlite" version = "0.1.0" dependencies = [ "async-trait", - "bytecodec", "diesel", "diesel_migrations", "log", - "patricia_tree", "tari_common", "tari_common_types", "tari_dan_core", + "tari_dan_engine", "tari_utilities", "thiserror", "tokio 1.19.2", @@ -6953,7 +7343,7 @@ dependencies = [ "bincode", "bytes 1.1.0", "chrono", - "clap 3.2.6", + "clap 3.2.8", "config", "crossterm 0.17.7", "derivative", @@ -7004,7 +7394,7 @@ dependencies = [ "base64 0.13.0", "bufstream", "chrono", - "clap 3.2.6", + "clap 3.2.8", "config", "crossbeam", "crossterm 0.17.7", @@ -7087,7 +7477,7 @@ dependencies = [ "rand 0.8.5", "reqwest", "rustls", - "semver 1.0.10", + "semver 1.0.12", "serde", "serde_derive", "tari_common", @@ -7212,7 +7602,7 @@ dependencies = [ "async-trait", "blake2 0.9.2", "bytecodec", - "clap 3.2.6", + "clap 3.2.8", "config", "digest 0.9.0", "futures 0.3.21", @@ -7235,6 +7625,7 @@ dependencies = [ "tari_crypto", "tari_dan_common_types", "tari_dan_core", + "tari_dan_engine", "tari_dan_storage_sqlite", "tari_mmr", "tari_p2p", @@ -7336,13 +7727,13 @@ dependencies = [ [[package]] name = "tauri" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1ebb60bb8f246d5351ff9b7728fdfa7a6eba72baa722ab6021d553981caba1" +checksum = "421641ec549d34935530886151a42ce5ecbbb57beb30e5eec1b22f8e08e10ee9" dependencies = [ "anyhow", "attohttpc", - "clap 3.2.6", + "clap 3.2.8", "cocoa", "dirs-next 2.0.0", "embed_plist", @@ -7366,7 +7757,7 @@ dependencies = [ "raw-window-handle", "regex", "rfd", - "semver 1.0.10", + "semver 1.0.12", "serde", "serde_json", "serde_repr", @@ -7390,14 +7781,14 @@ dependencies = [ [[package]] name = "tauri-build" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7b26eb3523e962b90012fedbfb744ca153d9be85e7981e00737e106d5323941" +checksum = "598bd36884ee15ac73dfca9921066fd87d13d9beea60384b99a66c3a5d800d70" dependencies = [ "anyhow", "cargo_toml", "heck 0.4.0", - "semver 1.0.10", + "semver 1.0.12", "serde_json", "tauri-utils", "winres", @@ -7405,32 +7796,34 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9468c5189188c820ef605dfe4937c768cb2918e9460c8093dc4ee2cbd717b262" +checksum = "048a7b404b92c86e7dc32458fd0963f042a76d520681e6f598d73a97c2feeeef" dependencies = [ "base64 0.13.0", "brotli", "ico", + "plist", "png 0.17.5", "proc-macro2", "quote", "regex", - "semver 1.0.10", + "semver 1.0.12", "serde", "serde_json", "sha2 0.10.2", "tauri-utils", "thiserror", + "time 0.3.11", "uuid 1.1.2", "walkdir", ] [[package]] name = "tauri-macros" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40e3ffddd7a274fc7baaa260888c971a0d95d2ef403aa16600c878b8b1c00ffe" +checksum = "aaf70098bfab21efde9b2c089008b319ba333f4ee6e55c38bdea188dea86497f" dependencies = [ "heck 0.4.0", "proc-macro2", @@ -7442,14 +7835,15 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7dc4db360bb40584187b6cb7834da736ce4ef2ab0914e2be98014444fa9920" +checksum = "82d34f58c61a6790ba3de5753daea61b5beb6926b2384d1ad03b9dfe622c72be" dependencies = [ "gtk", "http", "http-range", "infer", + "raw-window-handle", "serde", "serde_json", "tauri-utils", @@ -7461,14 +7855,15 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c876fb3a6e7c6fe2ac466b2a6ecd83658528844b4df0914558a9bc1501b31cf3" +checksum = "cd9a56e25146ff1f13f37bdb010ed0d692e7e81c824b9f977ae439f446f37ab4" dependencies = [ "cocoa", "gtk", "percent-encoding 2.1.0", "rand 0.8.5", + "raw-window-handle", "tauri-runtime", "tauri-utils", "uuid 1.1.2", @@ -7480,9 +7875,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727145cb55b8897fa9f2bcea4fad31dc39394703d037c9669b40f2d1c0c2d7f3" +checksum = "616f178da1e0466ca45963ed108a1567d4b8803662addaca313169d0dcd97715" dependencies = [ "brotli", "ctor", @@ -7495,13 +7890,14 @@ dependencies = [ "phf 0.10.1", "proc-macro2", "quote", - "semver 1.0.10", + "semver 1.0.12", "serde", "serde_json", "serde_with", "thiserror", "url 2.2.2", "walkdir", + "windows 0.37.0", ] [[package]] @@ -7653,6 +8049,7 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" dependencies = [ + "itoa 1.0.2", "libc", "num_threads", ] @@ -7834,7 +8231,7 @@ dependencies = [ "hyper", "hyper-timeout", "percent-encoding 2.1.0", - "pin-project 1.0.10", + "pin-project 1.0.11", "prost", "prost-derive", "tokio 1.19.2", @@ -7882,7 +8279,7 @@ dependencies = [ "futures-util", "hdrhistogram", "indexmap", - "pin-project 1.0.10", + "pin-project 1.0.11", "pin-project-lite 0.2.9", "rand 0.8.5", "slab", @@ -7920,9 +8317,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", @@ -7945,7 +8342,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.0.10", + "pin-project 1.0.11", "tracing", ] @@ -8007,13 +8404,13 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.11" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" +checksum = "3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59" dependencies = [ "ansi_term", - "lazy_static", "matchers 0.1.0", + "once_cell", "regex", "sharded-slab", "smallvec", @@ -8206,9 +8603,9 @@ checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] name = "unicode-normalization" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" dependencies = [ "tinyvec", ] @@ -8422,7 +8819,7 @@ dependencies = [ "mime", "mime_guess", "percent-encoding 2.1.0", - "pin-project 1.0.10", + "pin-project 1.0.11", "scoped-tls", "serde", "serde_json", @@ -8544,6 +8941,273 @@ dependencies = [ "quote", ] +[[package]] +name = "wasm-encoder" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f0c17267a5ffd6ae3d897589460e21db1673c84fb7016b909c9691369a75ea" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasmer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +dependencies = [ + "cfg-if 1.0.0", + "indexmap", + "js-sys", + "loupe", + "more-asserts", + "target-lexicon", + "thiserror", + "wasm-bindgen", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-compiler-cranelift", + "wasmer-derive", + "wasmer-engine", + "wasmer-engine-dylib", + "wasmer-engine-universal", + "wasmer-types", + "wasmer-vm", + "wat", + "winapi 0.3.9", +] + +[[package]] +name = "wasmer-artifact" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" +dependencies = [ + "enumset", + "loupe", + "thiserror", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-compiler" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +dependencies = [ + "enumset", + "loupe", + "rkyv", + "serde", + "serde_bytes", + "smallvec", + "target-lexicon", + "thiserror", + "wasmer-types", + "wasmparser", +] + +[[package]] +name = "wasmer-compiler-cranelift" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "gimli", + "loupe", + "more-asserts", + "rayon", + "smallvec", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-derive" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasmer-engine" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" +dependencies = [ + "backtrace", + "enumset", + "lazy_static", + "loupe", + "memmap2", + "more-asserts", + "rustc-demangle", + "serde", + "serde_bytes", + "target-lexicon", + "thiserror", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-types", + "wasmer-vm", +] + +[[package]] +name = "wasmer-engine-dylib" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" +dependencies = [ + "cfg-if 1.0.0", + "enum-iterator", + "enumset", + "leb128", + "libloading", + "loupe", + "object", + "rkyv", + "serde", + "tempfile", + "tracing", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-engine", + "wasmer-object", + "wasmer-types", + "wasmer-vm", + "which", +] + +[[package]] +name = "wasmer-engine-universal" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" +dependencies = [ + "cfg-if 1.0.0", + "enumset", + "leb128", + "loupe", + "region", + "rkyv", + "wasmer-compiler", + "wasmer-engine", + "wasmer-engine-universal-artifact", + "wasmer-types", + "wasmer-vm", + "winapi 0.3.9", +] + +[[package]] +name = "wasmer-engine-universal-artifact" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" +dependencies = [ + "enum-iterator", + "enumset", + "loupe", + "rkyv", + "thiserror", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-object" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" +dependencies = [ + "object", + "thiserror", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-types" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +dependencies = [ + "backtrace", + "enum-iterator", + "indexmap", + "loupe", + "more-asserts", + "rkyv", + "serde", + "thiserror", +] + +[[package]] +name = "wasmer-vm" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +dependencies = [ + "backtrace", + "cc", + "cfg-if 1.0.0", + "corosensei", + "enum-iterator", + "indexmap", + "lazy_static", + "libc", + "loupe", + "mach", + "memoffset", + "more-asserts", + "region", + "rkyv", + "scopeguard", + "serde", + "thiserror", + "wasmer-artifact", + "wasmer-types", + "winapi 0.3.9", +] + +[[package]] +name = "wasmparser" +version = "0.83.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" + +[[package]] +name = "wast" +version = "42.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badcb03f976f983ff0daf294da9697be659442f61e6b0942bb37a2b6cbfe9dd4" +dependencies = [ + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b92f20b742ac527066c8414bc0637352661b68cab07ef42586cefaba71c965cf" +dependencies = [ + "wast", +] + [[package]] name = "web-sys" version = "0.3.57" @@ -8671,9 +9335,9 @@ dependencies = [ [[package]] name = "wildmatch" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" +checksum = "ee583bdc5ff1cf9db20e9db5bb3ff4c3089a8f6b8b31aff265c9aba85812db86" [[package]] name = "winapi" @@ -8770,6 +9434,19 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f33f2b90a6664e369c41ab5ff262d06f048fc9685d9bf8a0e99a47750bb0463" +[[package]] +name = "windows-sys" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" +dependencies = [ + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + [[package]] name = "windows-sys" version = "0.36.1" @@ -8789,6 +9466,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3263d25f1170419995b78ff10c06b949e8a986c35c208dc24333c64753a87169" +[[package]] +name = "windows_aarch64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -8807,6 +9490,12 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0866510a3eca9aed73a077490bbbf03e5eaac4e1fd70849d89539e5830501fd" +[[package]] +name = "windows_i686_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" + [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -8825,6 +9514,12 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf0ffed56b7e9369a29078d2ab3aaeceea48eb58999d2cff3aa2494a275b95c6" +[[package]] +name = "windows_i686_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" + [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -8843,6 +9538,12 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384a173630588044205a2993b6864a2f56e5a8c1e7668c07b93ec18cf4888dc4" +[[package]] +name = "windows_x86_64_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -8861,6 +9562,12 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bd8f062d8ca5446358159d79a90be12c543b3a965c847c8f3eedf14b321d399" +[[package]] +name = "windows_x86_64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -8904,9 +9611,9 @@ dependencies = [ [[package]] name = "wry" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b1ba327c7dd4292f46bf8e6ba8e6ec2db4443b2973c9d304a359d95e0aa856" +checksum = "ce19dddbd3ce01dc8f14eb6d4c8f914123bf8379aaa838f6da4f981ff7104a3f" dependencies = [ "block", "cocoa", @@ -9034,8 +9741,3 @@ dependencies = [ "syn", "synstructure", ] - -[[patch.unused]] -name = "pgp" -version = "0.7.2" -source = "git+https://github.com/tari-project/rpgp.git?rev=32939dbe86565d5ede769a7907ec42dfdf353849#32939dbe86565d5ede769a7907ec42dfdf353849" diff --git a/Cargo.toml b/Cargo.toml index 3fe93f2d6b..6e3e7eb64b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,8 +35,6 @@ members = [ ] # -#[profile.release] -#debug = true # Shutdown when panicking so we can see the error, specifically for the wallet [profile.release] @@ -46,4 +44,5 @@ panic = 'abort' # Temporarily lock pgp to commit (master branch at time of writing) because the currently release crate locks zeroize to =1.3 liblmdb-sys = { git = "https://github.com/tari-project/lmdb-rs", tag = "0.7.6-tari.1" } #pgp = { git = "https://github.com/rpgp/rpgp.git", rev = "21081b6aaaaa5750ab937cfef30bae879a740d23" } -pgp = { git = "https://github.com/tari-project/rpgp.git", rev = "32939dbe86565d5ede769a7907ec42dfdf353849" } +#pgp = { git = "https://github.com/tari-project/rpgp.git", rev = "32939dbe86565d5ede769a7907ec42dfdf353849" } + diff --git a/applications/tari_validator_node/Cargo.toml b/applications/tari_validator_node/Cargo.toml index 85d177fb25..ebe3e79757 100644 --- a/applications/tari_validator_node/Cargo.toml +++ b/applications/tari_validator_node/Cargo.toml @@ -25,6 +25,7 @@ tari_dan_core = { path = "../../dan_layer/core" } tari_dan_storage_sqlite = { path = "../../dan_layer/storage_sqlite" } tari_dan_common_types = { path = "../../dan_layer/common_types" } tari_common_types = { path = "../../base_layer/common_types" } +tari_dan_engine = { path = "../../dan_layer/engine"} anyhow = "1.0.53" async-trait = "0.1.50" diff --git a/applications/tari_validator_node/src/contract_worker_manager.rs b/applications/tari_validator_node/src/contract_worker_manager.rs index 8b7f3bbcec..4f3558738d 100644 --- a/applications/tari_validator_node/src/contract_worker_manager.rs +++ b/applications/tari_validator_node/src/contract_worker_manager.rs @@ -359,6 +359,9 @@ impl ContractWorkerManager { checkpoint_unique_id: vec![], initial_state: Default::default(), template_parameters: vec![], + wasm_modules: vec![], + wasm_functions: vec![], + flow_functions: vec![], }, node_identity, mempool, diff --git a/applications/tari_validator_node/src/grpc/services/wallet_client.rs b/applications/tari_validator_node/src/grpc/services/wallet_client.rs index c8a1bf9056..fc9d0aa61d 100644 --- a/applications/tari_validator_node/src/grpc/services/wallet_client.rs +++ b/applications/tari_validator_node/src/grpc/services/wallet_client.rs @@ -34,7 +34,8 @@ use tari_app_grpc::{ }; use tari_common_types::types::{FixedHash, PublicKey, Signature}; use tari_crypto::tari_utilities::ByteArray; -use tari_dan_core::{models::StateRoot, services::WalletClient, DigitalAssetError}; +use tari_dan_core::{services::WalletClient, DigitalAssetError}; +use tari_dan_engine::state::models::StateRoot; type Inner = grpc::wallet_client::WalletClient; diff --git a/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs b/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs index bf4c9eb7dc..8db5bd6e46 100644 --- a/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs +++ b/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs @@ -30,10 +30,10 @@ use tari_common_types::types::{FixedHash, PublicKey, Signature}; use tari_comms::NodeIdentity; use tari_crypto::tari_utilities::ByteArray; use tari_dan_core::{ - models::Instruction, services::{AssetProcessor, AssetProxy, ServiceSpecification, WalletClient}, storage::DbFactory, }; +use tari_dan_engine::instructions::Instruction; use tokio::{task, time}; use tonic::{Request, Response, Status}; diff --git a/applications/tari_validator_node/src/p2p/proto/conversions.rs b/applications/tari_validator_node/src/p2p/proto/conversions.rs index ec4b3f29db..cd54cdc858 100644 --- a/applications/tari_validator_node/src/p2p/proto/conversions.rs +++ b/applications/tari_validator_node/src/p2p/proto/conversions.rs @@ -24,27 +24,27 @@ use std::convert::{TryFrom, TryInto}; use tari_common_types::types::PublicKey; use tari_crypto::tari_utilities::ByteArray; -use tari_dan_core::{ - models::{ - CheckpointData, - HotStuffMessage, - HotStuffMessageType, - HotStuffTreeNode, - Instruction, - InstructionSet, - KeyValue, - Node, - QuorumCertificate, - SideChainBlock, - Signature, - StateOpLogEntry, - StateRoot, - TariDanPayload, - TemplateId, - TreeNodeHash, - ViewId, +use tari_dan_common_types::TemplateId; +use tari_dan_core::models::{ + CheckpointData, + HotStuffMessage, + HotStuffMessageType, + HotStuffTreeNode, + InstructionSet, + Node, + QuorumCertificate, + SideChainBlock, + Signature, + TariDanPayload, + TreeNodeHash, + ViewId, +}; +use tari_dan_engine::{ + instructions::Instruction, + state::{ + models::{KeyValue, StateOpLogEntry, StateRoot}, + DbStateOpLogEntry, }, - storage::state::DbStateOpLogEntry, }; use crate::p2p::proto; @@ -218,7 +218,7 @@ impl TryFrom for Instruction { type Error = String; fn try_from(value: proto::common::Instruction) -> Result { - let template_id = TemplateId::try_from(value.template_id).map_err(|err| err.to_string())?; + let template_id = TemplateId::try_from(value.template_id)?; Ok(Self::new( template_id, value.method, diff --git a/applications/tari_validator_node/src/p2p/rpc/service_impl.rs b/applications/tari_validator_node/src/p2p/rpc/service_impl.rs index 681a77f371..4eb0561fad 100644 --- a/applications/tari_validator_node/src/p2p/rpc/service_impl.rs +++ b/applications/tari_validator_node/src/p2p/rpc/service_impl.rs @@ -28,16 +28,18 @@ use tari_comms::{ utils, }; use tari_dan_core::{ - models::{Instruction, TreeNodeHash}, + models::TreeNodeHash, services::{AssetProcessor, MempoolService}, - storage::{state::StateDbUnitOfWorkReader, DbFactory}, + storage::DbFactory, }; +use tari_dan_engine::state::StateDbUnitOfWorkReader; use tokio::{sync::mpsc, task}; const LOG_TARGET: &str = "vn::p2p::rpc"; use tari_common_types::types::PublicKey; use tari_crypto::tari_utilities::ByteArray; +use tari_dan_engine::instructions::Instruction; use crate::p2p::{proto::validator_node as proto, rpc::ValidatorNodeRpcService}; diff --git a/applications/tari_validator_node/src/p2p/services/rpc_client.rs b/applications/tari_validator_node/src/p2p/services/rpc_client.rs index 4e1a0121dd..ca99d05873 100644 --- a/applications/tari_validator_node/src/p2p/services/rpc_client.rs +++ b/applications/tari_validator_node/src/p2p/services/rpc_client.rs @@ -28,10 +28,12 @@ use tari_common_types::types::{FixedHash, PublicKey}; use tari_comms::PeerConnection; use tari_comms_dht::DhtRequester; use tari_crypto::tari_utilities::ByteArray; +use tari_dan_common_types::TemplateId; use tari_dan_core::{ - models::{Node, SchemaState, SideChainBlock, StateOpLogEntry, TemplateId, TreeNodeHash}, + models::{Node, SideChainBlock, TreeNodeHash}, services::{ValidatorNodeClientError, ValidatorNodeClientFactory, ValidatorNodeRpcClient}, }; +use tari_dan_engine::state::models::{SchemaState, StateOpLogEntry}; use tokio_stream::StreamExt; use crate::p2p::{proto::validator_node as proto, rpc}; diff --git a/dan_layer/common_types/src/lib.rs b/dan_layer/common_types/src/lib.rs index ff76c528c5..7772dd98c9 100644 --- a/dan_layer/common_types/src/lib.rs +++ b/dan_layer/common_types/src/lib.rs @@ -2,3 +2,7 @@ // SPDX-License-Identifier: BSD-3-Clause pub mod proto; +pub mod storage; + +mod template_id; +pub use template_id::TemplateId; diff --git a/dan_layer/common_types/src/storage/mod.rs b/dan_layer/common_types/src/storage/mod.rs new file mode 100644 index 0000000000..4d542cd250 --- /dev/null +++ b/dan_layer/common_types/src/storage/mod.rs @@ -0,0 +1,6 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +mod unit_of_work_tracker; + +pub use unit_of_work_tracker::UnitOfWorkTracker; diff --git a/dan_layer/common_types/src/storage/unit_of_work_tracker.rs b/dan_layer/common_types/src/storage/unit_of_work_tracker.rs new file mode 100644 index 0000000000..acdd3238db --- /dev/null +++ b/dan_layer/common_types/src/storage/unit_of_work_tracker.rs @@ -0,0 +1,47 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + RwLock, + RwLockReadGuard, + RwLockWriteGuard, +}; + +#[derive(Debug)] +pub struct UnitOfWorkTracker { + item: Arc>, + is_dirty: Arc, +} + +impl Clone for UnitOfWorkTracker { + fn clone(&self) -> Self { + Self { + item: self.item.clone(), + is_dirty: self.is_dirty.clone(), + } + } +} + +impl UnitOfWorkTracker { + pub fn new(item: TItem, is_dirty: bool) -> Self { + Self { + item: Arc::new(RwLock::new(item)), + is_dirty: Arc::new(AtomicBool::new(is_dirty)), + } + } + + pub fn get(&self) -> RwLockReadGuard { + self.item.read().unwrap() + } + + pub fn get_mut(&self) -> RwLockWriteGuard { + self.is_dirty.store(true, Ordering::SeqCst); + self.item.write().unwrap() + } + + pub fn is_dirty(&self) -> bool { + self.is_dirty.load(Ordering::SeqCst) + } +} diff --git a/dan_layer/common_types/src/template_id.rs b/dan_layer/common_types/src/template_id.rs new file mode 100644 index 0000000000..8c2aedab86 --- /dev/null +++ b/dan_layer/common_types/src/template_id.rs @@ -0,0 +1,70 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::{ + convert::TryFrom, + fmt::{Display, Formatter}, + str::FromStr, +}; + +#[derive(Copy, Clone, Debug)] +pub enum TemplateId { + Tip002 = 2, + Tip003 = 3, + Tip004 = 4, + Tip721 = 721, + EditableMetadata = 20, +} + +impl FromStr for TemplateId { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "Tip002" => Ok(TemplateId::Tip002), + "Tip003" => Ok(TemplateId::Tip003), + "Tip004" => Ok(TemplateId::Tip004), + "Tip721" => Ok(TemplateId::Tip721), + "EditableMetadata" => Ok(TemplateId::EditableMetadata), + _ => { + println!("Unrecognised template"); + Err(format!("Unrecognised template ID '{}'", s)) + }, + } + } +} + +impl TryFrom for TemplateId { + type Error = String; + + fn try_from(value: u32) -> Result { + match value { + 2 => Ok(TemplateId::Tip002), + 3 => Ok(TemplateId::Tip003), + 4 => Ok(TemplateId::Tip004), + 721 => Ok(TemplateId::Tip721), + _ => Err(format!("Unknown value: {}", value)), + } + } +} + +impl TryFrom for TemplateId { + type Error = String; + + fn try_from(value: i32) -> Result { + u32::try_from(value) + .map_err(|_| { + format!( + "Could not convert to TemplateId because it was not a valid u32:{}", + value + ) + })? + .try_into() + } +} + +impl Display for TemplateId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} diff --git a/dan_layer/core/Cargo.toml b/dan_layer/core/Cargo.toml index ecb17a3fbb..719eb1e89a 100644 --- a/dan_layer/core/Cargo.toml +++ b/dan_layer/core/Cargo.toml @@ -21,6 +21,7 @@ tari_core = {path = "../../base_layer/core"} tari_dan_common_types = {path = "../common_types"} tari_common_types = {path = "../../base_layer/common_types"} tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.4" } +tari_dan_engine = { path = "../engine"} anyhow = "1.0.53" async-trait = "0.1.50" @@ -41,9 +42,6 @@ tokio = { version="1.10", features = ["macros", "time"]} tokio-stream = { version = "0.1.7", features = ["sync"] } tonic = "0.6.2" -# saving of patricia tree -patricia_tree = { version = "0.3.0", features = ["binary-format"] } -bytecodec = { version = "0.4.14", features = ["bincode_codec"] } serde_json = "1.0.64" [dev-dependencies] diff --git a/dan_layer/core/src/digital_assets_error.rs b/dan_layer/core/src/digital_assets_error.rs index 5afe2b8ab2..bdd9bb435d 100644 --- a/dan_layer/core/src/digital_assets_error.rs +++ b/dan_layer/core/src/digital_assets_error.rs @@ -23,6 +23,7 @@ use prost::DecodeError; use tari_comms_dht::outbound::DhtOutboundError; use tari_crypto::ristretto::RistrettoPublicKey; +use tari_dan_engine::state::error::StateStorageError; use thiserror::Error; use tokio::sync::mpsc::error::SendError; @@ -105,6 +106,8 @@ pub enum DigitalAssetError { SendError(#[from] Box)>>), #[error("Invalid committee public key hex")] InvalidCommitteePublicKeyHex, + #[error("State storage error:{0}")] + StateStorageError(#[from] StateStorageError), } impl From for DigitalAssetError { diff --git a/dan_layer/core/src/models/asset_definition.rs b/dan_layer/core/src/models/asset_definition.rs index 97d89bc414..990668b6cd 100644 --- a/dan_layer/core/src/models/asset_definition.rs +++ b/dan_layer/core/src/models/asset_definition.rs @@ -23,6 +23,11 @@ use serde::{self, Deserialize, Serialize}; use tari_common_types::types::FixedHash; use tari_core::transactions::transaction_components::TemplateParameter; +use tari_dan_engine::{ + function_definitions::{FlowFunctionDefinition, WasmFunctionDefinition}, + state::models::SchemaState, + wasm::WasmModuleDefinition, +}; use crate::helpers::deserialize_from_hex; @@ -40,6 +45,9 @@ pub struct AssetDefinition { pub checkpoint_unique_id: Vec, pub initial_state: InitialState, pub template_parameters: Vec, + pub wasm_modules: Vec, + pub wasm_functions: Vec, + pub flow_functions: Vec, } impl Default for AssetDefinition { @@ -52,6 +60,9 @@ impl Default for AssetDefinition { phase_timeout: 30, initial_state: Default::default(), template_parameters: vec![], + wasm_modules: vec![], + wasm_functions: vec![], + flow_functions: vec![], } } } @@ -66,26 +77,3 @@ impl AssetDefinition { pub struct InitialState { pub schemas: Vec, } - -#[derive(Serialize, Deserialize, Default, Clone, Debug)] -pub struct SchemaState { - pub name: String, - pub items: Vec, -} - -impl SchemaState { - pub fn new(name: String, items: Vec) -> Self { - Self { name, items } - } - - pub fn push_key_value(&mut self, key_value: KeyValue) -> &mut Self { - self.items.push(key_value); - self - } -} - -#[derive(Serialize, Deserialize, Default, Clone, Debug)] -pub struct KeyValue { - pub key: Vec, - pub value: Vec, -} diff --git a/dan_layer/core/src/models/hot_stuff_tree_node.rs b/dan_layer/core/src/models/hot_stuff_tree_node.rs index 9478168c22..aec285709f 100644 --- a/dan_layer/core/src/models/hot_stuff_tree_node.rs +++ b/dan_layer/core/src/models/hot_stuff_tree_node.rs @@ -22,8 +22,9 @@ use digest::{Digest, FixedOutput}; use tari_crypto::common::Blake256; +use tari_dan_engine::state::models::StateRoot; -use crate::models::{Payload, StateRoot, TreeNodeHash}; +use crate::models::{Payload, TreeNodeHash}; #[derive(Debug, Clone)] pub struct HotStuffTreeNode { diff --git a/dan_layer/core/src/models/instruction_set.rs b/dan_layer/core/src/models/instruction_set.rs index b082b0dbaf..595943f61b 100644 --- a/dan_layer/core/src/models/instruction_set.rs +++ b/dan_layer/core/src/models/instruction_set.rs @@ -24,9 +24,10 @@ use std::{convert::TryFrom, hash::Hash, iter::FromIterator}; use tari_common_types::types::FixedHash; use tari_crypto::common::Blake256; +use tari_dan_engine::instructions::Instruction; use tari_mmr::MerkleMountainRange; -use crate::models::{ConsensusHash, Instruction}; +use crate::models::ConsensusHash; #[derive(PartialEq, Eq, Clone, Debug, Hash)] pub struct InstructionSetHash(FixedHash); diff --git a/dan_layer/core/src/models/mod.rs b/dan_layer/core/src/models/mod.rs index 2349e3c465..a39acc8c2f 100644 --- a/dan_layer/core/src/models/mod.rs +++ b/dan_layer/core/src/models/mod.rs @@ -20,12 +20,7 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use std::{ - convert::{TryFrom, TryInto}, - fmt::{Debug, Display, Formatter}, - hash::Hash, - str::FromStr, -}; +use std::{convert::TryFrom, fmt::Debug, hash::Hash}; mod asset_definition; mod base_layer_metadata; @@ -35,36 +30,30 @@ pub mod domain_events; mod error; mod hot_stuff_message; mod hot_stuff_tree_node; -mod instruction; mod instruction_set; mod node; -mod op_log; mod payload; mod quorum_certificate; mod sidechain_block; mod sidechain_metadata; -mod state_root; mod tari_dan_payload; mod tree_node_hash; mod view; mod view_id; -pub use asset_definition::{AssetDefinition, InitialState, KeyValue, SchemaState}; +pub use asset_definition::{AssetDefinition, InitialState}; pub use base_layer_metadata::BaseLayerMetadata; pub use base_layer_output::{BaseLayerOutput, CheckpointOutput, CommitteeOutput}; pub use committee::Committee; pub use error::ModelError; pub use hot_stuff_message::HotStuffMessage; pub use hot_stuff_tree_node::HotStuffTreeNode; -pub use instruction::Instruction; pub use instruction_set::InstructionSet; pub use node::Node; -pub use op_log::{StateOpLogEntry, StateOperation}; pub use payload::Payload; pub use quorum_certificate::QuorumCertificate; pub use sidechain_block::SideChainBlock; pub use sidechain_metadata::SidechainMetadata; -pub use state_root::StateRoot; pub use tari_dan_payload::{CheckpointData, TariDanPayload}; pub use tree_node_hash::TreeNodeHash; pub use view::View; @@ -81,69 +70,6 @@ impl InstructionCaller { } } -#[derive(Copy, Clone, Debug)] -pub enum TemplateId { - Tip002 = 2, - Tip003 = 3, - Tip004 = 4, - Tip721 = 721, - EditableMetadata = 20, -} - -impl FromStr for TemplateId { - type Err = ModelError; - - fn from_str(s: &str) -> Result { - match s { - "Tip002" => Ok(TemplateId::Tip002), - "Tip003" => Ok(TemplateId::Tip003), - "Tip004" => Ok(TemplateId::Tip004), - "Tip721" => Ok(TemplateId::Tip721), - "EditableMetadata" => Ok(TemplateId::EditableMetadata), - _ => { - println!("Unrecognised template"); - Err(ModelError::StringParseError { - details: format!("Unrecognised template ID '{}'", s), - }) - }, - } - } -} - -impl TryFrom for TemplateId { - type Error = ModelError; - - fn try_from(value: u32) -> Result { - match value { - 2 => Ok(TemplateId::Tip002), - 3 => Ok(TemplateId::Tip003), - 4 => Ok(TemplateId::Tip004), - 721 => Ok(TemplateId::Tip721), - _ => Err(ModelError::InvalidTemplateIdNumber { - value: i64::from(value), - }), - } - } -} - -impl TryFrom for TemplateId { - type Error = ModelError; - - fn try_from(value: i32) -> Result { - u32::try_from(value) - .map_err(|_| ModelError::InvalidTemplateIdNumber { - value: i64::from(value), - })? - .try_into() - } -} - -impl Display for TemplateId { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self) - } -} - #[derive(Clone, Debug, Hash)] pub struct TokenId(pub Vec); diff --git a/dan_layer/core/src/models/op_log.rs b/dan_layer/core/src/models/op_log.rs deleted file mode 100644 index be3b2e9e97..0000000000 --- a/dan_layer/core/src/models/op_log.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2022, The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use crate::storage::state::{DbStateOpLogEntry, DbStateOperation}; - -#[derive(Debug)] -pub struct StateOpLogEntry { - inner: DbStateOpLogEntry, -} - -impl StateOpLogEntry { - pub fn operation(&self) -> StateOperation { - self.inner.operation.into() - } - - pub fn into_inner(self) -> DbStateOpLogEntry { - self.inner - } -} - -impl From for StateOpLogEntry { - fn from(inner: DbStateOpLogEntry) -> Self { - Self { inner } - } -} - -#[derive(Debug, Clone, Copy)] -pub enum StateOperation { - Set, - Delete, -} - -impl StateOperation { - pub fn as_op_str(&self) -> &str { - use StateOperation::{Delete, Set}; - match self { - Set => "S", - Delete => "D", - } - } -} - -impl From for StateOperation { - fn from(op: DbStateOperation) -> Self { - match op { - DbStateOperation::Set => StateOperation::Set, - DbStateOperation::Delete => StateOperation::Delete, - } - } -} diff --git a/dan_layer/core/src/models/state_root.rs b/dan_layer/core/src/models/state_root.rs deleted file mode 100644 index 75b539e663..0000000000 --- a/dan_layer/core/src/models/state_root.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use tari_common_types::types::FixedHash; - -#[derive(PartialEq, Eq, Debug, Clone)] -pub struct StateRoot { - root: FixedHash, -} - -impl StateRoot { - pub fn new(root: FixedHash) -> Self { - Self { root } - } - - pub fn as_bytes(&self) -> &[u8] { - self.root.as_slice() - } - - pub fn initial() -> Self { - Self { - root: FixedHash::zero(), - } - } -} diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index 427b19a064..0693f2b3f5 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -25,8 +25,9 @@ use std::fmt::Debug; use digest::Digest; use tari_common_types::types::FixedHash; use tari_crypto::common::Blake256; +use tari_dan_engine::instructions::Instruction; -use crate::models::{ConsensusHash, Instruction, InstructionSet, Payload}; +use crate::models::{ConsensusHash, InstructionSet, Payload}; #[derive(Debug, Clone)] pub struct TariDanPayload { diff --git a/dan_layer/core/src/services/asset_processor.rs b/dan_layer/core/src/services/asset_processor.rs index 2d4287098f..918c7e28a1 100644 --- a/dan_layer/core/src/services/asset_processor.rs +++ b/dan_layer/core/src/services/asset_processor.rs @@ -23,11 +23,16 @@ use std::convert::TryInto; use tari_core::transactions::transaction_components::TemplateParameter; +use tari_dan_engine::{ + flow::FlowFactory, + instructions::Instruction, + state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}, + wasm::WasmModuleFactory, +}; use crate::{ digital_assets_error::DigitalAssetError, - models::{Instruction, InstructionSet, TemplateId}, - storage::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}, + models::{AssetDefinition, InstructionSet}, template_command::ExecutionResult, templates::{tip002_template, tip004_template, tip721_template}, }; @@ -50,7 +55,23 @@ pub trait AssetProcessor: Sync + Send + 'static { #[derive(Default, Clone)] pub struct ConcreteAssetProcessor { + _asset_definition: AssetDefinition, template_factory: TemplateFactory, + _wasm_factory: WasmModuleFactory, + _function_interface: FunctionInterface, + _flow_factory: FlowFactory, +} + +impl ConcreteAssetProcessor { + pub fn new(asset_definition: AssetDefinition) -> Self { + Self { + _wasm_factory: WasmModuleFactory::new(&asset_definition.wasm_modules, &asset_definition.wasm_functions), + _flow_factory: FlowFactory::new(&asset_definition.flow_functions), + _asset_definition: asset_definition, + template_factory: Default::default(), + _function_interface: FunctionInterface {}, + } + } } impl AssetProcessor for ConcreteAssetProcessor { @@ -71,12 +92,39 @@ impl AssetProcessor for ConcreteAssetProcessor { } } +#[derive(Clone, Default)] +pub struct FunctionInterface {} + +// impl FunctionInterface { +// #[allow(dead_code)] +// fn find_executor(&self, instruction: &Instruction) -> Result { +// match instruction.template_id() { +// // TODO: Put these back +// // TemplateId::Tip6000 => Ok(InstructionExecutor::WasmModule { +// // name: instruction.method().to_string(), +// // }), +// // TemplateId::Tip7000 => Ok(InstructionExecutor::Flow { +// // name: instruction.method().to_string(), +// // }), +// _ => Ok(InstructionExecutor::Template { +// template_id: instruction.template_id(), +// }), +// } +// } +// } +// +// pub enum InstructionExecutor { +// WasmModule { name: String }, +// Template { template_id: TemplateId }, +// Flow { name: String }, +// } + #[derive(Default, Clone)] pub struct TemplateFactory {} impl TemplateFactory { pub fn initial_instructions(&self, template_param: &TemplateParameter) -> InstructionSet { - use TemplateId::{EditableMetadata, Tip002, Tip003, Tip004, Tip721}; + use tari_dan_common_types::TemplateId::{EditableMetadata, Tip002, Tip003, Tip004, Tip721}; // TODO: We may want to use the TemplateId type, so that we know it is known/valid let template_id = template_param.template_id.try_into().unwrap(); match template_id { @@ -95,7 +143,7 @@ impl TemplateFactory { instruction: &Instruction, state_db: &TUnitOfWork, ) -> Result>, DigitalAssetError> { - use TemplateId::{EditableMetadata, Tip002, Tip003, Tip004, Tip721}; + use tari_dan_common_types::TemplateId::{EditableMetadata, Tip002, Tip003, Tip004, Tip721}; match instruction.template_id() { Tip002 => tip002_template::invoke_read_method(instruction.method(), instruction.args(), state_db), Tip003 => todo!(), @@ -112,7 +160,7 @@ impl TemplateFactory { instruction: &Instruction, state_db: &mut TUnitOfWork, ) -> Result<(), DigitalAssetError> { - use TemplateId::{EditableMetadata, Tip002, Tip003, Tip004, Tip721}; + use tari_dan_common_types::TemplateId::{EditableMetadata, Tip002, Tip003, Tip004, Tip721}; match instruction.template_id() { Tip002 => tip002_template::invoke_write_method(instruction.method(), instruction.args(), state_db), Tip003 => todo!(), diff --git a/dan_layer/core/src/services/asset_proxy.rs b/dan_layer/core/src/services/asset_proxy.rs index 079affdf95..0c0babd1e1 100644 --- a/dan_layer/core/src/services/asset_proxy.rs +++ b/dan_layer/core/src/services/asset_proxy.rs @@ -25,11 +25,12 @@ use futures::stream::FuturesUnordered; use log::*; use tari_common_types::types::{FixedHash, PublicKey}; use tari_core::transactions::transaction_components::OutputType; +use tari_dan_common_types::TemplateId; +use tari_dan_engine::instructions::Instruction; use tari_utilities::hex::Hex; use tokio_stream::StreamExt; use crate::{ - models::{Instruction, TemplateId}, services::{ validator_node_rpc_client::ValidatorNodeRpcClient, BaseNodeClient, diff --git a/dan_layer/core/src/services/checkpoint_manager.rs b/dan_layer/core/src/services/checkpoint_manager.rs index f7ee1ff7ec..04c9881263 100644 --- a/dan_layer/core/src/services/checkpoint_manager.rs +++ b/dan_layer/core/src/services/checkpoint_manager.rs @@ -22,12 +22,9 @@ use async_trait::async_trait; use log::*; +use tari_dan_engine::state::models::StateRoot; -use crate::{ - models::{AssetDefinition, StateRoot}, - services::wallet_client::WalletClient, - DigitalAssetError, -}; +use crate::{models::AssetDefinition, services::wallet_client::WalletClient, DigitalAssetError}; const LOG_TARGET: &str = "tari::dan::checkpoint_manager"; diff --git a/dan_layer/core/src/services/mempool_service.rs b/dan_layer/core/src/services/mempool_service.rs index 090f29a562..dfa1376d8f 100644 --- a/dan_layer/core/src/services/mempool_service.rs +++ b/dan_layer/core/src/services/mempool_service.rs @@ -24,12 +24,10 @@ use std::sync::Arc; use async_trait::async_trait; use tari_common_types::types::FixedHash; +use tari_dan_engine::instructions::Instruction; use tokio::sync::Mutex; -use crate::{ - digital_assets_error::DigitalAssetError, - models::{Instruction, TreeNodeHash}, -}; +use crate::{digital_assets_error::DigitalAssetError, models::TreeNodeHash}; #[async_trait] pub trait MempoolService: Sync + Send + 'static { diff --git a/dan_layer/core/src/services/mocks/mod.rs b/dan_layer/core/src/services/mocks/mod.rs index 3b76fd50bb..2de451e2b1 100644 --- a/dan_layer/core/src/services/mocks/mod.rs +++ b/dan_layer/core/src/services/mocks/mod.rs @@ -30,6 +30,17 @@ use async_trait::async_trait; use tari_common_types::types::{FixedHash, PublicKey}; use tari_core::{chain_storage::UtxoMinedInfo, transactions::transaction_components::OutputType}; use tari_crypto::ristretto::RistrettoPublicKey; +use tari_dan_common_types::TemplateId; +#[cfg(test)] +use tari_dan_engine::state::mocks::state_db::MockStateDbBackupAdapter; +use tari_dan_engine::{ + instructions::Instruction, + state::{ + models::{SchemaState, StateOpLogEntry, StateRoot}, + StateDbUnitOfWork, + StateDbUnitOfWorkReader, + }, +}; use crate::{ digital_assets_error::DigitalAssetError, @@ -40,18 +51,13 @@ use crate::{ Committee, Event, HotStuffTreeNode, - Instruction, InstructionSet, Node, Payload, - SchemaState, SideChainBlock, SidechainMetadata, Signature, - StateOpLogEntry, - StateRoot, TariDanPayload, - TemplateId, TreeNodeHash, }, services::{ @@ -70,19 +76,14 @@ use crate::{ ValidatorNodeRpcClient, WalletClient, }, - storage::{ - chain::ChainDbUnitOfWork, - state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}, - ChainStorageService, - StorageError, - }, + storage::{chain::ChainDbUnitOfWork, ChainStorageService, StorageError}, }; #[cfg(test)] use crate::{ models::domain_events::ConsensusWorkerDomainEvent, services::infrastructure_services::mocks::{MockInboundConnectionService, MockOutboundService}, services::{ConcreteAssetProxy, ServiceSpecification}, - storage::mocks::{chain_db::MockChainDbBackupAdapter, state_db::MockStateDbBackupAdapter, MockDbFactory}, + storage::mocks::{chain_db::MockChainDbBackupAdapter, MockDbFactory}, }; #[derive(Debug, Clone)] diff --git a/dan_layer/core/src/services/payload_processor.rs b/dan_layer/core/src/services/payload_processor.rs index 1c11d0a630..448d2ca2ba 100644 --- a/dan_layer/core/src/services/payload_processor.rs +++ b/dan_layer/core/src/services/payload_processor.rs @@ -21,12 +21,12 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use async_trait::async_trait; +use tari_dan_engine::state::{models::StateRoot, StateDbUnitOfWork}; use crate::{ digital_assets_error::DigitalAssetError, - models::{Payload, StateRoot, TariDanPayload}, + models::{Payload, TariDanPayload}, services::AssetProcessor, - storage::state::StateDbUnitOfWork, }; #[async_trait] diff --git a/dan_layer/core/src/services/service_specification.rs b/dan_layer/core/src/services/service_specification.rs index 04d8dad095..5c073ebbc8 100644 --- a/dan_layer/core/src/services/service_specification.rs +++ b/dan_layer/core/src/services/service_specification.rs @@ -20,6 +20,8 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use tari_dan_engine::state::StateDbBackendAdapter; + use crate::{ models::{domain_events::ConsensusWorkerDomainEvent, Payload}, services::{ @@ -37,13 +39,7 @@ use crate::{ SigningService, ValidatorNodeClientFactory, }, - storage::{ - chain::ChainDbBackendAdapter, - global::GlobalDbBackendAdapter, - state::StateDbBackendAdapter, - ChainStorageService, - DbFactory, - }, + storage::{chain::ChainDbBackendAdapter, global::GlobalDbBackendAdapter, ChainStorageService, DbFactory}, }; /// A trait to describe a specific configuration of services. This type allows other services to diff --git a/dan_layer/core/src/services/validator_node_rpc_client.rs b/dan_layer/core/src/services/validator_node_rpc_client.rs index b5f88c39f2..5fbcd7360c 100644 --- a/dan_layer/core/src/services/validator_node_rpc_client.rs +++ b/dan_layer/core/src/services/validator_node_rpc_client.rs @@ -28,9 +28,11 @@ use tari_comms::{ types::CommsPublicKey, }; use tari_comms_dht::DhtActorError; +use tari_dan_common_types::TemplateId; +use tari_dan_engine::state::models::{SchemaState, StateOpLogEntry}; use crate::{ - models::{Node, SchemaState, SideChainBlock, StateOpLogEntry, TemplateId, TreeNodeHash}, + models::{Node, SideChainBlock, TreeNodeHash}, services::infrastructure_services::NodeAddressable, }; diff --git a/dan_layer/core/src/services/wallet_client.rs b/dan_layer/core/src/services/wallet_client.rs index f4344aa26e..3ed857c6b6 100644 --- a/dan_layer/core/src/services/wallet_client.rs +++ b/dan_layer/core/src/services/wallet_client.rs @@ -22,8 +22,9 @@ use async_trait::async_trait; use tari_common_types::types::{FixedHash, PublicKey, Signature}; +use tari_dan_engine::state::models::StateRoot; -use crate::{models::StateRoot, DigitalAssetError}; +use crate::DigitalAssetError; #[async_trait] pub trait WalletClient: Send + Sync { diff --git a/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs b/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs index 78b28c3666..81deb6e1dc 100644 --- a/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs +++ b/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs @@ -27,12 +27,13 @@ use std::{ }; use log::*; +use tari_dan_common_types::storage::UnitOfWorkTracker; +use tari_dan_engine::instructions::Instruction; use crate::{ - models::{Instruction, Node, QuorumCertificate, TreeNodeHash}, + models::{Node, QuorumCertificate, TreeNodeHash}, storage::{ chain::{db_node::DbNode, ChainDbBackendAdapter, DbInstruction, DbQc}, - unit_of_work_tracker::UnitOfWorkTracker, StorageError, }, }; diff --git a/dan_layer/core/src/storage/chain/db_instruction.rs b/dan_layer/core/src/storage/chain/db_instruction.rs index 2cad7357d8..d8756cb2e2 100644 --- a/dan_layer/core/src/storage/chain/db_instruction.rs +++ b/dan_layer/core/src/storage/chain/db_instruction.rs @@ -20,7 +20,9 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::models::{Instruction, TreeNodeHash}; +use tari_dan_engine::instructions::Instruction; + +use crate::models::TreeNodeHash; #[derive(Debug, Clone)] pub struct DbInstruction { diff --git a/dan_layer/core/src/storage/db_factory.rs b/dan_layer/core/src/storage/db_factory.rs index c4458e18dc..543ae4c892 100644 --- a/dan_layer/core/src/storage/db_factory.rs +++ b/dan_layer/core/src/storage/db_factory.rs @@ -21,11 +21,11 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use tari_common_types::types::FixedHash; +use tari_dan_engine::state::{StateDb, StateDbBackendAdapter}; use crate::storage::{ chain::{ChainDb, ChainDbBackendAdapter}, global::{GlobalDb, GlobalDbBackendAdapter}, - state::{StateDb, StateDbBackendAdapter}, StorageError, }; diff --git a/dan_layer/core/src/storage/error.rs b/dan_layer/core/src/storage/error.rs index 8fc2705705..8733a78a36 100644 --- a/dan_layer/core/src/storage/error.rs +++ b/dan_layer/core/src/storage/error.rs @@ -23,7 +23,6 @@ use std::{io, sync::PoisonError}; use lmdb_zero as lmdb; -use tari_mmr::error::MerkleMountainRangeError; use tari_storage::lmdb_store::LMDBError; #[derive(Debug, thiserror::Error)] @@ -36,8 +35,6 @@ pub enum StorageError { LmdbError(#[from] lmdb::Error), #[error("LMDB Error: {0}")] LMDBError(#[from] LMDBError), - #[error("Decode Error: {0}")] - DecodeError(#[from] bytecodec::Error), #[error("Query error:{reason}")] QueryError { reason: String }, #[error("Migration error: {reason}")] @@ -48,8 +45,7 @@ pub enum StorageError { NotFound, #[error("File system path does not exist")] FileSystemPathDoesNotExist, - #[error("Merkle error:{0}")] - MerkleMountainRangeError(#[from] MerkleMountainRangeError), + #[error("General storage error: {details}")] General { details: String }, #[error("Lock error")] diff --git a/dan_layer/core/src/storage/lmdb/asset_db.rs b/dan_layer/core/src/storage/lmdb/asset_db.rs deleted file mode 100644 index d7b79bfe50..0000000000 --- a/dan_layer/core/src/storage/lmdb/asset_db.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// A database for each asset (per network) -pub struct AssetDb {} diff --git a/dan_layer/core/src/storage/lmdb/helpers.rs b/dan_layer/core/src/storage/lmdb/helpers.rs deleted file mode 100644 index 940425470a..0000000000 --- a/dan_layer/core/src/storage/lmdb/helpers.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2021, The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use std::path::Path; - -use lmdb_zero::db; -use tari_storage::lmdb_store::{LMDBBuilder, LMDBConfig, LMDBStore}; - -use crate::storage::StorageError; - -const DATABASES: &[(&str, db::Flags)] = &[("metadata", db::INTEGERKEY)]; - -pub fn create_lmdb_store>(path: P, config: LMDBConfig) -> Result { - const CREATE_FLAG: db::Flags = db::CREATE; - - let mut lmdb_store = LMDBBuilder::new() - .set_path(path) - .set_env_config(config) - .set_max_number_of_databases(10); - - for (db_name, flags) in DATABASES { - lmdb_store = lmdb_store.add_database(db_name, CREATE_FLAG | *flags); - } - - let lmdb_store = lmdb_store.build()?; - Ok(lmdb_store) -} diff --git a/dan_layer/core/src/storage/lmdb/lmdb_asset_backend.rs b/dan_layer/core/src/storage/lmdb/lmdb_asset_backend.rs deleted file mode 100644 index 8e1eb3282f..0000000000 --- a/dan_layer/core/src/storage/lmdb/lmdb_asset_backend.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use std::{fs, fs::File, path::Path, sync::Arc}; - -use lmdb_zero as lmdb; -use lmdb_zero::{put, ConstAccessor, LmdbResultExt, ReadTransaction, WriteAccessor, WriteTransaction}; -use tari_common::file_lock; -use tari_storage::lmdb_store::{DatabaseRef, LMDBConfig}; - -use crate::storage::{lmdb::helpers::create_lmdb_store, StorageError}; - -#[derive(Clone)] -pub struct LmdbAssetBackend { - _file_lock: Arc, - env: Arc, - metadata_db: DatabaseRef, -} - -impl LmdbAssetBackend { - pub(crate) fn initialize>(path: P, config: LMDBConfig) -> Result { - fs::create_dir_all(&path)?; - let file_lock = file_lock::try_lock_exclusive(path.as_ref())?; - let store = create_lmdb_store(path, config)?; - - Ok(Self { - _file_lock: Arc::new(file_lock), - env: store.env(), - metadata_db: store.get_handle("metadata").unwrap().db(), - }) - } - - pub fn read_transaction(&self) -> Result, StorageError> { - Ok(ReadTransaction::new(&*self.env)?) - } - - pub fn write_transaction(&self) -> Result, StorageError> { - Ok(WriteTransaction::new(&*self.env)?) - } - - pub fn get_metadata<'a>(&self, access: &'a ConstAccessor<'_>, key: u64) -> Result, StorageError> { - let val = access.get::<_, [u8]>(&*self.metadata_db, &key).to_opt()?; - Ok(val) - } - - pub fn replace_metadata( - &self, - access: &mut WriteAccessor<'_>, - key: u64, - metadata: &[u8], - ) -> Result<(), StorageError> { - access.put(&self.metadata_db, &key, metadata, put::Flags::empty())?; - Ok(()) - } -} diff --git a/dan_layer/core/src/storage/lmdb/lmdb_asset_store.rs b/dan_layer/core/src/storage/lmdb/lmdb_asset_store.rs deleted file mode 100644 index fab1bc9842..0000000000 --- a/dan_layer/core/src/storage/lmdb/lmdb_asset_store.rs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use std::path::Path; - -use bytecodec::{ - bincode_codec::{BincodeDecoder, BincodeEncoder}, - DecodeExt, - EncodeExt, -}; -use lmdb_zero::ConstAccessor; -use patricia_tree::{ - node::{Node, NodeDecoder, NodeEncoder}, - PatriciaMap, -}; -use tari_storage::lmdb_store::LMDBConfig; - -use crate::{ - digital_assets_error::DigitalAssetError, - models::TokenId, - storage::{ - lmdb::{lmdb_asset_backend::LmdbAssetBackend, PATRICIA_MAP_KEY}, - AssetStore, - StorageError, - }, -}; - -pub struct LmdbAssetStore { - db: LmdbAssetBackend, - cached: Option>>, -} - -impl LmdbAssetStore { - pub fn initialize>(path: P, config: LMDBConfig) -> Result { - Ok(Self { - db: LmdbAssetBackend::initialize(path, config)?, - cached: None, - }) - } - - /// Returns the full persisted ParticiaMap of the metadata state. - fn load_map(&self, access: &ConstAccessor<'_>) -> Result>, StorageError> { - let map = self - .db - .get_metadata(access, PATRICIA_MAP_KEY)? - .map(decode_patricia_nodes) - .transpose()? - .unwrap_or_else(Node::root); - Ok(map.into()) - } -} - -impl AssetStore for LmdbAssetStore { - fn get_metadata(&mut self, token_id: &TokenId) -> Result>, DigitalAssetError> { - match &self.cached { - Some(cached) => { - let val = cached.get(token_id); - Ok(val.cloned()) - }, - None => { - let txn = self.db.read_transaction()?; - let map = self.load_map(&txn.access())?; - let val = map.get(token_id).cloned(); - self.cached = Some(map); - Ok(val) - }, - } - } - - fn replace_metadata(&mut self, token_id: &TokenId, value: &[u8]) -> Result<(), DigitalAssetError> { - let mut cached = self.cached.take(); - let txn = self.db.write_transaction()?; - { - let mut access = txn.access(); - if cached.is_none() { - cached = Some(self.load_map(&*access)?); - }; - let cached_ref = cached.as_mut().unwrap(); - cached_ref.insert(token_id, value.to_vec()); - let encoded = encode_patricia_map(cached_ref.clone()) - .map_err(|_| DigitalAssetError::MalformedMetadata("Failed to encode Patricia map".to_string()))?; - self.db.replace_metadata(&mut access, PATRICIA_MAP_KEY, &encoded)?; - } - txn.commit()?; - self.cached = cached; - - Ok(()) - } -} - -impl Clone for LmdbAssetStore { - fn clone(&self) -> Self { - Self { - db: self.db.clone(), - cached: None, - } - } -} -fn decode_patricia_nodes(bytes: &[u8]) -> Result, bytecodec::Error> -where for<'de> T: serde::Deserialize<'de> { - let mut decoder = NodeDecoder::new(BincodeDecoder::new()); - let nodes = decoder.decode_from_bytes(bytes)?; - Ok(nodes) -} - -fn encode_patricia_map(map: PatriciaMap) -> Result, bytecodec::Error> -where T: serde::Serialize { - let mut encoder = NodeEncoder::new(BincodeEncoder::new()); - let encoded = encoder.encode_into_bytes(map.into())?; - Ok(encoded) -} diff --git a/dan_layer/core/src/storage/lmdb/mod.rs b/dan_layer/core/src/storage/lmdb/mod.rs deleted file mode 100644 index 2f0e34e07e..0000000000 --- a/dan_layer/core/src/storage/lmdb/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2021, The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#[cfg(test)] -mod test; - -mod asset_db; -mod helpers; -mod lmdb_asset_backend; -mod lmdb_asset_store; - -pub use asset_db::AssetDb; -pub use lmdb_asset_backend::LmdbAssetBackend; -pub use lmdb_asset_store::LmdbAssetStore; - -const PATRICIA_MAP_KEY: u64 = 1u64; diff --git a/dan_layer/core/src/storage/lmdb/test.rs b/dan_layer/core/src/storage/lmdb/test.rs deleted file mode 100644 index fb6548cd5e..0000000000 --- a/dan_layer/core/src/storage/lmdb/test.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2021, The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use std::fs; - -use tari_test_utils::paths; - -use crate::{ - models::TokenId, - storage::{lmdb::lmdb_asset_store::LmdbAssetStore, AssetStore}, -}; - -fn with_store(f: F) { - let path = paths::create_temporary_data_path(); - let store = LmdbAssetStore::initialize(&path, Default::default()).unwrap(); - f(store); - // TODO: This will not happen on panic - fs::remove_dir_all(path).unwrap(); -} - -#[test] -fn it_replaces_the_metadata() { - with_store(|mut store| { - store.replace_metadata(&TokenId(b"123".to_vec()), &[4, 5, 6]).unwrap(); - let metadata = store.get_metadata(&TokenId(b"123".to_vec())).unwrap().unwrap(); - assert_eq!(metadata, vec![4, 5, 6]); - - store.replace_metadata(&TokenId(b"123".to_vec()), &[5, 6, 7]).unwrap(); - let metadata = store.get_metadata(&TokenId(b"123".to_vec())).unwrap().unwrap(); - assert_eq!(metadata, vec![5, 6, 7]); - }); -} - -#[test] -fn it_returns_none_if_key_does_not_exist() { - with_store(|mut store| { - let metadata = store.get_metadata(&TokenId(b"123".to_vec())).unwrap(); - assert!(metadata.is_none()); - }); -} diff --git a/dan_layer/core/src/storage/mocks/mod.rs b/dan_layer/core/src/storage/mocks/mod.rs index 7c5fc12496..e8f7ce4a19 100644 --- a/dan_layer/core/src/storage/mocks/mod.rs +++ b/dan_layer/core/src/storage/mocks/mod.rs @@ -22,7 +22,6 @@ pub mod chain_db; pub mod global_db; -pub mod state_db; use std::{ collections::HashMap, @@ -30,16 +29,12 @@ use std::{ }; use tari_common_types::types::FixedHash; +use tari_dan_engine::state::{mocks::state_db::MockStateDbBackupAdapter, StateDb}; use crate::storage::{ chain::{ChainDb, DbInstruction, DbNode, DbQc}, global::GlobalDb, - mocks::{ - chain_db::MockChainDbBackupAdapter, - global_db::MockGlobalDbBackupAdapter, - state_db::MockStateDbBackupAdapter, - }, - state::StateDb, + mocks::{chain_db::MockChainDbBackupAdapter, global_db::MockGlobalDbBackupAdapter}, DbFactory, StorageError, }; diff --git a/dan_layer/core/src/storage/mocks/state_db.rs b/dan_layer/core/src/storage/mocks/state_db.rs deleted file mode 100644 index 2ca153cec0..0000000000 --- a/dan_layer/core/src/storage/mocks/state_db.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2022, The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use patricia_tree::PatriciaMap; - -use crate::storage::{ - state::{DbKeyValue, DbStateOpLogEntry, StateDbBackendAdapter}, - StorageError, -}; - -#[derive(Debug, Clone, Default)] -pub struct MockStateDbBackupAdapter; - -impl StateDbBackendAdapter for MockStateDbBackupAdapter { - type BackendTransaction = (); - type Error = StorageError; - - fn create_transaction(&self) -> Result { - todo!() - } - - fn update_key_value( - &self, - _schema: &str, - _key: &[u8], - _value: &[u8], - _tx: &Self::BackendTransaction, - ) -> Result<(), Self::Error> { - todo!() - } - - fn get(&self, _schema: &str, _key: &[u8]) -> Result>, Self::Error> { - todo!() - } - - fn find_keys_by_value(&self, _schema: &str, _value: &[u8]) -> Result>, Self::Error> { - todo!() - } - - fn commit(&self, _tx: &Self::BackendTransaction) -> Result<(), Self::Error> { - todo!() - } - - fn get_current_state_tree(&self, _tx: &Self::BackendTransaction) -> Result>, Self::Error> { - todo!() - } - - fn set_current_state_tree( - &self, - _tree: PatriciaMap>, - _tx: &Self::BackendTransaction, - ) -> Result<(), Self::Error> { - todo!() - } - - fn get_all_schemas(&self, _tx: &Self::BackendTransaction) -> Result, Self::Error> { - todo!() - } - - fn get_all_values_for_schema( - &self, - _schema: &str, - _tx: &Self::BackendTransaction, - ) -> Result, Self::Error> { - todo!() - } - - fn get_state_op_logs_by_height( - &self, - _height: u64, - _tx: &Self::BackendTransaction, - ) -> Result, Self::Error> { - todo!() - } - - fn add_state_oplog_entry( - &self, - _entry: DbStateOpLogEntry, - _tx: &Self::BackendTransaction, - ) -> Result<(), Self::Error> { - todo!() - } - - fn clear_all_state(&self, _tx: &Self::BackendTransaction) -> Result<(), Self::Error> { - todo!() - } -} diff --git a/dan_layer/core/src/storage/mod.rs b/dan_layer/core/src/storage/mod.rs index 03a87e3cf7..5f085f3f03 100644 --- a/dan_layer/core/src/storage/mod.rs +++ b/dan_layer/core/src/storage/mod.rs @@ -22,19 +22,14 @@ pub use chain_storage_service::ChainStorageService; pub use error::StorageError; -pub use lmdb::{LmdbAssetBackend, LmdbAssetStore}; pub use store::{AssetDataStore, AssetStore}; pub mod chain; mod chain_storage_service; mod db_factory; mod error; pub mod global; -pub mod lmdb; -pub mod state; mod store; -mod unit_of_work_tracker; pub use db_factory::DbFactory; -pub use unit_of_work_tracker::UnitOfWorkTracker; pub mod mocks; diff --git a/dan_layer/core/src/storage/state/db_key_value.rs b/dan_layer/core/src/storage/state/db_key_value.rs deleted file mode 100644 index 496b53554b..0000000000 --- a/dan_layer/core/src/storage/state/db_key_value.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#[derive(Debug, Clone)] -pub struct DbKeyValue { - pub schema: String, - pub key: Vec, - pub value: Vec, -} diff --git a/dan_layer/core/src/storage/state/mod.rs b/dan_layer/core/src/storage/state/mod.rs deleted file mode 100644 index 00eaeb630a..0000000000 --- a/dan_layer/core/src/storage/state/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -mod state_db_unit_of_work; -pub use state_db_unit_of_work::{StateDbUnitOfWork, StateDbUnitOfWorkImpl, StateDbUnitOfWorkReader, UnitOfWorkContext}; - -mod db_key_value; -pub use db_key_value::DbKeyValue; - -mod state_db; -pub use state_db::StateDb; - -mod state_db_backend_adapter; -pub use state_db_backend_adapter::StateDbBackendAdapter; - -mod state_op_log; -pub use state_op_log::{DbStateOpLogEntry, DbStateOperation}; diff --git a/dan_layer/core/src/storage/state/state_db.rs b/dan_layer/core/src/storage/state/state_db.rs deleted file mode 100644 index 68fd97051e..0000000000 --- a/dan_layer/core/src/storage/state/state_db.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use tari_common_types::types::FixedHash; - -use crate::storage::state::{ - state_db_unit_of_work::{StateDbUnitOfWorkImpl, StateDbUnitOfWorkReader, UnitOfWorkContext}, - StateDbBackendAdapter, -}; - -pub struct StateDb { - backend_adapter: TStateDbBackendAdapter, - contract_id: FixedHash, -} - -impl StateDb { - pub fn new(contract_id: FixedHash, backend_adapter: TStateDbBackendAdapter) -> Self { - Self { - backend_adapter, - contract_id, - } - } - - pub fn new_unit_of_work(&self, height: u64) -> StateDbUnitOfWorkImpl { - StateDbUnitOfWorkImpl::new( - UnitOfWorkContext::new(height, self.contract_id), - self.backend_adapter.clone(), - ) - } - - pub fn reader(&self) -> impl StateDbUnitOfWorkReader { - // TODO: A reader doesnt need the current context, should perhaps make a read-only implementation that the - // writable implementation also uses - StateDbUnitOfWorkImpl::new( - UnitOfWorkContext::new(0, self.contract_id), - self.backend_adapter.clone(), - ) - } -} diff --git a/dan_layer/core/src/storage/state/state_db_backend_adapter.rs b/dan_layer/core/src/storage/state/state_db_backend_adapter.rs deleted file mode 100644 index df8b0080aa..0000000000 --- a/dan_layer/core/src/storage/state/state_db_backend_adapter.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use patricia_tree::PatriciaMap; - -use crate::storage::{ - state::{db_key_value::DbKeyValue, DbStateOpLogEntry}, - StorageError, -}; - -pub trait StateDbBackendAdapter: Send + Sync + Clone { - type BackendTransaction; - type Error: Into; - - fn create_transaction(&self) -> Result; - fn update_key_value( - &self, - schema: &str, - key: &[u8], - value: &[u8], - tx: &Self::BackendTransaction, - ) -> Result<(), Self::Error>; - fn get(&self, schema: &str, key: &[u8]) -> Result>, Self::Error>; - fn find_keys_by_value(&self, schema: &str, value: &[u8]) -> Result>, Self::Error>; - fn commit(&self, tx: &Self::BackendTransaction) -> Result<(), Self::Error>; - fn get_current_state_tree(&self, tx: &Self::BackendTransaction) -> Result>, Self::Error>; - fn set_current_state_tree( - &self, - tree: PatriciaMap>, - tx: &Self::BackendTransaction, - ) -> Result<(), Self::Error>; - - fn get_all_schemas(&self, tx: &Self::BackendTransaction) -> Result, Self::Error>; - fn get_all_values_for_schema( - &self, - schema: &str, - tx: &Self::BackendTransaction, - ) -> Result, Self::Error>; - fn get_state_op_logs_by_height( - &self, - height: u64, - tx: &Self::BackendTransaction, - ) -> Result, Self::Error>; - fn add_state_oplog_entry(&self, entry: DbStateOpLogEntry, tx: &Self::BackendTransaction) - -> Result<(), Self::Error>; - fn clear_all_state(&self, tx: &Self::BackendTransaction) -> Result<(), Self::Error>; -} diff --git a/dan_layer/core/src/storage/state/state_op_log.rs b/dan_layer/core/src/storage/state/state_op_log.rs deleted file mode 100644 index 76c7a9b982..0000000000 --- a/dan_layer/core/src/storage/state/state_op_log.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2022, The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use std::str::FromStr; - -use crate::{models::TreeNodeHash, storage::state::DbKeyValue}; - -#[derive(Debug)] -pub struct DbStateOpLogEntry { - pub height: u64, - pub merkle_root: Option, - pub operation: DbStateOperation, - pub schema: String, - pub key: Vec, - pub value: Option>, -} - -impl DbStateOpLogEntry { - pub fn set_operation(height: u64, key_value: DbKeyValue) -> Self { - Self { - height, - merkle_root: None, - operation: DbStateOperation::Set, - schema: key_value.schema, - key: key_value.key, - value: Some(key_value.value), - } - } -} - -#[derive(Debug, Clone, Copy)] -pub enum DbStateOperation { - Set, - Delete, -} - -impl DbStateOperation { - pub fn as_op_str(&self) -> &str { - use DbStateOperation::{Delete, Set}; - match self { - Set => "S", - Delete => "D", - } - } -} - -impl FromStr for DbStateOperation { - type Err = (); - - fn from_str(s: &str) -> Result { - use DbStateOperation::{Delete, Set}; - match s { - "S" => Ok(Set), - "D" => Ok(Delete), - _ => Err(()), - } - } -} diff --git a/dan_layer/core/src/storage/unit_of_work_tracker.rs b/dan_layer/core/src/storage/unit_of_work_tracker.rs deleted file mode 100644 index 6431d97307..0000000000 --- a/dan_layer/core/src/storage/unit_of_work_tracker.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - RwLock, - RwLockReadGuard, - RwLockWriteGuard, -}; - -#[derive(Debug)] -pub struct UnitOfWorkTracker { - item: Arc>, - is_dirty: Arc, -} - -impl Clone for UnitOfWorkTracker { - fn clone(&self) -> Self { - Self { - item: self.item.clone(), - is_dirty: self.is_dirty.clone(), - } - } -} - -impl UnitOfWorkTracker { - pub fn new(item: TItem, is_dirty: bool) -> Self { - Self { - item: Arc::new(RwLock::new(item)), - is_dirty: Arc::new(AtomicBool::new(is_dirty)), - } - } - - pub fn get(&self) -> RwLockReadGuard { - self.item.read().unwrap() - } - - pub fn get_mut(&self) -> RwLockWriteGuard { - self.is_dirty.store(true, Ordering::SeqCst); - self.item.write().unwrap() - } - - pub fn is_dirty(&self) -> bool { - self.is_dirty.load(Ordering::SeqCst) - } -} diff --git a/dan_layer/core/src/template_command.rs b/dan_layer/core/src/template_command.rs index 0264b304a3..2f1b1431d3 100644 --- a/dan_layer/core/src/template_command.rs +++ b/dan_layer/core/src/template_command.rs @@ -20,7 +20,9 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{digital_assets_error::DigitalAssetError, storage::state::StateDbUnitOfWork}; +use tari_dan_engine::state::StateDbUnitOfWork; + +use crate::digital_assets_error::DigitalAssetError; pub trait TemplateCommand { fn try_execute( diff --git a/dan_layer/core/src/templates/tip002_template.rs b/dan_layer/core/src/templates/tip002_template.rs index 0c54aeb3ab..26146720da 100644 --- a/dan_layer/core/src/templates/tip002_template.rs +++ b/dan_layer/core/src/templates/tip002_template.rs @@ -23,14 +23,14 @@ use prost::Message; use tari_common_types::types::PublicKey; use tari_core::transactions::transaction_components::TemplateParameter; -use tari_dan_common_types::proto::tips::tip002; +use tari_dan_common_types::{proto::tips::tip002, TemplateId}; +use tari_dan_engine::{ + instructions::Instruction, + state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}, +}; use tari_utilities::{hex::Hex, ByteArray}; -use crate::{ - models::{Instruction, InstructionSet, TemplateId}, - storage::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}, - DigitalAssetError, -}; +use crate::{models::InstructionSet, DigitalAssetError}; pub fn initial_instructions(template_param: &TemplateParameter) -> InstructionSet { InstructionSet::from_vec(vec![Instruction::new( diff --git a/dan_layer/core/src/templates/tip004_template.rs b/dan_layer/core/src/templates/tip004_template.rs index 22a484b8dc..028c23fc84 100644 --- a/dan_layer/core/src/templates/tip004_template.rs +++ b/dan_layer/core/src/templates/tip004_template.rs @@ -26,13 +26,10 @@ use prost::Message; use tari_core::transactions::transaction_components::TemplateParameter; use tari_crypto::common::Blake256; use tari_dan_common_types::proto::tips::tip004; +use tari_dan_engine::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}; use tari_utilities::hex::Hex; -use crate::{ - models::InstructionSet, - storage::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}, - DigitalAssetError, -}; +use crate::{models::InstructionSet, DigitalAssetError}; const LOG_TARGET: &str = "tari::dan_layer::core::templates::tip004_template"; diff --git a/dan_layer/core/src/templates/tip721_template.rs b/dan_layer/core/src/templates/tip721_template.rs index c35312dd94..8ab09bf29e 100644 --- a/dan_layer/core/src/templates/tip721_template.rs +++ b/dan_layer/core/src/templates/tip721_template.rs @@ -24,13 +24,10 @@ use log::*; use prost::Message; use tari_core::transactions::transaction_components::TemplateParameter; use tari_dan_common_types::proto::tips::tip721; +use tari_dan_engine::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}; use tari_utilities::{hex::Hex, ByteArray}; -use crate::{ - models::InstructionSet, - storage::state::{StateDbUnitOfWork, StateDbUnitOfWorkReader}, - DigitalAssetError, -}; +use crate::{models::InstructionSet, DigitalAssetError}; const LOG_TARGET: &str = "tari::dan_layer::core::templates::tip721_template"; diff --git a/dan_layer/core/src/workers/consensus_worker.rs b/dan_layer/core/src/workers/consensus_worker.rs index 487e0ca585..633f9ce6c8 100644 --- a/dan_layer/core/src/workers/consensus_worker.rs +++ b/dan_layer/core/src/workers/consensus_worker.rs @@ -27,6 +27,7 @@ use std::sync::{ use log::*; use tari_common_types::types::PublicKey; +use tari_dan_engine::state::{StateDbUnitOfWork, StateDbUnitOfWorkImpl, StateDbUnitOfWorkReader}; use tari_shutdown::ShutdownSignal; use tokio::time::Duration; @@ -36,7 +37,6 @@ use crate::{ services::{CheckpointManager, CommitteeManager, EventsPublisher, PayloadProvider, ServiceSpecification}, storage::{ chain::{ChainDb, ChainDbUnitOfWork}, - state::{StateDbUnitOfWork, StateDbUnitOfWorkImpl, StateDbUnitOfWorkReader}, DbFactory, }, workers::{states, states::ConsensusWorkerStateEvent}, diff --git a/dan_layer/core/src/workers/state_sync/error.rs b/dan_layer/core/src/workers/state_sync/error.rs index 6a68292dba..c336e17fe1 100644 --- a/dan_layer/core/src/workers/state_sync/error.rs +++ b/dan_layer/core/src/workers/state_sync/error.rs @@ -20,6 +20,8 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use tari_dan_engine::state::error::StateStorageError; + use crate::{services::ValidatorNodeClientError, storage::StorageError}; #[derive(Debug, thiserror::Error)] @@ -30,6 +32,8 @@ pub enum StateSyncError { NoOtherCommitteeMembersToSync, #[error("Storage error: {0}")] StorageError(#[from] StorageError), + #[error("State storage error: {0}")] + StateStorageError(#[from] StateStorageError), #[error("Invalid state Merkle root")] InvalidStateMerkleRoot, #[error("Remote peer does not have tip node")] diff --git a/dan_layer/core/src/workers/state_sync/mod.rs b/dan_layer/core/src/workers/state_sync/mod.rs index e9feea43ee..9aba7e7b54 100644 --- a/dan_layer/core/src/workers/state_sync/mod.rs +++ b/dan_layer/core/src/workers/state_sync/mod.rs @@ -25,15 +25,18 @@ pub use error::StateSyncError; use log::*; use rand::{rngs::OsRng, seq::SliceRandom}; use tari_common_types::types::PublicKey; +use tari_dan_engine::state::{ + error::StateStorageError, + StateDb, + StateDbBackendAdapter, + StateDbUnitOfWork, + StateDbUnitOfWorkReader, +}; use tari_utilities::hex::Hex; use crate::{ models::CheckpointOutput, services::{ValidatorNodeClientFactory, ValidatorNodeRpcClient}, - storage::{ - state::{StateDb, StateDbBackendAdapter, StateDbUnitOfWork, StateDbUnitOfWorkReader}, - StorageError, - }, }; const LOG_TARGET: &str = "tari::dan::workers::state_sync"; @@ -128,8 +131,8 @@ where } // TODO: Check merkle root before commit - uow.clear_all_state().map_err(StorageError::from)?; - uow.commit().map_err(StorageError::from)?; + uow.clear_all_state().map_err(StateStorageError::from)?; + uow.commit().map_err(StateStorageError::from)?; let merkle_root = uow.calculate_root()?; if self.last_checkpoint.merkle_root.as_slice() != merkle_root.as_bytes() { diff --git a/dan_layer/core/src/workers/states/next_view.rs b/dan_layer/core/src/workers/states/next_view.rs index 25c94fd677..6f07ab3bee 100644 --- a/dan_layer/core/src/workers/states/next_view.rs +++ b/dan_layer/core/src/workers/states/next_view.rs @@ -23,11 +23,12 @@ use std::marker::PhantomData; use log::*; +use tari_dan_engine::state::models::StateRoot; use tari_shutdown::ShutdownSignal; use crate::{ digital_assets_error::DigitalAssetError, - models::{AssetDefinition, Committee, HotStuffMessage, HotStuffTreeNode, QuorumCertificate, StateRoot, View}, + models::{AssetDefinition, Committee, HotStuffMessage, HotStuffTreeNode, QuorumCertificate, View}, services::{infrastructure_services::OutboundService, PayloadProvider, ServiceSpecification}, storage::DbFactory, workers::states::ConsensusWorkerStateEvent, diff --git a/dan_layer/core/src/workers/states/prepare.rs b/dan_layer/core/src/workers/states/prepare.rs index 7d3f51fc04..24aba6c7e1 100644 --- a/dan_layer/core/src/workers/states/prepare.rs +++ b/dan_layer/core/src/workers/states/prepare.rs @@ -24,6 +24,7 @@ use std::{collections::HashMap, time::Duration}; use log::*; use tari_common_types::types::FixedHash; +use tari_dan_engine::state::StateDbUnitOfWork; use tokio::time::sleep; use crate::{ @@ -46,7 +47,7 @@ use crate::{ ServiceSpecification, SigningService, }, - storage::{chain::ChainDbUnitOfWork, state::StateDbUnitOfWork, ChainStorageService, DbFactory, StorageError}, + storage::{chain::ChainDbUnitOfWork, ChainStorageService, DbFactory, StorageError}, workers::states::ConsensusWorkerStateEvent, }; diff --git a/dan_layer/core/src/workers/states/synchronizing.rs b/dan_layer/core/src/workers/states/synchronizing.rs index 7852adacf7..d94f12553a 100644 --- a/dan_layer/core/src/workers/states/synchronizing.rs +++ b/dan_layer/core/src/workers/states/synchronizing.rs @@ -25,11 +25,12 @@ use std::{convert::TryFrom, marker::PhantomData}; use log::*; use tari_comms::types::CommsPublicKey; use tari_core::transactions::transaction_components::OutputType; +use tari_dan_engine::state::StateDbUnitOfWorkReader; use crate::{ models::{AssetDefinition, CheckpointOutput}, services::{BaseNodeClient, ServiceSpecification}, - storage::{state::StateDbUnitOfWorkReader, DbFactory}, + storage::DbFactory, workers::{state_sync::StateSynchronizer, states::ConsensusWorkerStateEvent}, DigitalAssetError, }; diff --git a/dan_layer/engine/Cargo.toml b/dan_layer/engine/Cargo.toml new file mode 100644 index 0000000000..c7ecbe91a4 --- /dev/null +++ b/dan_layer/engine/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "tari_dan_engine" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tari_common_types = {path = "../../base_layer/common_types"} +tari_dan_common_types = {path = "../common_types"} +tari_mmr = { path = "../../base_layer/mmr" } +tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.4" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.14.0" } + +wasmer = "2.2.1" +digest = "0.9.0" +d3ne = { git="https://github.com/stringhandler/d3ne-rs.git", branch="st-fixes2"} +anyhow = "1.0.53" +serde = "1.0.126" +log = { version = "0.4.8", features = ["std"] } +serde_json ="1.0.81" +thiserror = "^1.0.20" diff --git a/dan_layer/engine/src/flow/error.rs b/dan_layer/engine/src/flow/error.rs new file mode 100644 index 0000000000..60d9eec06e --- /dev/null +++ b/dan_layer/engine/src/flow/error.rs @@ -0,0 +1,9 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use thiserror::Error; +#[derive(Debug, Error)] +pub enum FlowEngineError { + #[error("The instruction execution failed: Inner error:{inner}")] + InstructionFailed { inner: String }, +} diff --git a/dan_layer/engine/src/flow/flow_factory.rs b/dan_layer/engine/src/flow/flow_factory.rs new file mode 100644 index 0000000000..02ba0fffd2 --- /dev/null +++ b/dan_layer/engine/src/flow/flow_factory.rs @@ -0,0 +1,48 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::collections::HashMap; + +use d3ne::WorkersBuilder; + +use crate::{ + flow::{FlowEngineError, FlowInstance}, + function_definitions::{FlowFunctionDefinition, FunctionArgDefinition}, + instructions::Instruction, + state::StateDbUnitOfWork, +}; + +#[derive(Clone, Default)] +pub struct FlowFactory { + flows: HashMap, FlowInstance)>, +} +impl FlowFactory { + pub fn new(flow_functions: &[FlowFunctionDefinition]) -> Self { + let mut flows = HashMap::new(); + for func_def in flow_functions { + // build_instance(&mut instance, &func_def); + flows.insert( + func_def.name.clone(), + ( + func_def.args.clone(), + FlowInstance::try_build(func_def.flow.clone(), WorkersBuilder::new().build()) + .expect("Could not build flow"), + ), + ); + } + Self { flows } + } + + pub fn invoke_write_method( + &self, + name: String, + instruction: &Instruction, + state_db: TUnitOfWork, + ) -> Result { + if let Some((args, engine)) = self.flows.get(&name) { + engine.process(instruction.args(), args, instruction.sender(), state_db) + } else { + todo!("could not find engine") + } + } +} diff --git a/dan_layer/engine/src/flow/flow_instance.rs b/dan_layer/engine/src/flow/flow_instance.rs new file mode 100644 index 0000000000..8c89ebbae8 --- /dev/null +++ b/dan_layer/engine/src/flow/flow_instance.rs @@ -0,0 +1,127 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::{ + collections::HashMap, + ops::Deref, + sync::{Arc, RwLock}, +}; + +use d3ne::{Engine, Node, Workers, WorkersBuilder}; +use serde_json::Value as JsValue; +use tari_common_types::types::PublicKey; +use tari_utilities::ByteArray; + +use crate::{ + flow::{ + workers::{ + ArgWorker, + CreateBucketWorker, + HasRoleWorker, + MintBucketWorker, + SenderWorker, + StartWorker, + StoreBucketWorker, + TextWorker, + }, + ArgValue, + FlowEngineError, + }, + function_definitions::{ArgType, FunctionArgDefinition}, + state::StateDbUnitOfWork, +}; + +#[derive(Clone, Debug)] +pub struct FlowInstance { + // engine: Engine, + // TODO: engine is not Send so can't be added here + // process: JsValue, + start_node: i64, + nodes: HashMap, +} + +impl FlowInstance { + pub fn try_build(value: JsValue, workers: Workers) -> Result { + let engine = Engine::new("tari@0.1.0", workers); + // dbg!(&value); + let nodes = engine.parse_value(value).expect("could not create engine"); + Ok(FlowInstance { + // process: value, + nodes, + start_node: 1, + }) + } + + pub fn process( + &self, + args: &[u8], + arg_defs: &[FunctionArgDefinition], + sender: PublicKey, + state_db: TUnitOfWork, + ) -> Result { + let mut engine_args = HashMap::new(); + + let mut remaining_args = Vec::from(args); + for ad in arg_defs { + let value = match ad.arg_type { + ArgType::String => { + let length = remaining_args.pop().expect("no more args: len") as usize; + let s_bytes: Vec = remaining_args.drain(0..length).collect(); + let s = String::from_utf8(s_bytes).expect("could not convert string"); + ArgValue::String(s) + }, + ArgType::Byte => ArgValue::Byte(remaining_args.pop().expect("No byte to read")), + ArgType::PublicKey => { + let bytes: Vec = remaining_args.drain(0..32).collect(); + let pk = PublicKey::from_bytes(&bytes).expect("Not a valid public key"); + ArgValue::PublicKey(pk) + }, + ArgType::Uint => { + let bytes: Vec = remaining_args.drain(0..8).collect(); + let mut fixed: [u8; 8] = [0u8; 8]; + fixed.copy_from_slice(&bytes); + let value = u64::from_le_bytes(fixed); + ArgValue::Uint(value) + }, + }; + engine_args.insert(ad.name.clone(), value); + } + + let state_db = Arc::new(RwLock::new(state_db)); + let engine = Engine::new("tari@0.1.0", load_workers(engine_args, sender, state_db.clone())); + let output = engine.process(&self.nodes, self.start_node); + let _od = output.expect("engine process failed"); + // if let Some(err) = od.get("error") { + // match err { + // Ok(_) => todo!("Unexpected Ok result returned from error"), + // Err(e) => { + // return Err(FlowEngineError::InstructionFailed { inner: e.to_string() }); + // }, + // } + // } + let inner = state_db.read().map(|s| s.deref().clone()).unwrap(); + Ok(inner) + } +} + +fn load_workers( + args: HashMap, + sender: PublicKey, + state_db: Arc>, +) -> Workers { + let mut workers = WorkersBuilder::new(); + workers.add(StartWorker {}); + workers.add(CreateBucketWorker { + state_db: state_db.clone(), + }); + workers.add(StoreBucketWorker { + state_db: state_db.clone(), + }); + workers.add(ArgWorker { args: args.clone() }); + workers.add(ArgWorker { args }); + workers.add(SenderWorker { sender }); + workers.add(TextWorker {}); + workers.add(HasRoleWorker { state_db }); + workers.add(MintBucketWorker {}); + workers.build() +} diff --git a/dan_layer/engine/src/flow/mod.rs b/dan_layer/engine/src/flow/mod.rs new file mode 100644 index 0000000000..96a826171a --- /dev/null +++ b/dan_layer/engine/src/flow/mod.rs @@ -0,0 +1,33 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +pub mod error; +mod flow_factory; +mod flow_instance; +pub mod workers; + +use std::any::Any; + +pub use error::FlowEngineError; +pub use flow_factory::FlowFactory; +pub use flow_instance::FlowInstance; +use tari_common_types::types::PublicKey; + +#[derive(Clone, Debug)] +pub enum ArgValue { + String(String), + Byte(u8), + PublicKey(PublicKey), + Uint(u64), +} + +impl ArgValue { + pub fn into_any(self) -> Box { + match self { + ArgValue::String(s) => Box::new(s), + ArgValue::Byte(b) => Box::new(b), + ArgValue::PublicKey(k) => Box::new(k), + ArgValue::Uint(u) => Box::new(u), + } + } +} diff --git a/dan_layer/engine/src/flow/workers/arg_worker.rs b/dan_layer/engine/src/flow/workers/arg_worker.rs new file mode 100644 index 0000000000..2d9e896493 --- /dev/null +++ b/dan_layer/engine/src/flow/workers/arg_worker.rs @@ -0,0 +1,53 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::collections::HashMap; + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; +use tari_utilities::hex::Hex; + +use crate::flow::ArgValue; + +pub struct ArgWorker { + pub args: HashMap, +} + +impl Worker for ArgWorker { + // fn call(&self, node: Node, inputs: InputData) -> OutputData { + // let name = node.get_string_field("name", &inputs).unwrap(); + // let mut map = HashMap::new(); + // let value = self.args.get(&name).cloned().expect("could not find arg"); + // match value { + // ArgValue::Uint(x) => map.insert( + // "default".to_string(), + // Ok(IOData { + // data: Box::new(x as i64), + // }), + // ), + // ArgValue::PublicKey(pk) => map.insert( + // "default".to_string(), + // Ok(IOData { + // data: Box::new(pk.to_hex()), + // }), + // ), + // _ => todo!(), + // }; + // + // Rc::new(map) + // } + + fn name(&self) -> &str { + "tari::arg" + } + + fn work(&self, node: &Node, input_data: InputData) -> anyhow::Result { + let name = node.get_string_field("name", &input_data)?; + let value = self.args.get(&name).cloned().expect("could not find arg"); + let output = match value { + ArgValue::Uint(x) => OutputDataBuilder::new().data("default", Box::new(x as i64)), + ArgValue::PublicKey(pk) => OutputDataBuilder::new().data("default", Box::new(pk.to_hex())), + _ => todo!(), + }; + Ok(output.build()) + } +} diff --git a/dan_layer/engine/src/flow/workers/create_bucket_worker.rs b/dan_layer/engine/src/flow/workers/create_bucket_worker.rs new file mode 100644 index 0000000000..0b543ecacd --- /dev/null +++ b/dan_layer/engine/src/flow/workers/create_bucket_worker.rs @@ -0,0 +1,110 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::{ + convert::TryFrom, + sync::{Arc, RwLock}, +}; + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; +use tari_common_types::types::PublicKey; +use tari_utilities::{hex::Hex, ByteArray}; + +use crate::{models::Bucket, state::StateDbUnitOfWork}; + +pub struct CreateBucketWorker { + pub state_db: Arc>, +} + +impl Worker for CreateBucketWorker { + fn name(&self) -> &str { + "tari::create_bucket" + } + + fn work(&self, node: &Node, input_data: InputData) -> anyhow::Result { + // TODO: return proper errors.... + let amount = u64::try_from(node.get_number_field("amount", &input_data)?)?; + let token_id = u64::try_from(node.get_number_field("token_id", &input_data)?)?; + let asset_id = u64::try_from(node.get_number_field("asset_id", &input_data)?)?; + let from = PublicKey::from_hex(&node.get_string_field("from", &input_data)?).expect("Not a valid pub key"); + let mut state = self.state_db.write().unwrap(); + let balance_key = format!("token_id-{}-{}", asset_id, token_id); + let balance = state.get_u64(&balance_key, from.as_bytes())?.unwrap_or(0); + let new_balance = balance.checked_sub(amount).expect("Not enough funds to create bucket"); + state + .set_u64(&balance_key, from.as_bytes(), new_balance) + .expect("Could not save state"); + let output = OutputDataBuilder::new() + .data("default", Box::new(())) + .data("bucket", Box::new(Bucket::new(amount, token_id, asset_id))) + .build(); + Ok(output) + } + // let mut map = HashMap::new(); + // let amount = match node.get_number_field("amount", &inputs) { + // Ok(a) => a as u64, + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // let token_id = match node.get_number_field("token_id", &inputs) { + // Ok(a) => a as u64, + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // let asset_id = match node.get_number_field("asset_id", &inputs) { + // Ok(a) => a as u64, + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // let from = match node.get_string_field("from", &inputs) { + // Ok(a) => PublicKey::from_hex(&a).expect("Not a valid pub key"), + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // + // let mut state = self.state_db.write().unwrap(); + // let balance_key = format!("token_id-{}-{}", asset_id, token_id); + // let balance = match state.get_u64(&balance_key, from.as_bytes()) { + // Ok(b) => b.unwrap_or(0), + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err.into())); + // return Rc::new(err_map); + // }, + // }; + // + // let new_balance = match balance.checked_sub(amount) { + // Some(x) => x, + // None => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(anyhow!("Not enough funds to create bucket"))); + // return Rc::new(err_map); + // }, + // }; + // match state.set_u64(&balance_key, from.as_bytes(), new_balance) { + // Ok(_) => (), + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err.into())); + // return Rc::new(err_map); + // }, + // } + // + // let bucket = Bucket::new(amount, token_id, asset_id); + // map.insert("default".to_string(), Ok(IOData { data: Box::new(()) })); + // map.insert("bucket".to_string(), Ok(IOData { data: Box::new(bucket) })); + // Rc::new(map) + // } +} diff --git a/dan_layer/engine/src/flow/workers/has_role_worker.rs b/dan_layer/engine/src/flow/workers/has_role_worker.rs new file mode 100644 index 0000000000..df9bc9641e --- /dev/null +++ b/dan_layer/engine/src/flow/workers/has_role_worker.rs @@ -0,0 +1,42 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::sync::{Arc, RwLock}; + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; + +use crate::state::StateDbUnitOfWork; + +pub struct HasRoleWorker { + pub state_db: Arc>, +} +impl Worker for HasRoleWorker { + // fn call(&self, node: Node, inputs: InputData) -> OutputData { + // let _role = node.get_string_field("role", &inputs).unwrap(); + // + // let _pubkey = match node.get_string_field("pubkey", &inputs) { + // Ok(a) => PublicKey::from_hex(&a).expect("Not a valid pub key"), + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // + // // let state = self.state_db.read().expect("Could not get lock on data"); + // // state.get_value() + // // TODO: read roles from db + // let mut map = HashMap::new(); + // map.insert("default".to_string(), Ok(IOData { data: Box::new(()) })); + // Rc::new(map) + // } + + fn name(&self) -> &str { + "tari::has_role" + } + + fn work(&self, node: &Node, input_data: InputData) -> anyhow::Result { + let _role = node.get_string_field("role", &input_data)?; + Ok(OutputDataBuilder::new().data("default", Box::new(())).build()) + } +} diff --git a/dan_layer/engine/src/flow/workers/mint_bucket_worker.rs b/dan_layer/engine/src/flow/workers/mint_bucket_worker.rs new file mode 100644 index 0000000000..001f329f12 --- /dev/null +++ b/dan_layer/engine/src/flow/workers/mint_bucket_worker.rs @@ -0,0 +1,61 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::convert::TryFrom; + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; + +use crate::models::Bucket; + +pub struct MintBucketWorker {} + +impl Worker for MintBucketWorker { + // fn call(&self, node: Node, inputs: InputData) -> OutputData { + // let mut map = HashMap::new(); + // let amount = match node.get_number_field("amount", &inputs) { + // Ok(a) => a as u64, + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // let token_id = match node.get_number_field("token_id", &inputs) { + // Ok(a) => a as u64, + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // + // let asset_id = match node.get_number_field("asset_id", &inputs) { + // Ok(a) => a as u64, + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // let bucket = Bucket::new(amount, token_id, asset_id); + // map.insert("default".to_string(), Ok(IOData { data: Box::new(()) })); + // map.insert("bucket".to_string(), Ok(IOData { data: Box::new(bucket) })); + // Rc::new(map) + // } + + fn name(&self) -> &str { + "tari::mint_bucket" + } + + fn work(&self, node: &Node, inputs: InputData) -> anyhow::Result { + let amount = u64::try_from(node.get_number_field("amount", &inputs)?)?; + let token_id = u64::try_from(node.get_number_field("token_id", &inputs)?)?; + let asset_id = u64::try_from(node.get_number_field("asset_id", &inputs)?)?; + let bucket = Bucket::new(amount, token_id, asset_id); + let output = OutputDataBuilder::new() + .data("default", Box::new(())) + .data("bucket", Box::new(bucket)) + .build(); + Ok(output) + } +} diff --git a/dan_layer/engine/src/flow/workers/mod.rs b/dan_layer/engine/src/flow/workers/mod.rs new file mode 100644 index 0000000000..c44e88c458 --- /dev/null +++ b/dan_layer/engine/src/flow/workers/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause +mod arg_worker; +mod create_bucket_worker; +mod has_role_worker; +mod mint_bucket_worker; +mod sender_worker; +mod start_worker; +mod store_bucket_worker; +mod text_worker; + +pub use arg_worker::ArgWorker; +pub use create_bucket_worker::CreateBucketWorker; +pub use has_role_worker::HasRoleWorker; +pub use mint_bucket_worker::MintBucketWorker; +pub use sender_worker::SenderWorker; +pub use start_worker::StartWorker; +pub use store_bucket_worker::StoreBucketWorker; +pub use text_worker::TextWorker; diff --git a/dan_layer/engine/src/flow/workers/sender_worker.rs b/dan_layer/engine/src/flow/workers/sender_worker.rs new file mode 100644 index 0000000000..16f47b2745 --- /dev/null +++ b/dan_layer/engine/src/flow/workers/sender_worker.rs @@ -0,0 +1,33 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; +use tari_common_types::types::PublicKey; +use tari_utilities::hex::Hex; + +pub struct SenderWorker { + pub sender: PublicKey, +} + +impl Worker for SenderWorker { + // fn call(&self, _node: Node, _input: InputData) -> OutputData { + // let mut map = HashMap::new(); + // map.insert( + // "default".to_string(), + // Ok(IOData { + // data: Box::new(self.sender.to_hex()), + // }), + // ); + // Rc::new(map) + // } + + fn name(&self) -> &str { + "core::sender" + } + + fn work(&self, _node: &Node, _input_data: InputData) -> anyhow::Result { + Ok(OutputDataBuilder::new() + .data("default", Box::new(self.sender.to_hex())) + .build()) + } +} diff --git a/dan_layer/engine/src/flow/workers/start_worker.rs b/dan_layer/engine/src/flow/workers/start_worker.rs new file mode 100644 index 0000000000..3bb2fd2d93 --- /dev/null +++ b/dan_layer/engine/src/flow/workers/start_worker.rs @@ -0,0 +1,22 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; + +pub struct StartWorker {} + +impl Worker for StartWorker { + // fn call(&self, _node: Node, _inputs: InputData) -> OutputData { + // let mut map = HashMap::new(); + // map.insert("default".to_string(), Ok(IOData { data: Box::new(()) })); + // Rc::new(map) + // } + + fn name(&self) -> &str { + "core::start" + } + + fn work(&self, _node: &Node, _input_data: InputData) -> anyhow::Result { + Ok(OutputDataBuilder::new().data("default", Box::new(())).build()) + } +} diff --git a/dan_layer/engine/src/flow/workers/store_bucket_worker.rs b/dan_layer/engine/src/flow/workers/store_bucket_worker.rs new file mode 100644 index 0000000000..a625a6a0d9 --- /dev/null +++ b/dan_layer/engine/src/flow/workers/store_bucket_worker.rs @@ -0,0 +1,84 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::sync::{Arc, RwLock}; + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; +use tari_common_types::types::PublicKey; +use tari_utilities::{hex::Hex, ByteArray}; + +use crate::{models::Bucket, state::StateDbUnitOfWork}; + +pub struct StoreBucketWorker { + pub state_db: Arc>, +} + +impl Worker for StoreBucketWorker { + // fn call(&self, node: Node, inputs: InputData) -> OutputData { + // let mut map = HashMap::new(); + // let bucket: Bucket = match node.get_field_t("bucket", &inputs) { + // Ok(a) => a, + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // + // let to = match node.get_string_field("to", &inputs) { + // Ok(a) => PublicKey::from_hex(&a).expect("Not a valid pub key"), + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err)); + // return Rc::new(err_map); + // }, + // }; + // + // let mut state = self.state_db.write().unwrap(); + // let balance_key = format!("token_id-{}-{}", bucket.asset_id(), bucket.token_id()); + // let balance = match state.get_u64(&balance_key, to.as_bytes()) { + // Ok(b) => b.unwrap_or(0), + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err.into())); + // return Rc::new(err_map); + // }, + // }; + // match state.set_u64( + // &balance_key, + // to.as_bytes(), + // bucket.amount().checked_add(balance).expect("overflowed"), + // ) { + // Ok(_) => (), + // Err(err) => { + // let mut err_map = HashMap::new(); + // err_map.insert("error".to_string(), Err(err.into())); + // return Rc::new(err_map); + // }, + // } + // + // map.insert("default".to_string(), Ok(IOData { data: Box::new(()) })); + // // map.insert("bucket".to_string(), Ok(IOData { data: Box::new(bucket) })); + // Rc::new(map) + // } + + fn name(&self) -> &str { + "tari::store_bucket" + } + + fn work(&self, node: &Node, inputs: InputData) -> anyhow::Result { + let bucket: Bucket = serde_json::from_str(&node.get_string_field("bucket", &inputs)?)?; + let to = PublicKey::from_hex(&node.get_string_field("to", &inputs)?)?; + let mut state = self.state_db.write().unwrap(); + let balance_key = format!("token_id-{}-{}", bucket.asset_id(), bucket.token_id()); + let balance = state.get_u64(&balance_key, to.as_bytes())?.unwrap_or(0); + state.set_u64( + &balance_key, + to.as_bytes(), + bucket.amount().checked_add(balance).expect("overflowed"), + )?; + + let output = OutputDataBuilder::new().data("default", Box::new(())).build(); + Ok(output) + } +} diff --git a/dan_layer/engine/src/flow/workers/text_worker.rs b/dan_layer/engine/src/flow/workers/text_worker.rs new file mode 100644 index 0000000000..24e90379d0 --- /dev/null +++ b/dan_layer/engine/src/flow/workers/text_worker.rs @@ -0,0 +1,24 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use d3ne::{InputData, Node, OutputData, OutputDataBuilder, Worker}; + +pub struct TextWorker {} + +impl Worker for TextWorker { + // fn call(&self, node: Node, inputs: InputData) -> OutputData { + // let txt = node.get_string_field("txt", &inputs).unwrap(); + // let mut map = HashMap::new(); + // map.insert("txt".to_string(), Ok(IOData { data: Box::new(txt) })); + // Rc::new(map) + // } + + fn name(&self) -> &str { + "core::text" + } + + fn work(&self, node: &Node, input_data: InputData) -> anyhow::Result { + let txt = node.get_string_field("txt", &input_data)?; + Ok(OutputDataBuilder::new().data("txt", Box::new(txt)).build()) + } +} diff --git a/dan_layer/engine/src/function_definitions/flow_function_definition.rs b/dan_layer/engine/src/function_definitions/flow_function_definition.rs new file mode 100644 index 0000000000..0ac03e7fa9 --- /dev/null +++ b/dan_layer/engine/src/function_definitions/flow_function_definition.rs @@ -0,0 +1,13 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsValue; + +use crate::function_definitions::FunctionArgDefinition; + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct FlowFunctionDefinition { + pub name: String, + pub args: Vec, + pub flow: JsValue, +} diff --git a/dan_layer/engine/src/function_definitions/function_arg_definition.rs b/dan_layer/engine/src/function_definitions/function_arg_definition.rs new file mode 100644 index 0000000000..5d55835c01 --- /dev/null +++ b/dan_layer/engine/src/function_definitions/function_arg_definition.rs @@ -0,0 +1,20 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct FunctionArgDefinition { + pub name: String, + #[serde(rename = "type")] + pub arg_type: ArgType, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "snake_case")] +pub enum ArgType { + String, + Byte, + PublicKey, + Uint, +} diff --git a/dan_layer/engine/src/function_definitions/mod.rs b/dan_layer/engine/src/function_definitions/mod.rs new file mode 100644 index 0000000000..d0998b0528 --- /dev/null +++ b/dan_layer/engine/src/function_definitions/mod.rs @@ -0,0 +1,11 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +mod function_arg_definition; + +mod flow_function_definition; +mod wasm_function_definition; + +pub use flow_function_definition::FlowFunctionDefinition; +pub use function_arg_definition::{ArgType, FunctionArgDefinition}; +pub use wasm_function_definition::WasmFunctionDefinition; diff --git a/dan_layer/engine/src/function_definitions/wasm_function_definition.rs b/dan_layer/engine/src/function_definitions/wasm_function_definition.rs new file mode 100644 index 0000000000..c68f44a003 --- /dev/null +++ b/dan_layer/engine/src/function_definitions/wasm_function_definition.rs @@ -0,0 +1,13 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use serde::{Deserialize, Serialize}; + +use crate::function_definitions::FunctionArgDefinition; + +#[derive(Serialize, Deserialize, Default, Clone, Debug)] +pub struct WasmFunctionDefinition { + pub name: String, + pub args: Vec, + pub in_module: String, +} diff --git a/dan_layer/core/src/models/instruction.rs b/dan_layer/engine/src/instructions/instruction.rs similarity index 58% rename from dan_layer/core/src/models/instruction.rs rename to dan_layer/engine/src/instructions/instruction.rs index 3830fe7ca5..bda812423a 100644 --- a/dan_layer/core/src/models/instruction.rs +++ b/dan_layer/engine/src/instructions/instruction.rs @@ -1,34 +1,14 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause use std::fmt::{Display, Formatter}; use digest::Digest; use tari_common_types::types::{FixedHash, PublicKey}; use tari_crypto::common::Blake256; +use tari_dan_common_types::TemplateId; use tari_utilities::hex::Hex; -use crate::models::TemplateId; - #[derive(Clone, Debug)] pub struct Instruction { template_id: TemplateId, diff --git a/dan_layer/engine/src/instructions/mod.rs b/dan_layer/engine/src/instructions/mod.rs new file mode 100644 index 0000000000..e7dc0b50e9 --- /dev/null +++ b/dan_layer/engine/src/instructions/mod.rs @@ -0,0 +1,6 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +mod instruction; + +pub use instruction::Instruction; diff --git a/dan_layer/engine/src/lib.rs b/dan_layer/engine/src/lib.rs new file mode 100644 index 0000000000..a543eb9be5 --- /dev/null +++ b/dan_layer/engine/src/lib.rs @@ -0,0 +1,9 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +pub mod flow; +pub mod function_definitions; +pub mod instructions; +pub mod models; +pub mod state; +pub mod wasm; diff --git a/dan_layer/engine/src/models/bucket.rs b/dan_layer/engine/src/models/bucket.rs new file mode 100644 index 0000000000..d9f43d7cfc --- /dev/null +++ b/dan_layer/engine/src/models/bucket.rs @@ -0,0 +1,33 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use serde::Deserialize; + +#[derive(Debug, Default, Clone, Deserialize)] +pub struct Bucket { + amount: u64, + token_id: u64, + asset_id: u64, +} + +impl Bucket { + pub fn new(amount: u64, token_id: u64, asset_id: u64) -> Self { + Self { + amount, + token_id, + asset_id, + } + } + + pub fn amount(&self) -> u64 { + self.amount + } + + pub fn token_id(&self) -> u64 { + self.token_id + } + + pub fn asset_id(&self) -> u64 { + self.asset_id + } +} diff --git a/dan_layer/engine/src/models/mod.rs b/dan_layer/engine/src/models/mod.rs new file mode 100644 index 0000000000..020c508d6d --- /dev/null +++ b/dan_layer/engine/src/models/mod.rs @@ -0,0 +1,6 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +mod bucket; + +pub use bucket::Bucket; diff --git a/dan_layer/engine/src/state/db_key_value.rs b/dan_layer/engine/src/state/db_key_value.rs new file mode 100644 index 0000000000..7e639270ca --- /dev/null +++ b/dan_layer/engine/src/state/db_key_value.rs @@ -0,0 +1,9 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +#[derive(Debug, Clone)] +pub struct DbKeyValue { + pub schema: String, + pub key: Vec, + pub value: Vec, +} diff --git a/dan_layer/engine/src/state/error.rs b/dan_layer/engine/src/state/error.rs new file mode 100644 index 0000000000..e6e840d0fc --- /dev/null +++ b/dan_layer/engine/src/state/error.rs @@ -0,0 +1,28 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause +use std::sync::PoisonError; + +use tari_mmr::error::MerkleMountainRangeError; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum StateStorageError { + #[error("Lock error")] + LockError, + #[error("Merkle error:{0}")] + MerkleMountainRangeError(#[from] MerkleMountainRangeError), + #[error("Could not connect to storage:{reason}")] + ConnectionError { reason: String }, + #[error("Query error:{reason}")] + QueryError { reason: String }, + #[error("Migration error: {reason}")] + MigrationError { reason: String }, + #[error("General storage error: {details}")] + General { details: String }, +} + +impl From> for StateStorageError { + fn from(_err: PoisonError) -> Self { + Self::LockError + } +} diff --git a/dan_layer/engine/src/state/mocks/mod.rs b/dan_layer/engine/src/state/mocks/mod.rs new file mode 100644 index 0000000000..06eb2c9285 --- /dev/null +++ b/dan_layer/engine/src/state/mocks/mod.rs @@ -0,0 +1,4 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +pub mod state_db; diff --git a/dan_layer/engine/src/state/mocks/state_db.rs b/dan_layer/engine/src/state/mocks/state_db.rs new file mode 100644 index 0000000000..db968a6899 --- /dev/null +++ b/dan_layer/engine/src/state/mocks/state_db.rs @@ -0,0 +1,70 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use crate::state::{error::StateStorageError, DbKeyValue, DbStateOpLogEntry, StateDbBackendAdapter}; + +#[derive(Debug, Clone, Default)] +pub struct MockStateDbBackupAdapter; + +impl StateDbBackendAdapter for MockStateDbBackupAdapter { + type BackendTransaction = (); + type Error = StateStorageError; + + fn create_transaction(&self) -> Result { + todo!() + } + + fn update_key_value( + &self, + _schema: &str, + _key: &[u8], + _value: &[u8], + _tx: &Self::BackendTransaction, + ) -> Result<(), Self::Error> { + todo!() + } + + fn get(&self, _schema: &str, _key: &[u8]) -> Result>, Self::Error> { + todo!() + } + + fn find_keys_by_value(&self, _schema: &str, _value: &[u8]) -> Result>, Self::Error> { + todo!() + } + + fn commit(&self, _tx: &Self::BackendTransaction) -> Result<(), Self::Error> { + todo!() + } + + fn get_all_schemas(&self, _tx: &Self::BackendTransaction) -> Result, Self::Error> { + todo!() + } + + fn get_all_values_for_schema( + &self, + _schema: &str, + _tx: &Self::BackendTransaction, + ) -> Result, Self::Error> { + todo!() + } + + fn get_state_op_logs_by_height( + &self, + _height: u64, + _tx: &Self::BackendTransaction, + ) -> Result, Self::Error> { + todo!() + } + + fn add_state_oplog_entry( + &self, + _entry: DbStateOpLogEntry, + _tx: &Self::BackendTransaction, + ) -> Result<(), Self::Error> { + todo!() + } + + fn clear_all_state(&self, _tx: &Self::BackendTransaction) -> Result<(), Self::Error> { + todo!() + } +} diff --git a/dan_layer/engine/src/state/mod.rs b/dan_layer/engine/src/state/mod.rs new file mode 100644 index 0000000000..f182357543 --- /dev/null +++ b/dan_layer/engine/src/state/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +mod state_db_unit_of_work; +pub use state_db_unit_of_work::{StateDbUnitOfWork, StateDbUnitOfWorkImpl, StateDbUnitOfWorkReader, UnitOfWorkContext}; + +mod db_key_value; +pub use db_key_value::DbKeyValue; + +mod state_db; +pub use state_db::StateDb; + +mod state_db_backend_adapter; +pub use state_db_backend_adapter::StateDbBackendAdapter; + +mod state_op_log; +pub use state_op_log::{DbStateOpLogEntry, DbStateOperation}; + +pub mod models; + +pub mod error; +pub mod mocks; diff --git a/dan_layer/engine/src/state/models/key_value.rs b/dan_layer/engine/src/state/models/key_value.rs new file mode 100644 index 0000000000..98271aa6c9 --- /dev/null +++ b/dan_layer/engine/src/state/models/key_value.rs @@ -0,0 +1,10 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Default, Clone, Debug)] +pub struct KeyValue { + pub key: Vec, + pub value: Vec, +} diff --git a/dan_layer/engine/src/state/models/mod.rs b/dan_layer/engine/src/state/models/mod.rs new file mode 100644 index 0000000000..72e01e6142 --- /dev/null +++ b/dan_layer/engine/src/state/models/mod.rs @@ -0,0 +1,14 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +mod key_value; +pub use key_value::KeyValue; + +mod schema_state; +pub use schema_state::SchemaState; + +mod state_root; +pub use state_root::StateRoot; + +mod op_log; +pub use op_log::{StateOpLogEntry, StateOperation}; diff --git a/dan_layer/engine/src/state/models/op_log.rs b/dan_layer/engine/src/state/models/op_log.rs new file mode 100644 index 0000000000..8ccea65eb7 --- /dev/null +++ b/dan_layer/engine/src/state/models/op_log.rs @@ -0,0 +1,50 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use crate::state::{DbStateOpLogEntry, DbStateOperation}; + +#[derive(Debug)] +pub struct StateOpLogEntry { + inner: DbStateOpLogEntry, +} + +impl StateOpLogEntry { + pub fn operation(&self) -> StateOperation { + self.inner.operation.into() + } + + pub fn into_inner(self) -> DbStateOpLogEntry { + self.inner + } +} + +impl From for StateOpLogEntry { + fn from(inner: DbStateOpLogEntry) -> Self { + Self { inner } + } +} + +#[derive(Debug, Clone, Copy)] +pub enum StateOperation { + Set, + Delete, +} + +impl StateOperation { + pub fn as_op_str(&self) -> &str { + use StateOperation::{Delete, Set}; + match self { + Set => "S", + Delete => "D", + } + } +} + +impl From for StateOperation { + fn from(op: DbStateOperation) -> Self { + match op { + DbStateOperation::Set => StateOperation::Set, + DbStateOperation::Delete => StateOperation::Delete, + } + } +} diff --git a/dan_layer/engine/src/state/models/schema_state.rs b/dan_layer/engine/src/state/models/schema_state.rs new file mode 100644 index 0000000000..b5ed83d11c --- /dev/null +++ b/dan_layer/engine/src/state/models/schema_state.rs @@ -0,0 +1,23 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use serde::{Deserialize, Serialize}; + +use crate::state::models::KeyValue; + +#[derive(Serialize, Deserialize, Default, Clone, Debug)] +pub struct SchemaState { + pub name: String, + pub items: Vec, +} + +impl SchemaState { + pub fn new(name: String, items: Vec) -> Self { + Self { name, items } + } + + pub fn push_key_value(&mut self, key_value: KeyValue) -> &mut Self { + self.items.push(key_value); + self + } +} diff --git a/dan_layer/engine/src/state/models/state_root.rs b/dan_layer/engine/src/state/models/state_root.rs new file mode 100644 index 0000000000..fb1d1efff7 --- /dev/null +++ b/dan_layer/engine/src/state/models/state_root.rs @@ -0,0 +1,25 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use tari_common_types::types::FixedHash; + +#[derive(PartialEq, Eq, Debug, Clone)] +pub struct StateRoot { + root: FixedHash, +} + +impl StateRoot { + pub fn new(root: FixedHash) -> Self { + Self { root } + } + + pub fn as_bytes(&self) -> &[u8] { + self.root.as_slice() + } + + pub fn initial() -> Self { + Self { + root: FixedHash::zero(), + } + } +} diff --git a/dan_layer/engine/src/state/state_db.rs b/dan_layer/engine/src/state/state_db.rs new file mode 100644 index 0000000000..7fa683888a --- /dev/null +++ b/dan_layer/engine/src/state/state_db.rs @@ -0,0 +1,39 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use tari_common_types::types::FixedHash; + +use crate::state::{ + state_db_unit_of_work::{StateDbUnitOfWorkImpl, StateDbUnitOfWorkReader, UnitOfWorkContext}, + StateDbBackendAdapter, +}; + +pub struct StateDb { + backend_adapter: TStateDbBackendAdapter, + contract_id: FixedHash, +} + +impl StateDb { + pub fn new(contract_id: FixedHash, backend_adapter: TStateDbBackendAdapter) -> Self { + Self { + backend_adapter, + contract_id, + } + } + + pub fn new_unit_of_work(&self, height: u64) -> StateDbUnitOfWorkImpl { + StateDbUnitOfWorkImpl::new( + UnitOfWorkContext::new(height, self.contract_id), + self.backend_adapter.clone(), + ) + } + + pub fn reader(&self) -> impl StateDbUnitOfWorkReader { + // TODO: A reader doesnt need the current context, should perhaps make a read-only implementation that the + // writable implementation also uses + StateDbUnitOfWorkImpl::new( + UnitOfWorkContext::new(0, self.contract_id), + self.backend_adapter.clone(), + ) + } +} diff --git a/dan_layer/engine/src/state/state_db_backend_adapter.rs b/dan_layer/engine/src/state/state_db_backend_adapter.rs new file mode 100644 index 0000000000..c25eea837d --- /dev/null +++ b/dan_layer/engine/src/state/state_db_backend_adapter.rs @@ -0,0 +1,35 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use crate::state::{db_key_value::DbKeyValue, error::StateStorageError, DbStateOpLogEntry}; + +pub trait StateDbBackendAdapter: Send + Sync + Clone { + type BackendTransaction; + type Error: Into; + + fn create_transaction(&self) -> Result; + fn update_key_value( + &self, + schema: &str, + key: &[u8], + value: &[u8], + tx: &Self::BackendTransaction, + ) -> Result<(), Self::Error>; + fn get(&self, schema: &str, key: &[u8]) -> Result>, Self::Error>; + fn find_keys_by_value(&self, schema: &str, value: &[u8]) -> Result>, Self::Error>; + fn commit(&self, tx: &Self::BackendTransaction) -> Result<(), Self::Error>; + fn get_all_schemas(&self, tx: &Self::BackendTransaction) -> Result, Self::Error>; + fn get_all_values_for_schema( + &self, + schema: &str, + tx: &Self::BackendTransaction, + ) -> Result, Self::Error>; + fn get_state_op_logs_by_height( + &self, + height: u64, + tx: &Self::BackendTransaction, + ) -> Result, Self::Error>; + fn add_state_oplog_entry(&self, entry: DbStateOpLogEntry, tx: &Self::BackendTransaction) + -> Result<(), Self::Error>; + fn clear_all_state(&self, tx: &Self::BackendTransaction) -> Result<(), Self::Error>; +} diff --git a/dan_layer/core/src/storage/state/state_db_unit_of_work.rs b/dan_layer/engine/src/state/state_db_unit_of_work.rs similarity index 79% rename from dan_layer/core/src/storage/state/state_db_unit_of_work.rs rename to dan_layer/engine/src/state/state_db_unit_of_work.rs index 408d24ccea..c4f0c4a86a 100644 --- a/dan_layer/core/src/storage/state/state_db_unit_of_work.rs +++ b/dan_layer/engine/src/state/state_db_unit_of_work.rs @@ -1,24 +1,5 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause use std::{ convert::TryInto, @@ -30,35 +11,35 @@ use digest::Digest; use log::*; use tari_common_types::types::{FixedHash, HashDigest}; use tari_crypto::common::Blake256; +use tari_dan_common_types::storage::UnitOfWorkTracker; use tari_mmr::{MemBackendVec, MerkleMountainRange}; use tari_utilities::hex::Hex; -use crate::{ +use crate::state::{ + db_key_value::DbKeyValue, + error::StateStorageError, models::{KeyValue, SchemaState, StateOpLogEntry, StateRoot}, - storage::{ - state::{db_key_value::DbKeyValue, DbStateOpLogEntry, StateDbBackendAdapter}, - StorageError, - UnitOfWorkTracker, - }, + DbStateOpLogEntry, + StateDbBackendAdapter, }; const LOG_TARGET: &str = "tari::dan::state_db"; pub trait StateDbUnitOfWork: StateDbUnitOfWorkReader { - fn set_value(&mut self, schema: String, key: Vec, value: Vec) -> Result<(), StorageError>; - fn set_u64(&mut self, schema: &str, key: &[u8], value: u64) -> Result<(), StorageError>; - fn commit(&mut self) -> Result<(), StorageError>; - fn clear_all_state(&self) -> Result<(), StorageError>; + fn set_value(&mut self, schema: String, key: Vec, value: Vec) -> Result<(), StateStorageError>; + fn set_u64(&mut self, schema: &str, key: &[u8], value: u64) -> Result<(), StateStorageError>; + fn commit(&mut self) -> Result<(), StateStorageError>; + fn clear_all_state(&self) -> Result<(), StateStorageError>; } pub trait StateDbUnitOfWorkReader: Clone + Send + Sync { fn context(&self) -> &UnitOfWorkContext; - fn get_value(&self, schema: &str, key: &[u8]) -> Result>, StorageError>; - fn get_u64(&self, schema: &str, key: &[u8]) -> Result, StorageError>; - fn find_keys_by_value(&self, schema: &str, value: &[u8]) -> Result>, StorageError>; - fn calculate_root(&self) -> Result; - fn get_all_state(&self) -> Result, StorageError>; - fn get_op_logs_for_height(&self, height: u64) -> Result, StorageError>; + fn get_value(&self, schema: &str, key: &[u8]) -> Result>, StateStorageError>; + fn get_u64(&self, schema: &str, key: &[u8]) -> Result, StateStorageError>; + fn find_keys_by_value(&self, schema: &str, value: &[u8]) -> Result>, StateStorageError>; + fn calculate_root(&self) -> Result; + fn get_all_state(&self) -> Result, StateStorageError>; + fn get_op_logs_for_height(&self, height: u64) -> Result, StateStorageError>; } #[derive(Debug, Clone)] @@ -105,7 +86,7 @@ impl Clone for StateDbUnitOfWorkImpl StateDbUnitOfWork for StateDbUnitOfWorkImpl { - fn set_value(&mut self, schema: String, key: Vec, value: Vec) -> Result<(), StorageError> { + fn set_value(&mut self, schema: String, key: Vec, value: Vec) -> Result<(), StateStorageError> { let mut inner = self.inner.write()?; inner .updates @@ -114,11 +95,11 @@ impl StateDbUnitOfWork for StateDbUnitOf Ok(()) } - fn set_u64(&mut self, schema: &str, key: &[u8], value: u64) -> Result<(), StorageError> { + fn set_u64(&mut self, schema: &str, key: &[u8], value: u64) -> Result<(), StateStorageError> { self.set_value(schema.to_string(), Vec::from(key), Vec::from(value.to_le_bytes())) } - fn commit(&mut self) -> Result<(), StorageError> { + fn commit(&mut self) -> Result<(), StateStorageError> { let mut inner = self.inner.write()?; let tx = inner .backend_adapter @@ -163,7 +144,7 @@ impl StateDbUnitOfWork for StateDbUnitOf /// Clears the state db immediately (before commit) - this will not be needed in future when build up the state from /// instructions/op logs - fn clear_all_state(&self) -> Result<(), StorageError> { + fn clear_all_state(&self) -> Result<(), StateStorageError> { let inner = self.inner.write()?; let tx = inner .backend_adapter @@ -181,7 +162,7 @@ impl StateDbUnitOfWorkReader for StateDb &self.context } - fn get_value(&self, schema: &str, key: &[u8]) -> Result>, StorageError> { + fn get_value(&self, schema: &str, key: &[u8]) -> Result>, StateStorageError> { let inner = self.inner.read()?; // Hit the DB. inner @@ -190,7 +171,7 @@ impl StateDbUnitOfWorkReader for StateDb .map_err(TBackendAdapter::Error::into) } - fn get_u64(&self, schema: &str, key: &[u8]) -> Result, StorageError> { + fn get_u64(&self, schema: &str, key: &[u8]) -> Result, StateStorageError> { let data = self.get_value(schema, key)?; match data { Some(data) => { @@ -202,7 +183,7 @@ impl StateDbUnitOfWorkReader for StateDb } } - fn find_keys_by_value(&self, schema: &str, value: &[u8]) -> Result>, StorageError> { + fn find_keys_by_value(&self, schema: &str, value: &[u8]) -> Result>, StateStorageError> { let inner = self.inner.read()?; inner .backend_adapter @@ -210,7 +191,7 @@ impl StateDbUnitOfWorkReader for StateDb .map_err(TBackendAdapter::Error::into) } - fn calculate_root(&self) -> Result { + fn calculate_root(&self) -> Result { let inner = self.inner.read()?; let tx = inner .backend_adapter @@ -263,7 +244,7 @@ impl StateDbUnitOfWorkReader for StateDb )) } - fn get_all_state(&self) -> Result, StorageError> { + fn get_all_state(&self) -> Result, StateStorageError> { let inner = self.inner.read()?; let tx = inner .backend_adapter @@ -294,7 +275,7 @@ impl StateDbUnitOfWorkReader for StateDb Ok(schema_state) } - fn get_op_logs_for_height(&self, height: u64) -> Result, StorageError> { + fn get_op_logs_for_height(&self, height: u64) -> Result, StateStorageError> { let inner = self.inner.read()?; let tx = inner .backend_adapter diff --git a/dan_layer/engine/src/state/state_op_log.rs b/dan_layer/engine/src/state/state_op_log.rs new file mode 100644 index 0000000000..764fba8f41 --- /dev/null +++ b/dan_layer/engine/src/state/state_op_log.rs @@ -0,0 +1,60 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::str::FromStr; + +use tari_common_types::types::FixedHash; + +use crate::state::DbKeyValue; + +#[derive(Debug)] +pub struct DbStateOpLogEntry { + pub height: u64, + pub merkle_root: Option, + pub operation: DbStateOperation, + pub schema: String, + pub key: Vec, + pub value: Option>, +} + +impl DbStateOpLogEntry { + pub fn set_operation(height: u64, key_value: DbKeyValue) -> Self { + Self { + height, + merkle_root: None, + operation: DbStateOperation::Set, + schema: key_value.schema, + key: key_value.key, + value: Some(key_value.value), + } + } +} + +#[derive(Debug, Clone, Copy)] +pub enum DbStateOperation { + Set, + Delete, +} + +impl DbStateOperation { + pub fn as_op_str(&self) -> &str { + use DbStateOperation::{Delete, Set}; + match self { + Set => "S", + Delete => "D", + } + } +} + +impl FromStr for DbStateOperation { + type Err = (); + + fn from_str(s: &str) -> Result { + use DbStateOperation::{Delete, Set}; + match s { + "S" => Ok(Set), + "D" => Ok(Delete), + _ => Err(()), + } + } +} diff --git a/dan_layer/engine/src/wasm/error.rs b/dan_layer/engine/src/wasm/error.rs new file mode 100644 index 0000000000..b7f3cd3cb7 --- /dev/null +++ b/dan_layer/engine/src/wasm/error.rs @@ -0,0 +1,10 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum WasmError { + #[error("Missing argument at position {position} (name: {argument_name}")] + MissingArgument { argument_name: String, position: usize }, +} diff --git a/dan_layer/engine/src/wasm/mod.rs b/dan_layer/engine/src/wasm/mod.rs new file mode 100644 index 0000000000..d884d88abc --- /dev/null +++ b/dan_layer/engine/src/wasm/mod.rs @@ -0,0 +1,10 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +mod error; +mod wasm_module_definition; +mod wasm_module_factory; + +pub use error::WasmError; +pub use wasm_module_definition::WasmModuleDefinition; +pub use wasm_module_factory::WasmModuleFactory; diff --git a/dan_layer/engine/src/wasm/wasm_module_definition.rs b/dan_layer/engine/src/wasm/wasm_module_definition.rs new file mode 100644 index 0000000000..1750e88dd0 --- /dev/null +++ b/dan_layer/engine/src/wasm/wasm_module_definition.rs @@ -0,0 +1,12 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Default, Clone, Debug)] +pub struct WasmModuleDefinition { + pub name: String, + pub path: PathBuf, +} diff --git a/dan_layer/engine/src/wasm/wasm_module_factory.rs b/dan_layer/engine/src/wasm/wasm_module_factory.rs new file mode 100644 index 0000000000..92d17745d2 --- /dev/null +++ b/dan_layer/engine/src/wasm/wasm_module_factory.rs @@ -0,0 +1,148 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::{collections::HashMap, fs}; + +use wasmer::{imports, Instance, Module, Store, Val, Value}; + +use crate::{ + function_definitions::{ArgType, WasmFunctionDefinition}, + instructions::Instruction, + state::StateDbUnitOfWork, + wasm::{WasmError, WasmModuleDefinition}, +}; + +#[derive(Clone, Default)] +pub struct WasmModuleFactory { + modules: HashMap, + functions: HashMap, String)>, +} + +impl WasmModuleFactory { + pub fn new(wasm_modules: &[WasmModuleDefinition], wasm_functions: &[WasmFunctionDefinition]) -> Self { + let mut modules = HashMap::new(); + for mod_def in wasm_modules { + let store = Store::default(); + let file = fs::read(&mod_def.path).expect("could not read all bytes"); + let module = Module::new(&store, file).expect("Did not compile"); + let import_object = imports! {}; // <- SDK for interacting with block chain + let _declared_imps: Vec<_> = module.imports().functions().collect(); + // TODO: Does wasm code auto run at this point + let instance = Instance::new(&module, &import_object).expect("Could not create instance"); + modules.insert(mod_def.name.clone(), instance); + } + let mut functions = HashMap::new(); + for func_def in wasm_functions { + if let Some(instance) = modules.get(&func_def.in_module) { + // check that imported function is actually present in wasm + let _function = instance.exports.get_function(&func_def.name).unwrap(); + + functions.insert( + func_def.name.clone(), + ( + func_def.args.iter().map(|at| at.arg_type.clone()).collect(), + func_def.in_module.clone(), + ), + ); + } else { + panic!("module {} does not exist", func_def.in_module) + } + } + Self { modules, functions } + } + + pub fn invoke_write_method( + &self, + name: String, + instruction: &Instruction, + state_db: TUnitOfWork, + ) -> Result { + // TODO: We should probably create a new instance each time, so that + // there's no stale memory + if let Some((arg_types, module_name)) = self.functions.get(&name) { + if let Some(instance) = self.modules.get(module_name) { + let func_pointer = instance.exports.get_function(&name).expect("Could not find function"); + let _type_params = func_pointer.ty().params(); + let _remaining_args = Vec::from(instruction.args()); + // dbg!(&remaining_args); + // let memory = instance.get_memory("mem"); + let _offset = 0; + // TODO: better iteration + let mut remaining_instruction_args = Vec::from(instruction.args()); + let args: Vec> = arg_types + .iter() + .enumerate() + .map(|(position, param)| { + match param { + ArgType::String => { + // if remaining_args.len() < 3 { + // return Err(DigitalAssetError::MissingArgument { + // position, + // argument_name: "Wasm string".to_string(), + // }); + // } + // + // let len = remaining_instruction_args.pop().expect("can't take length") as usize; + // let instruction_arg = + // String::from_utf8(remaining_instruction_args.drain(len)).expect("invalid utf8"); + // let ptr = WasmPtr::::new(offset); + // let derefed = ptr.deref(&memory).expect("could not get derefed pointer"); + // derefed.set(instruction_arg); + // + // Ok(vec![Value::I32()]) + todo!() + }, + ArgType::Byte => { + if remaining_instruction_args.is_empty() { + return Err(WasmError::MissingArgument { + position, + argument_name: "Wasm byte".to_string(), + }); + } + let byte = remaining_instruction_args.pop().expect("not enough length"); + Ok(vec![Value::I32(i32::from(byte))]) + }, + ArgType::PublicKey => { + if remaining_instruction_args.len() < 32 { + return Err(WasmError::MissingArgument { + position, + argument_name: "Wasm public key".to_string(), + }); + } + let bytes: Vec = remaining_instruction_args.drain(..32).collect(); + let mut result = Vec::with_capacity(8); + for i in 0..8 { + let mut data = [0u8; 4]; + data.copy_from_slice(&bytes[i * 4..i * 4 + 4]); + result.push(Value::I32(i32::from_le_bytes(data))); + } + // write as 8 * bytes + Ok(result) + }, + // F32, + // F64, + // V128, + // ExternRef, + // FuncRef, + _ => { + todo!() + }, + } + }) + .collect::>()?; + + let args: Vec = args.into_iter().flatten().collect(); + let _result = func_pointer.call(args.as_slice()).expect("invokation error"); + Ok(state_db) + } else { + todo!("No module found") + } + } else { + todo!("function not found") + } + // let store = Store::default(); + // let module = Module::new(&store, wat_file.as_str()); + // let import_object = imports! {}; + // let instance = Instance::new(&module, &import_object)?; + } +} diff --git a/dan_layer/storage_sqlite/Cargo.toml b/dan_layer/storage_sqlite/Cargo.toml index adeeefa6e2..0eb363fc10 100644 --- a/dan_layer/storage_sqlite/Cargo.toml +++ b/dan_layer/storage_sqlite/Cargo.toml @@ -9,7 +9,7 @@ tari_dan_core = {path="../core"} tari_common = { path = "../../common"} tari_common_types = {path = "../../base_layer/common_types"} tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.4" } - +tari_dan_engine = { path = "../engine"} diesel = { version = "1.4.8", features = ["sqlite"] } diesel_migrations = "1.4.0" @@ -18,5 +18,3 @@ async-trait = "0.1.50" tokio = { version="1.10", features = ["macros", "time"]} tokio-stream = { version = "0.1.7", features = ["sync"] } log = { version = "0.4.8", features = ["std"] } -patricia_tree = { version = "0.3.0", features = ["binary-format"] } -bytecodec = { version = "0.4.14", features = ["bincode_codec"] } diff --git a/dan_layer/storage_sqlite/src/error.rs b/dan_layer/storage_sqlite/src/error.rs index 42c864c458..fc07993ddd 100644 --- a/dan_layer/storage_sqlite/src/error.rs +++ b/dan_layer/storage_sqlite/src/error.rs @@ -22,6 +22,7 @@ use diesel; use tari_common_types::types::FixedHashSizeError; use tari_dan_core::{models::ModelError, storage::StorageError}; +use tari_dan_engine::state::error::StateStorageError; use thiserror::Error; #[derive(Debug, Error)] @@ -41,14 +42,14 @@ pub enum SqliteStorageError { #[from] source: diesel_migrations::RunMigrationsError, }, - #[error("Error decoding bytes:{0}")] - DecodeError(#[from] bytecodec::Error), #[error("Encountered malformed hash data")] MalformedHashData, #[error("Malformed DB data: {0}")] MalformedDbData(String), #[error(transparent)] ModelError(#[from] ModelError), + #[error("Conversion error:{reason}")] + ConversionError { reason: String }, } impl From for StorageError { @@ -63,7 +64,6 @@ impl From for StorageError { SqliteStorageError::MigrationError { .. } => StorageError::MigrationError { reason: source.to_string(), }, - SqliteStorageError::DecodeError(e) => StorageError::DecodeError(e), other => StorageError::General { details: other.to_string(), }, @@ -71,6 +71,25 @@ impl From for StorageError { } } +impl From for StateStorageError { + fn from(source: SqliteStorageError) -> Self { + match source { + SqliteStorageError::ConnectionError { .. } => StateStorageError::ConnectionError { + reason: source.to_string(), + }, + SqliteStorageError::DieselError { .. } => StateStorageError::QueryError { + reason: source.to_string(), + }, + SqliteStorageError::MigrationError { .. } => StateStorageError::MigrationError { + reason: source.to_string(), + }, + other => StateStorageError::General { + details: other.to_string(), + }, + } + } +} + impl From for SqliteStorageError { fn from(_: FixedHashSizeError) -> Self { SqliteStorageError::MalformedHashData diff --git a/dan_layer/storage_sqlite/src/models/instruction.rs b/dan_layer/storage_sqlite/src/models/instruction.rs index d9909b8c1f..173688e001 100644 --- a/dan_layer/storage_sqlite/src/models/instruction.rs +++ b/dan_layer/storage_sqlite/src/models/instruction.rs @@ -39,11 +39,14 @@ pub struct Instruction { pub sender: Vec, } -impl TryFrom for tari_dan_core::models::Instruction { +impl TryFrom for tari_dan_engine::instructions::Instruction { type Error = SqliteStorageError; fn try_from(instruction: Instruction) -> Result { - let template_id = instruction.template_id.try_into()?; + let template_id = instruction + .template_id + .try_into() + .map_err(|s| SqliteStorageError::ConversionError { reason: s })?; Ok(Self::new( template_id, instruction.method, diff --git a/dan_layer/storage_sqlite/src/models/mod.rs b/dan_layer/storage_sqlite/src/models/mod.rs index 00613a6de0..bc30cc1599 100644 --- a/dan_layer/storage_sqlite/src/models/mod.rs +++ b/dan_layer/storage_sqlite/src/models/mod.rs @@ -26,4 +26,3 @@ pub mod node; pub mod prepare_qc; pub mod state_key; pub mod state_op_log; -pub mod state_tree; diff --git a/dan_layer/storage_sqlite/src/models/state_op_log.rs b/dan_layer/storage_sqlite/src/models/state_op_log.rs index 5d21f3670e..4ebbb358ff 100644 --- a/dan_layer/storage_sqlite/src/models/state_op_log.rs +++ b/dan_layer/storage_sqlite/src/models/state_op_log.rs @@ -1,6 +1,8 @@ use std::convert::TryFrom; -use tari_dan_core::models::TreeNodeHash; +use tari_common_types::types::FixedHash; +use tari_dan_engine::state::DbStateOpLogEntry; + // Copyright 2022, The Tari Project // // Redistribution and use in source and binary forms, with or without modification, are permitted provided that @@ -23,8 +25,6 @@ use tari_dan_core::models::TreeNodeHash; // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH // DAMAGE. -use tari_dan_core::storage::state::DbStateOpLogEntry; - use crate::{error::SqliteStorageError, schema::*}; #[derive(Debug, Clone, Identifiable, Queryable)] @@ -55,7 +55,7 @@ impl From for NewStateOpLogEntry { fn from(entry: DbStateOpLogEntry) -> Self { Self { height: entry.height as i64, - merkle_root: entry.merkle_root.map(|r| r.as_bytes().to_vec()), + merkle_root: entry.merkle_root.map(|r| r.to_vec()), operation: entry.operation.as_op_str().to_string(), schema: entry.schema, key: entry.key, @@ -73,13 +73,15 @@ impl TryFrom for DbStateOpLogEntry { height: entry.height as u64, merkle_root: entry .merkle_root - .map(TreeNodeHash::try_from) + .map(FixedHash::try_from) .transpose() .map_err(|_| SqliteStorageError::MalformedHashData)?, operation: entry .operation .parse() - .map_err(|_| SqliteStorageError::MalformedDbData("Invalid OpLog operation".to_string()))?, + .map_err(|_| SqliteStorageError::ConversionError { + reason: "Invalid OpLog operation".to_string(), + })?, schema: entry.schema, key: entry.key, value: entry.value, diff --git a/dan_layer/storage_sqlite/src/models/state_tree.rs b/dan_layer/storage_sqlite/src/models/state_tree.rs deleted file mode 100644 index 3654df2ca5..0000000000 --- a/dan_layer/storage_sqlite/src/models/state_tree.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use crate::schema::*; -#[derive(Queryable)] -pub(crate) struct StateTree { - pub _id: i32, - pub version: i32, - pub _is_current: bool, - pub data: Vec, -} - -#[derive(Insertable)] -#[table_name = "state_tree"] -pub(crate) struct NewStateTree { - pub version: i32, - pub is_current: bool, - pub data: Vec, -} diff --git a/dan_layer/storage_sqlite/src/sqlite_db_factory.rs b/dan_layer/storage_sqlite/src/sqlite_db_factory.rs index 6c1c823eb6..7ede7674a6 100644 --- a/dan_layer/storage_sqlite/src/sqlite_db_factory.rs +++ b/dan_layer/storage_sqlite/src/sqlite_db_factory.rs @@ -26,7 +26,8 @@ use diesel::{Connection, ConnectionError, SqliteConnection}; use diesel_migrations::embed_migrations; use log::*; use tari_common_types::types::FixedHash; -use tari_dan_core::storage::{chain::ChainDb, global::GlobalDb, state::StateDb, DbFactory, StorageError}; +use tari_dan_core::storage::{chain::ChainDb, global::GlobalDb, DbFactory, StorageError}; +use tari_dan_engine::state::StateDb; use tari_utilities::hex::Hex; use crate::{ diff --git a/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs b/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs index bd4db62c84..879fc499cb 100644 --- a/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs +++ b/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs @@ -22,25 +22,15 @@ use std::convert::TryInto; -use bytecodec::{ - bincode_codec::{BincodeDecoder, BincodeEncoder}, - DecodeExt, - EncodeExt, -}; use diesel::{prelude::*, Connection, SqliteConnection}; use log::*; -use patricia_tree::{ - node::{Node, NodeDecoder, NodeEncoder}, - PatriciaMap, -}; -use tari_dan_core::storage::state::{DbKeyValue, DbStateOpLogEntry, StateDbBackendAdapter}; +use tari_dan_engine::state::{DbKeyValue, DbStateOpLogEntry, StateDbBackendAdapter}; use crate::{ error::SqliteStorageError, models::{ state_key::StateKey, state_op_log::{NewStateOpLogEntry, StateOpLogEntry}, - state_tree::{NewStateTree, StateTree}, }, schema::*, SqliteTransaction, @@ -161,70 +151,6 @@ impl StateDbBackendAdapter for SqliteStateDbBackendAdapter { Ok(()) } - fn get_current_state_tree(&self, tx: &Self::BackendTransaction) -> Result>, Self::Error> { - use crate::schema::state_tree::dsl; - let row: Option = dsl::state_tree - .filter(state_tree::is_current.eq(true)) - .order_by(state_tree::version.desc()) - .first(tx.connection()) - .optional() - .map_err(|source| SqliteStorageError::DieselError { - source, - operation: "get_current_state_tree".to_string(), - })?; - if let Some(row) = row { - let mut decoder = NodeDecoder::new(BincodeDecoder::new()); - let nodes: Node> = decoder.decode_from_bytes(&row.data)?; - Ok(nodes.into()) - } else { - Ok(PatriciaMap::new()) - } - } - - fn set_current_state_tree( - &self, - tree: patricia_tree::map::PatriciaMap>, - tx: &Self::BackendTransaction, - ) -> Result<(), Self::Error> { - let mut encoder = NodeEncoder::new(BincodeEncoder::new()); - let encoded = encoder.encode_into_bytes(tree.into())?; - - use crate::schema::state_tree::dsl; - let existing_row: Option = dsl::state_tree - .filter(state_tree::is_current.eq(true)) - .order_by(state_tree::version.desc()) - .first(tx.connection()) - .optional() - .map_err(|source| SqliteStorageError::DieselError { - source, - operation: "set_current_state_tree::fetch".to_string(), - })?; - - diesel::update(dsl::state_tree.filter(state_tree::is_current.eq(true))) - .set(state_tree::is_current.eq(false)) - .execute(tx.connection()) - .map_err(|source| SqliteStorageError::DieselError { - source, - operation: "set_current_state_tree:update".to_string(), - })?; - - let row = NewStateTree { - version: existing_row.map(|r| r.version).unwrap_or_default() + 1, - is_current: true, - data: encoded, - }; - - diesel::insert_into(dsl::state_tree) - .values(row) - .execute(tx.connection()) - .map_err(|source| SqliteStorageError::DieselError { - source, - operation: "set_current_state_tree::insert".to_string(), - })?; - - Ok(()) - } - fn get_all_schemas(&self, tx: &Self::BackendTransaction) -> Result, Self::Error> { use crate::schema::state_keys::dsl; let schemas: Vec = dsl::state_keys