diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index eb72e61f607..d0de8c56d2e 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -3,6 +3,7 @@ use crate::data_contract::validation::data_contract_validator::DataContractValid use crate::data_contract::{DataContract, DataContractFactory}; use crate::prelude::Identifier; +use crate::util::entropy_generator::EntropyGenerator; use crate::validation::SimpleValidationResult; use crate::version::ProtocolVersionValidator; use crate::ProtocolError; @@ -29,6 +30,22 @@ impl DataContractFacade { } } + pub fn new_with_entropy_generator( + protocol_version: u32, + protocol_version_validator: Arc, + entropy_generator: Box, + ) -> Self { + let validator = Arc::new(DataContractValidator::new(protocol_version_validator)); + Self { + factory: DataContractFactory::new_with_entropy_generator( + protocol_version, + validator.clone(), + entropy_generator, + ), + data_contract_validator: validator, + } + } + /// Create Data Contract pub fn create( &self, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index e0e69dbbaf8..efcb20bbc42 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -125,6 +125,12 @@ impl IdentityCreateTransition { state_transition.set_asset_lock_proof(AssetLockProof::try_from(proof)?)?; } + if let Some(signature) = + transition_map.get_optional_binary_data(property_names::SIGNATURE)? + { + state_transition.set_signature(signature); + } + state_transition.protocol_version = transition_map.get_integer(property_names::PROTOCOL_VERSION)?; diff --git a/packages/wasm-dpp/lib/index.ts b/packages/wasm-dpp/lib/index.ts index 396fcf87944..595f076112c 100644 --- a/packages/wasm-dpp/lib/index.ts +++ b/packages/wasm-dpp/lib/index.ts @@ -5,27 +5,35 @@ import wasmBase from '../wasm/wasm_dpp_bg.js'; import patchIdentifier from "./identifier/patchIdentifier"; let isInitialized = false; +let loadingPromise: Promise | null = null; export default async function loadDpp() { if (isInitialized) { - return dpp_module; - } else { - // @ts-ignore - let bytes = Buffer.from(wasmBase, 'base64'); - - if (typeof fetch !== 'undefined') { - let blob = new Blob([bytes], { type: "application/wasm" }); - let wasmUrl = URL.createObjectURL(blob); - await init(wasmUrl); - isInitialized = true; - } else { - dpp_module.initSync(bytes); - isInitialized = true; - } - - patchIdentifier(dpp_module); - - return dpp_module; + return dpp_module + } + + if (!loadingPromise) { + loadingPromise = loadDppModule() } + + await loadingPromise; + isInitialized = true; + loadingPromise = null; + return dpp_module; }; +const loadDppModule = async () => { + // @ts-ignore + let bytes = Buffer.from(wasmBase, 'base64'); + + if (typeof window !== 'undefined') { + let blob = new Blob([bytes], { type: "application/wasm" }); + let wasmUrl = URL.createObjectURL(blob); + await init(wasmUrl); + } else { + dpp_module.initSync(bytes); + } + + patchIdentifier(dpp_module); +} + diff --git a/packages/wasm-dpp/src/dash_platform_protocol.rs b/packages/wasm-dpp/src/dash_platform_protocol.rs index 24253c0ae33..c92ace32451 100644 --- a/packages/wasm-dpp/src/dash_platform_protocol.rs +++ b/packages/wasm-dpp/src/dash_platform_protocol.rs @@ -14,6 +14,7 @@ use dpp::identity::validation::PublicKeysValidator; use crate::state_transition_facade::StateTransitionFacadeWasm; use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; +use crate::entropy_generator::ExternalEntropyGenerator; use serde::{Deserialize, Serialize}; #[wasm_bindgen(js_name=DashPlatformProtocol)] @@ -26,6 +27,7 @@ pub struct DashPlatformProtocol { state_repository: ExternalStateRepositoryLike, public_keys_validator: Arc>, bls: BlsAdapter, + entropy_generator: ExternalEntropyGenerator, } #[derive(Serialize, Deserialize)] @@ -40,6 +42,7 @@ impl DashPlatformProtocol { pub fn new( bls_adapter: JsBlsAdapter, state_repository: ExternalStateRepositoryLike, + entropy_generator: ExternalEntropyGenerator, maybe_protocol_version: Option, ) -> Result { let bls = BlsAdapter(bls_adapter); @@ -52,6 +55,7 @@ impl DashPlatformProtocol { protocol_version, state_repository.clone(), bls.clone(), + entropy_generator.clone(), )?; Ok(Self { @@ -63,6 +67,7 @@ impl DashPlatformProtocol { state_repository, public_keys_validator, bls, + entropy_generator, }) } @@ -102,6 +107,7 @@ impl DashPlatformProtocol { protocol_version, self.state_repository.clone(), self.bls.clone(), + self.entropy_generator.clone(), ) } @@ -110,7 +116,12 @@ impl DashPlatformProtocol { &mut self, state_repository: ExternalStateRepositoryLike, ) -> Result<(), JsValue> { - self.init(self.protocol_version, state_repository, self.bls.clone()) + self.init( + self.protocol_version, + state_repository, + self.bls.clone(), + self.entropy_generator.clone(), + ) } #[wasm_bindgen(js_name = getStateRepository)] @@ -123,6 +134,7 @@ impl DashPlatformProtocol { protocol_version: u32, state_repository: ExternalStateRepositoryLike, bls_adapter: BlsAdapter, + entropy_generator: ExternalEntropyGenerator, ) -> Result<(), JsValue> { let (identity_facade, document_facade, data_contract_facade, state_transition_facade) = create_facades( @@ -130,6 +142,7 @@ impl DashPlatformProtocol { protocol_version, state_repository.clone(), bls_adapter, + entropy_generator, )?; self.protocol_version = protocol_version; @@ -148,6 +161,7 @@ fn create_facades( protocol_version: u32, state_repository: ExternalStateRepositoryLike, bls_adapter: BlsAdapter, + entropy_generator: ExternalEntropyGenerator, ) -> Result< ( IdentityFacadeWasm, @@ -172,10 +186,14 @@ fn create_facades( protocol_version, protocol_version_validator.clone(), wrapped_state_repository, + entropy_generator.clone(), ); - let data_contract_facade = - DataContractFacadeWasm::new(protocol_version, protocol_version_validator.clone()); + let data_contract_facade = DataContractFacadeWasm::new( + protocol_version, + protocol_version_validator.clone(), + entropy_generator, + ); let state_transition_facade = StateTransitionFacadeWasm::new(state_repository, bls_adapter, protocol_version_validator)?; @@ -192,12 +210,14 @@ fn init_document_facade( protocol_version: u32, protocol_version_validator: Arc, state_repository: ExternalStateRepositoryLikeWrapper, + entropy_generator: ExternalEntropyGenerator, ) -> DocumentFacadeWasm { let document_validator = DocumentValidatorWasm::new_with_arc(protocol_version_validator); let document_factory = DocumentFactoryWASM::new_with_state_repository_wrapper( protocol_version, document_validator.clone(), + entropy_generator, state_repository.clone(), ); diff --git a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs index d15ab415d07..11227b95e86 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs @@ -8,6 +8,7 @@ use dpp::data_contract::DataContractFacade; use dpp::identifier::Identifier; use dpp::version::ProtocolVersionValidator; +use crate::entropy_generator::ExternalEntropyGenerator; use crate::utils::{get_bool_from_options, WithJsError, SKIP_VALIDATION_PROPERTY_NAME}; use crate::validation::ValidationResultWasm; use dpp::platform_value::Value; @@ -23,8 +24,13 @@ impl DataContractFacadeWasm { pub fn new( protocol_version: u32, protocol_version_validator: Arc, + entropy_generator: ExternalEntropyGenerator, ) -> Self { - let inner = DataContractFacade::new(protocol_version, protocol_version_validator); + let inner = DataContractFacade::new_with_entropy_generator( + protocol_version, + protocol_version_validator, + Box::new(entropy_generator), + ); Self(Arc::new(inner)) } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index f2aa659507c..cf8ba08f1ca 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -6,6 +6,8 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; +use dpp::consensus::signature::SignatureError; +use dpp::consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant; use dpp::{ data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition, platform_value, @@ -161,6 +163,7 @@ impl DataContractCreateTransitionWasm { bls: JsBlsAdapter, ) -> Result<(), JsValue> { let bls_adapter = BlsAdapter(bls); + self.0 .sign( &identity_public_key.to_owned().into(), @@ -169,4 +172,31 @@ impl DataContractCreateTransitionWasm { ) .with_js_error() } + + #[wasm_bindgen(js_name=verifySignature)] + pub fn verify_signature( + &self, + identity_public_key: &IdentityPublicKeyWasm, + bls: JsBlsAdapter, + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() + } } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index e7754ceae5f..aa1eca937d5 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -6,7 +6,10 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; +use dpp::consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant; + use dpp::{ + consensus::signature::SignatureError, data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition, platform_value, state_transition::{ @@ -17,7 +20,11 @@ use dpp::{ use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -use crate::utils::WithJsError; +use crate::{ + bls_adapter::{BlsAdapter, JsBlsAdapter}, + utils::WithJsError, + IdentityPublicKeyWasm, +}; use crate::{ buffer::Buffer, errors::protocol_error::from_protocol_error, identifier::IdentifierWrapper, with_js_error, DataContractParameters, DataContractWasm, StateTransitionExecutionContextWasm, @@ -159,4 +166,31 @@ impl DataContractUpdateTransitionWasm { .serialize(&serde_wasm_bindgen::Serializer::json_compatible()) .map_err(|e| e.into()) } + + #[wasm_bindgen(js_name=verifySignature)] + pub fn verify_signature( + &self, + identity_public_key: &IdentityPublicKeyWasm, + bls: JsBlsAdapter, + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() + } } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 3e94d4fe93b..bd4bf8993a0 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -67,12 +67,14 @@ impl DocumentFactoryWASM { pub(crate) fn new_with_state_repository_wrapper( protocol_version: u32, document_validator: DocumentValidatorWasm, + entropy_generator: ExternalEntropyGenerator, state_repository: ExternalStateRepositoryLikeWrapper, ) -> Self { - let factory = DocumentFactory::new( + let factory = DocumentFactory::new_with_entropy_generator( protocol_version, document_validator.into(), DataContractFetcherAndValidator::new(Arc::new(state_repository)), + Box::new(entropy_generator), ); DocumentFactoryWASM(factory) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 98ef0820ef9..3a9f7cf51f0 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,6 +1,8 @@ use dpp::identity::KeyID; -use dpp::state_transition::fee::calculate_state_transition_fee_factory::calculate_state_transition_fee; + use dpp::{ + consensus::signature::SignatureError, + consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant, document::{ document_transition::document_base_transition, state_transition::documents_batch_transition::property_names, DocumentsBatchTransition, @@ -16,7 +18,6 @@ use dpp::{ use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; -use dpp::platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use dpp::platform_value::{BinaryData, ReplacementType}; use wasm_bindgen::prelude::*; @@ -296,12 +297,28 @@ impl DocumentsBatchTransitionWasm { #[wasm_bindgen(js_name=verifySignature)] pub fn verify_signature( &self, - public_key: &IdentityPublicKeyWasm, + identity_public_key: &IdentityPublicKeyWasm, bls: JsBlsAdapter, - ) -> Result<(), JsValue> { - self.0 - .verify_signature(public_key.inner(), &BlsAdapter(bls)) - .with_js_error() + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() } #[wasm_bindgen(js_name=setSignaturePublicKey)] diff --git a/packages/wasm-dpp/src/entropy_generator.rs b/packages/wasm-dpp/src/entropy_generator.rs index 7e6d18d340c..21101d6b3a0 100644 --- a/packages/wasm-dpp/src/entropy_generator.rs +++ b/packages/wasm-dpp/src/entropy_generator.rs @@ -6,6 +6,7 @@ use wasm_bindgen::JsValue; #[wasm_bindgen] extern "C" { + #[derive(Clone)] pub type ExternalEntropyGenerator; #[wasm_bindgen(catch, structural, method)] diff --git a/packages/wasm-dpp/src/identity/identity_facade.rs b/packages/wasm-dpp/src/identity/identity_facade.rs index d0f44847420..91b63f437f5 100644 --- a/packages/wasm-dpp/src/identity/identity_facade.rs +++ b/packages/wasm-dpp/src/identity/identity_facade.rs @@ -116,8 +116,8 @@ impl IdentityFacadeWasm { } #[wasm_bindgen] - pub fn validate(&self, identity: IdentityWasm) -> Result { - let identity: Identity = identity.into(); + pub fn validate(&self, identity: &IdentityWasm) -> Result { + let identity: Identity = identity.to_owned().into(); let identity_json = identity.to_cleaned_object().with_js_error()?; let validation_result = self diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 9cd16bd44d9..38603d3311f 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -1,6 +1,7 @@ use std::convert::TryInto; use std::default::Default; +use dpp::consensus::signature::SignatureError; use serde::{Deserialize, Serialize}; use wasm_bindgen::__rt::Ref; use wasm_bindgen::prelude::*; @@ -18,6 +19,9 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; use crate::utils::{generic_of_js_val, WithJsError}; + +use dpp::consensus::ConsensusError::SignatureError as ConsensusSignatureErrorVariant; + use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::{KeyID, TimestampMillis}; use dpp::platform_value::string_encoding::Encoding; @@ -483,4 +487,31 @@ impl IdentityUpdateTransitionWasm { ) .with_js_error() } + + #[wasm_bindgen(js_name=verifySignature)] + pub fn verify_signature( + &self, + identity_public_key: &IdentityPublicKeyWasm, + bls: JsBlsAdapter, + ) -> Result { + let bls_adapter = BlsAdapter(bls); + + let verification_result = self + .0 + .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); + + match verification_result { + Ok(()) => Ok(true), + Err(protocol_error) => match &protocol_error { + ProtocolError::AbstractConsensusError(err) => match err.as_ref() { + ConsensusSignatureErrorVariant( + SignatureError::InvalidStateTransitionSignatureError, + ) => Ok(false), + _ => Err(protocol_error), + }, + _ => Err(protocol_error), + }, + } + .with_js_error() + } } diff --git a/packages/wasm-dpp/src/state_transition/conversion.rs b/packages/wasm-dpp/src/state_transition/conversion.rs index 8ad03a49e51..87cb3ff8a50 100644 --- a/packages/wasm-dpp/src/state_transition/conversion.rs +++ b/packages/wasm-dpp/src/state_transition/conversion.rs @@ -3,16 +3,50 @@ use crate::utils::generic_of_js_val; use crate::{ DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, DocumentsBatchTransitionWasm, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, - IdentityUpdateTransitionWasm, + IdentityUpdateTransitionWasm, PreCalculatedOperationWasm, ReadOperationWasm, + SignatureVerificationOperationWasm, }; use dpp::consensus::basic::state_transition::InvalidStateTransitionTypeError; use dpp::consensus::basic::BasicError; use dpp::consensus::ConsensusError; +use dpp::state_transition::fee::operations::Operation; use dpp::state_transition::{StateTransition, StateTransitionType}; use std::convert::TryInto; use wasm_bindgen::__rt::Ref; use wasm_bindgen::{JsCast, JsError, JsValue}; +pub fn create_operation_from_wasm_instance(js_value: &JsValue) -> Result { + let maybe_signature_verification_operation: Result< + Ref, + JsValue, + > = generic_of_js_val::( + js_value, + "SignatureVerificationOperation", + ); + + if let Ok(operation) = maybe_signature_verification_operation { + return Ok(Operation::SignatureVerification( + operation.to_owned().into(), + )); + } + + let maybe_read_operation: Result, JsValue> = + generic_of_js_val::(js_value, "ReadOperation"); + + if let Ok(operation) = maybe_read_operation { + return Ok(Operation::Read(operation.to_owned().into())); + } + + let maybe_precalculated_operation: Result, JsValue> = + generic_of_js_val::(js_value, "PreCalculatedOperation"); + + if let Ok(operation) = maybe_precalculated_operation { + return Ok(Operation::PreCalculated(operation.to_owned().into())); + } + + Err(JsError::new("Unknown operation").into()) +} + pub fn create_state_transition_from_wasm_instance( js_value: &JsValue, ) -> Result { diff --git a/packages/wasm-dpp/src/state_transition/fee/mod.rs b/packages/wasm-dpp/src/state_transition/fee/mod.rs index 7f787f119d6..c87ea551280 100644 --- a/packages/wasm-dpp/src/state_transition/fee/mod.rs +++ b/packages/wasm-dpp/src/state_transition/fee/mod.rs @@ -9,6 +9,8 @@ mod fee_result; mod operations; mod refunds; +pub use operations::*; + #[wasm_bindgen(js_name=Operation)] #[derive(Clone)] pub struct OperationWasm(Operation); diff --git a/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs b/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs index 59bce03f0af..0ba6380d95d 100644 --- a/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs +++ b/packages/wasm-dpp/src/state_transition/fee/operations/pre_calculated_operation.rs @@ -21,6 +21,12 @@ impl From for PreCalculatedOperationWasm { } } +impl From for PreCalculatedOperation { + fn from(value: PreCalculatedOperationWasm) -> Self { + value.0 + } +} + #[wasm_bindgen(js_class=PreCalculatedOperation)] impl PreCalculatedOperationWasm { #[wasm_bindgen(constructor)] diff --git a/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs b/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs index 6971d484b0a..abb657d07cd 100644 --- a/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs +++ b/packages/wasm-dpp/src/state_transition/fee/operations/read_operation.rs @@ -17,6 +17,12 @@ impl From for ReadOperationWasm { } } +impl From for ReadOperation { + fn from(value: ReadOperationWasm) -> Self { + value.0 + } +} + #[wasm_bindgen(js_class=ReadOperation)] impl ReadOperationWasm { #[wasm_bindgen(constructor)] diff --git a/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs b/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs index b09d6005000..ffa27dc4723 100644 --- a/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs +++ b/packages/wasm-dpp/src/state_transition/fee/operations/signature_verification_operation.rs @@ -23,6 +23,12 @@ impl From for SignatureVerificationOperationWasm } } +impl From for SignatureVerificationOperation { + fn from(value: SignatureVerificationOperationWasm) -> Self { + value.0 + } +} + #[wasm_bindgen(js_class=SignatureVerificationOperation)] impl SignatureVerificationOperationWasm { #[wasm_bindgen(constructor)] diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 2916d16696f..1dc022b9d63 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -1,5 +1,6 @@ use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use dpp::state_transition::fee::operations::Operation; use wasm_bindgen::prelude::*; pub mod errors; @@ -8,7 +9,9 @@ pub mod state_transition_factory; pub mod fee; pub mod validation; +use crate::state_transition::conversion::create_operation_from_wasm_instance; use crate::utils::Inner; +pub use fee::*; pub use validation::*; pub(crate) mod conversion; @@ -69,6 +72,30 @@ impl StateTransitionExecutionContextWasm { pub fn disable_dry_run(&self) { self.0.disable_dry_run(); } + + #[wasm_bindgen(js_name=addOperation)] + pub fn add_operation(&self, operation: JsValue) -> Result<(), JsValue> { + let operation = create_operation_from_wasm_instance(&operation)?; + self.0.add_operation(operation); + Ok(()) + } + + #[wasm_bindgen(js_name=getOperations)] + pub fn get_operation(&self) -> Vec { + let operations = self.0.get_operations(); + operations + .iter() + .map(|operation| match operation { + Operation::PreCalculated(operation) => { + PreCalculatedOperationWasm::from(operation.to_owned()).into() + } + Operation::Read(operation) => ReadOperationWasm::from(operation.to_owned()).into(), + Operation::SignatureVerification(operation) => { + SignatureVerificationOperationWasm::from(operation.to_owned()).into() + } + }) + .collect() + } } impl Inner for StateTransitionExecutionContextWasm { diff --git a/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js b/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js index ac0a4d484d0..8124b8c688f 100644 --- a/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/DataContractFacade.spec.js @@ -1,4 +1,5 @@ const getDataContractJSFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); +const crypto = require('crypto'); const getBlsAdapterMock = require('../../../lib/test/mocks/getBlsAdapterMock'); const { default: loadWasmDpp } = require('../../..'); @@ -24,7 +25,9 @@ describe('DataContractFacade', () => { beforeEach(async () => { blsAdapter = await getBlsAdapterMock(); - dpp = new DashPlatformProtocol(1, blsAdapter); + dpp = new DashPlatformProtocol( + blsAdapter, {}, { generate: () => crypto.randomBytes(32) }, 1, + ); dataContractJs = await getDataContractJSFixture(); rawDataContract = dataContractJs.toObject(); diff --git a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js index 860f8c20f29..a330bef2fd4 100644 --- a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js +++ b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js @@ -1,3 +1,4 @@ +const crypto = require('crypto'); const generateRandomIdentifier = require('@dashevo/dpp/lib/test/utils/generateRandomIdentifier'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); @@ -45,7 +46,12 @@ describe('DocumentFacade', () => { stateRepositoryMock.fetchDataContract.resolves(dataContract); blsAdapter = await getBlsAdapterMock(); - dpp = new DashPlatformProtocol(blsAdapter, stateRepositoryMock, 1); + dpp = new DashPlatformProtocol( + blsAdapter, + stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, + 1, + ); documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { diff --git a/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js b/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js index 2b873a88062..734b8f7bb60 100644 --- a/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js +++ b/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js @@ -1,3 +1,4 @@ +const crypto = require('crypto'); const getIdentityFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityFixture'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); @@ -43,7 +44,12 @@ describe('IdentityFacade', () => { height: 42, }); - dpp = new DashPlatformProtocol(getBlsAdapterMock(), stateRepositoryMock, 1); + dpp = new DashPlatformProtocol( + getBlsAdapterMock(), + stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, + 1, + ); const chainAssetLockProofJS = getChainAssetLockProofFixture(); const instantAssetLockProofJS = getInstantAssetLockProofFixture(); diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 81936a835e6..e0af52de689 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -1,4 +1,5 @@ const { PrivateKey } = require('@dashevo/dashcore-lib'); +const crypto = require('crypto'); const getIdentityCreateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityCreateTransitionFixture'); @@ -108,7 +109,12 @@ describe('StateTransitionFacade', () => { const blsAdapter = await getBlsAdapterMock(); - dpp = new DashPlatformProtocol(blsAdapter, stateRepositoryMock, 1); + dpp = new DashPlatformProtocol( + blsAdapter, + stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, + 1, + ); }); describe('createFromObject', () => { diff --git a/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js b/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js index 4e84d029075..05e88638cdc 100644 --- a/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js +++ b/packages/wasm-dpp/test/unit/DashPlatformProtocol.spec.js @@ -1,3 +1,4 @@ +const crypto = require('crypto'); const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); const createStateRepositoryMock = require('../../lib/test/mocks/createStateRepositoryMock'); @@ -16,6 +17,7 @@ describe('DashPlatformProtocol', () => { dpp = new DashPlatformProtocol( getBlsAdapterMock(), stateRepositoryMock, + { generate: () => crypto.randomBytes(32) }, protocolVersion.latestVersion, ); }); diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionExecutionContext.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionExecutionContext.spec.js new file mode 100644 index 00000000000..7975bd4690c --- /dev/null +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionExecutionContext.spec.js @@ -0,0 +1,52 @@ +const { expect } = require('chai'); +const { default: loadWasmDpp } = require('../../../dist'); + +describe('StateTransitionExecutionContext', () => { + let ReadOperation; + let PreCalculatedOperation; + let SignatureVerificationOperation; + let StateTransitionExecutionContext; + + let executionContext; + + before(async () => { + ({ + ReadOperation, + PreCalculatedOperation, + SignatureVerificationOperation, + StateTransitionExecutionContext, + } = await loadWasmDpp()); + }); + + beforeEach(() => { + executionContext = new StateTransitionExecutionContext(); + }); + + describe('should add operation', () => { + it('should add ReadOperation', () => { + executionContext.addOperation(new ReadOperation(100)); + const operations = executionContext.getOperations(); + expect(operations[0]).to.be.instanceOf(ReadOperation); + }); + + it('should add SignatureVerificationOperation', () => { + executionContext.addOperation(new SignatureVerificationOperation(0)); + const operations = executionContext.getOperations(); + expect(operations[0]).to.be.instanceOf(SignatureVerificationOperation); + }); + + it('should add PreCalculatedOperation', () => { + executionContext.addOperation(new PreCalculatedOperation(1, 1, [])); + const operations = executionContext.getOperations(); + expect(operations[0]).to.be.instanceOf(PreCalculatedOperation); + }); + + it('should throw Error for unknown operation', () => { + try { + executionContext.addOperation({}); + } catch (e) { + expect(e.message).to.equal('Unknown operation'); + } + }); + }); +});