diff --git a/Cargo.lock b/Cargo.lock index ba2ed10273d..f083b913129 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1563,9 +1563,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libloading" diff --git a/packages/js-dpp/lib/errors/consensus/codes.js b/packages/js-dpp/lib/errors/consensus/codes.js index 91883e22770..3511cedcda5 100644 --- a/packages/js-dpp/lib/errors/consensus/codes.js +++ b/packages/js-dpp/lib/errors/consensus/codes.js @@ -66,7 +66,7 @@ const IncompatibleRe2PatternError = require('./basic/dataContract/IncompatibleRe const InvalidDataContractVersionError = require('./basic/dataContract/InvalidDataContractVersionError'); const IncompatibleDataContractSchemaError = require('./basic/dataContract/IncompatibleDataContractSchemaError'); const DataContractImmutablePropertiesUpdateError = require('./basic/dataContract/DataContractImmutablePropertiesUpdateError'); -const DataContractIndicesChangedError = require('./basic/dataContract/DataContractUniqueIndicesChangedError'); +const DataContractUniqueIndicesChangedError = require('./basic/dataContract/DataContractUniqueIndicesChangedError'); const DuplicateIndexNameError = require('./basic/dataContract/DuplicateIndexNameError'); const DataContractInvalidIndexDefinitionUpdateError = require('./basic/dataContract/DataContractInvalidIndexDefinitionUpdateError'); const DataContractHaveNewUniqueIndexError = require('./basic/dataContract/DataContractHaveNewUniqueIndexError'); @@ -116,7 +116,7 @@ const codes = { 1050: InvalidDataContractVersionError, 1051: IncompatibleDataContractSchemaError, 1052: DataContractImmutablePropertiesUpdateError, - 1053: DataContractIndicesChangedError, + 1053: DataContractUniqueIndicesChangedError, 1054: DataContractInvalidIndexDefinitionUpdateError, 1055: DataContractHaveNewUniqueIndexError, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs index 9ac340b5d2e..7434ff39d72 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -1,41 +1,42 @@ +use anyhow::anyhow; +use serde_json::Value as JsonValue; +use sha2::digest::generic_array::functional::FunctionalSequence; use std::collections::{hash_map::Entry, HashMap}; -use crate::document::document_transition::{DocumentBaseTransition, DocumentTransition}; +use crate::document::document_transition::{ + DocumentBaseTransition, DocumentTransition, DocumentTransitionObjectLike, +}; use crate::util::string_encoding::Encoding; /// Find the duplicates in the collection of Document Transitions pub fn find_duplicates_by_id<'a>( - document_transitions: impl IntoIterator, -) -> Vec<&'a DocumentTransition> { - let mut fingerprints: HashMap = HashMap::new(); - let mut duplicates: Vec<&DocumentTransition> = vec![]; + document_transitions: impl IntoIterator, +) -> Result, anyhow::Error> { + let mut fingerprints: HashMap = HashMap::new(); + let mut duplicates: Vec = vec![]; - for dt in document_transitions { - match fingerprints.entry(create_fingerprint(dt)) { - Entry::Occupied(_) => { - duplicates.push(dt); + for transition in document_transitions { + let fingerprint = create_fingerprint(&transition).ok_or(anyhow!( + "Can't create fingerprint from a document transition" + ))?; + match fingerprints.entry(fingerprint.clone()) { + Entry::Occupied(val) => { + duplicates.push(val.get().clone()); } Entry::Vacant(v) => { - v.insert(()); + v.insert(transition.clone()); } } } - duplicates + Ok(duplicates) } -fn create_fingerprint(document_transition: &DocumentTransition) -> String { - match document_transition { - DocumentTransition::Create(ref dt) => fingerprint(&dt.base), - DocumentTransition::Delete(ref dt) => fingerprint(&dt.base), - DocumentTransition::Replace(ref dt) => fingerprint(&dt.base), - } -} -fn fingerprint(document: &DocumentBaseTransition) -> String { - format!( +fn create_fingerprint(document_transition: &JsonValue) -> Option { + Some(format!( "{}:{}", - document.data_contract_id.to_string(Encoding::Base58), - document.document_type - ) + document_transition.as_object()?.get("$type")?, + document_transition.as_object()?.get("id")?, + )) } #[cfg(test)] diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 711e5a96788..2f52d09914f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -3,6 +3,7 @@ use std::{ convert::{TryFrom, TryInto}, }; +use crate::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; use crate::{ consensus::basic::BasicError, data_contract::{ @@ -209,7 +210,7 @@ fn validate_raw_transitions<'a>( for raw_document_transition in raw_document_transitions.iter() { let document_type = match raw_document_transition.get_string("$type") { Err(_) => { - result.add_error(BasicError::MissingDocumentTypeError); + result.add_error(BasicError::MissingDocumentTransitionTypeError); return Ok(result); } @@ -292,8 +293,7 @@ fn validate_raw_transitions<'a>( let raw_document_transitions_iter = raw_document_transitions.into_iter(); - let duplicate_transitions = - find_duplicates_by_indices(raw_document_transitions_iter.clone(), data_contract)?; + let duplicate_transitions = find_duplicates_by_id(raw_document_transitions_iter.clone())?; if !duplicate_transitions.is_empty() { let references: Vec<(String, Vec)> = duplicate_transitions .iter() @@ -306,6 +306,20 @@ fn validate_raw_transitions<'a>( result.add_error(BasicError::DuplicateDocumentTransitionsWithIdsError { references }); } + let duplicate_transitions_by_indices = + find_duplicates_by_indices(raw_document_transitions_iter.clone(), data_contract)?; + if !duplicate_transitions_by_indices.is_empty() { + let references: Vec<(String, Vec)> = duplicate_transitions_by_indices + .iter() + .map(|t| { + let doc_type = t.get_string("$type")?.to_string(); + let id = t.get_bytes("$id")?; + Ok((doc_type, id)) + }) + .collect::)>, anyhow::Error>>()?; + result.add_error(BasicError::DuplicateDocumentTransitionsWithIndicesError { references }); + } + let validation_result = validate_partial_compound_indices( raw_document_transitions_iter .clone() diff --git a/packages/rs-dpp/src/errors/codes.rs b/packages/rs-dpp/src/errors/codes.rs index 4fe5045e6d4..c0db2664d05 100644 --- a/packages/rs-dpp/src/errors/codes.rs +++ b/packages/rs-dpp/src/errors/codes.rs @@ -25,8 +25,8 @@ impl ErrorWithCode for ConsensusError { Self::IncompatibleProtocolVersionError(_) => 1003, // Identity - Self::DuplicatedIdentityPublicKeyError(_) => 1029, - Self::DuplicatedIdentityPublicKeyIdError(_) => 1030, + Self::DuplicatedIdentityPublicKeyBasicError(_) => 1029, + Self::DuplicatedIdentityPublicKeyBasicIdError(_) => 1030, Self::IdentityAssetLockProofLockedTransactionMismatchError(_) => 1031, Self::IdentityAssetLockTransactionIsNotFoundError(_) => 1032, Self::IdentityAssetLockTransactionOutPointAlreadyExistsError(_) => 1033, @@ -103,12 +103,14 @@ impl ErrorWithCode for BasicError { // Document Self::DataContractNotPresent { .. } => 1018, Self::InvalidDocumentTypeError { .. } => 1024, - Self::MissingDocumentTypeError { .. } => 1027, + Self::MissingDocumentTransitionTypeError { .. } => 1027, Self::MissingDocumentTransitionActionError { .. } => 1026, + Self::MissingDocumentTypeError => 1028, Self::InvalidDocumentTransitionIdError { .. } => 1023, Self::InvalidDocumentTransitionActionError { .. } => 1022, Self::DuplicateDocumentTransitionsWithIdsError { .. } => 1019, + Self::DuplicateDocumentTransitionsWithIndicesError { .. } => 1020, Self::MissingDataContractIdError => 1025, Self::InvalidIdentifierError { .. } => 1006, @@ -122,7 +124,7 @@ impl ErrorWithCode for BasicError { Self::DataContractImmutablePropertiesUpdateError { .. } => 1052, Self::IncompatibleDataContractSchemaError { .. } => 1051, - Self::DataContractUniqueIndicesChangedError { .. } => 4016, + Self::DataContractUniqueIndicesChangedError { .. } => 1053, // TODO - they don't have error codes in https://github.com/dashevo/platform/blob/25ab6d8a38880eaff6ac119126b2ee5991b2a5aa/packages/js-dpp/lib/errors/consensus/codes.js Self::DataContractHaveNewUniqueIndexError { .. } => 0, Self::DataContractInvalidIndexDefinitionUpdateError { .. } => 0, diff --git a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs index 9b2a4392dde..83652786526 100644 --- a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs +++ b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs @@ -39,13 +39,13 @@ pub enum ConsensusError { #[error("{0}")] IncompatibleProtocolVersionError(IncompatibleProtocolVersionError), #[error("{0}")] - DuplicatedIdentityPublicKeyIdError(DuplicatedIdentityPublicKeyIdError), + DuplicatedIdentityPublicKeyBasicIdError(DuplicatedIdentityPublicKeyIdError), #[error("{0}")] InvalidIdentityPublicKeyDataError(InvalidIdentityPublicKeyDataError), #[error("{0}")] InvalidIdentityPublicKeySecurityLevelError(InvalidIdentityPublicKeySecurityLevelError), #[error("{0}")] - DuplicatedIdentityPublicKeyError(DuplicatedIdentityPublicKeyError), + DuplicatedIdentityPublicKeyBasicError(DuplicatedIdentityPublicKeyError), #[error("{0}")] MissingMasterPublicKeyError(MissingMasterPublicKeyError), #[error("{0}")] @@ -144,8 +144,8 @@ impl ConsensusError { ConsensusError::IncompatibleProtocolVersionError(_) => 1003, // Identity - ConsensusError::DuplicatedIdentityPublicKeyError(_) => 1029, - ConsensusError::DuplicatedIdentityPublicKeyIdError(_) => 1030, + ConsensusError::DuplicatedIdentityPublicKeyBasicError(_) => 1029, + ConsensusError::DuplicatedIdentityPublicKeyBasicIdError(_) => 1030, ConsensusError::IdentityAssetLockProofLockedTransactionMismatchError(_) => 1031, ConsensusError::IdentityAssetLockTransactionIsNotFoundError(_) => 1032, ConsensusError::IdentityAssetLockTransactionOutPointAlreadyExistsError(_) => 1033, @@ -204,7 +204,7 @@ impl From for ConsensusError { impl From for ConsensusError { fn from(error: DuplicatedIdentityPublicKeyIdError) -> Self { - Self::DuplicatedIdentityPublicKeyIdError(error) + Self::DuplicatedIdentityPublicKeyBasicIdError(error) } } @@ -222,7 +222,7 @@ impl From for ConsensusError { impl From for ConsensusError { fn from(error: DuplicatedIdentityPublicKeyError) -> Self { - Self::DuplicatedIdentityPublicKeyError(error) + Self::DuplicatedIdentityPublicKeyBasicError(error) } } diff --git a/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs index 10285b92634..ca52aa8191a 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs @@ -47,6 +47,9 @@ pub enum BasicError { document_type: String, }, + #[error("$type is not present")] + MissingDocumentTransitionTypeError, + #[error("$type is not present")] MissingDocumentTypeError, @@ -69,6 +72,12 @@ pub enum BasicError { #[error("Document transitions with duplicate IDs {:?}", references)] DuplicateDocumentTransitionsWithIdsError { references: Vec<(String, Vec)> }, + #[error( + "Document transitions with duplicate unique properties: {:?}", + references + )] + DuplicateDocumentTransitionsWithIndicesError { references: Vec<(String, Vec)> }, + #[error("$dataContractId is not present")] MissingDataContractIdError, diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 3f1a9c8aea1..d17d11fdfa1 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -340,7 +340,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_key_ids() { let errors = assert_consensus_errors!( result, - ConsensusError::DuplicatedIdentityPublicKeyIdError, + ConsensusError::DuplicatedIdentityPublicKeyBasicIdError, 1 ); let consensus_error = result.errors().first().unwrap(); @@ -372,8 +372,11 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { ); let result = validator.validate_keys(&raw_public_keys).unwrap(); - let errors = - assert_consensus_errors!(&result, ConsensusError::DuplicatedIdentityPublicKeyError, 1); + let errors = assert_consensus_errors!( + &result, + ConsensusError::DuplicatedIdentityPublicKeyBasicError, + 1 + ); let consensus_error = result.errors().first().unwrap(); let error = errors.get(0).unwrap(); diff --git a/packages/rs-drive/src/common/helpers/setup.rs b/packages/rs-drive/src/common/helpers/setup.rs index 24e9362aa4b..6ef37a375cf 100644 --- a/packages/rs-drive/src/common/helpers/setup.rs +++ b/packages/rs-drive/src/common/helpers/setup.rs @@ -61,7 +61,7 @@ pub fn setup_drive(drive_config: Option) -> Drive { /// Sets up Drive with the initial state structure. pub fn setup_drive_with_initial_state_structure() -> Drive { - let drive = setup_drive(Some(DriveConfig{ + let drive = setup_drive(Some(DriveConfig { batching_consistency_verification: true, ..Default::default() })); diff --git a/packages/rs-drive/src/drive/object_size_info.rs b/packages/rs-drive/src/drive/object_size_info.rs index 8c2a70e1491..ae2540a4a26 100644 --- a/packages/rs-drive/src/drive/object_size_info.rs +++ b/packages/rs-drive/src/drive/object_size_info.rs @@ -261,7 +261,11 @@ impl<'a, const N: usize> PathKeyInfo<'a, N> { (*path_iterator).iter().map(|a| a.len() as u32).sum::() + key.len() as u32 } PathKeySize(key_info_path, key_size) => { - key_info_path.iterator().map(|a| a.max_length() as u32).sum::() + key_size.max_length() as u32 + key_info_path + .iterator() + .map(|a| a.max_length() as u32) + .sum::() + + key_size.max_length() as u32 } } } diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index e75499a8e70..a46a20327e7 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -1257,8 +1257,8 @@ impl<'a> DriveQuery<'a> { let element = Element::deserialize(value).unwrap(); match element { Element::Item(val, _) => values.push(val), - | Element::SumItem(val, _) => values.push(val.to_be_bytes().to_vec()), - Element::Tree(..) | Element::SumTree(..) | Element::Reference(..) => { + Element::SumItem(val, _) => values.push(val.to_be_bytes().to_vec()), + Element::Tree(..) | Element::SumTree(..) | Element::Reference(..) => { return Err(Error::GroveDB(GroveError::InvalidQuery( "path query should only point to items: got trees", ))); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 566dd53b7d4..1d11b1a4fc1 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -256,7 +256,8 @@ fn test_query_historical() { assert_eq!( root_hash.as_slice(), vec![ - 49, 205, 177, 218, 169, 224, 236, 206, 112, 34, 163, 112, 222, 73, 92, 82, 189, 120, 135, 32, 13, 65, 253, 139, 167, 209, 146, 1, 81, 127, 38, 61 + 49, 205, 177, 218, 169, 224, 236, 206, 112, 34, 163, 112, 222, 73, 92, 82, 189, 120, + 135, 32, 13, 65, 253, 139, 167, 209, 146, 1, 81, 127, 38, 61 ] ); @@ -1534,7 +1535,8 @@ fn test_query_historical() { assert_eq!( root_hash.as_slice(), vec![ - 200, 234, 81, 179, 120, 70, 117, 20, 202, 219, 197, 168, 20, 96, 55, 130, 62, 243, 181, 198, 88, 50, 225, 68, 205, 54, 191, 136, 37, 65, 113, 200 + 200, 234, 81, 179, 120, 70, 117, 20, 202, 219, 197, 168, 20, 96, 55, 130, 62, 243, 181, + 198, 88, 50, 225, 68, 205, 54, 191, 136, 37, 65, 113, 200 ] ); } diff --git a/packages/wasm-dpp/lib/dpp.ts b/packages/wasm-dpp/lib/dpp.ts new file mode 100644 index 00000000000..8e3fd34920c --- /dev/null +++ b/packages/wasm-dpp/lib/dpp.ts @@ -0,0 +1,24 @@ +import * as dpp_module from '../wasm/wasm_dpp'; +import { patchConsensusErrors } from './errors/patchConsensusErrors'; + +patchConsensusErrors(); + +// While we declared it above, those fields do not hold any values - let's assign them. +// We need to suppress the compiler here, as he won't be happy about those reassignments. +// @ts-ignore +dpp_module.IdentityPublicKey.TYPES = dpp_module.KeyType; +// @ts-ignore +dpp_module.IdentityPublicKey.PURPOSES = dpp_module.KeyPurpose; +// @ts-ignore +dpp_module.IdentityPublicKey.SECURITY_LEVELS = dpp_module.KeySecurityLevel; + +export * from '../wasm/wasm_dpp'; +export * from './errors/AbstractConsensusError'; +export * from './errors/DPPError'; + +// Declarations written prior to "export *" will overwrite exports +export declare class IdentityPublicKey extends dpp_module.IdentityPublicKey { + static TYPES: typeof dpp_module.KeyType; + static PURPOSES: typeof dpp_module.KeyPurpose; + static SECURITY_LEVELS: typeof dpp_module.KeySecurityLevel; +} diff --git a/packages/wasm-dpp/lib/errors/AbstractConsensusError.ts b/packages/wasm-dpp/lib/errors/AbstractConsensusError.ts new file mode 100644 index 00000000000..0cc87cd9c83 --- /dev/null +++ b/packages/wasm-dpp/lib/errors/AbstractConsensusError.ts @@ -0,0 +1,13 @@ +import { DPPError } from './DPPError' + +/** + * @abstract + */ +export class AbstractConsensusError extends DPPError { + /** + * @param {string} message + */ + constructor(message: string) { + super(message); + } +} diff --git a/packages/wasm-dpp/lib/errors/DPPError.ts b/packages/wasm-dpp/lib/errors/DPPError.ts new file mode 100644 index 00000000000..395c92427eb --- /dev/null +++ b/packages/wasm-dpp/lib/errors/DPPError.ts @@ -0,0 +1,15 @@ +export class DPPError extends Error { + name: string; + message: string; + + constructor(message: string) { + super(); + + this.name = this.constructor.name; + this.message = message; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } +} diff --git a/packages/wasm-dpp/lib/errors/patchConsensusErrors.ts b/packages/wasm-dpp/lib/errors/patchConsensusErrors.ts new file mode 100644 index 00000000000..5eafb514dce --- /dev/null +++ b/packages/wasm-dpp/lib/errors/patchConsensusErrors.ts @@ -0,0 +1,175 @@ +import * as dpp_module from '../../wasm/wasm_dpp'; +import { extend } from "../utils/extend"; +import { AbstractConsensusError } from "./AbstractConsensusError"; + +const { + ProtocolVersionParsingError, + UnsupportedProtocolVersionError, + IncompatibleProtocolVersionError, + SerializedObjectParsingError, + JsonSchemaError, + InvalidIdentifierError, + DataContractMaxDepthExceedError, + DuplicateIndexError, + InvalidCompoundIndexError, + InvalidDataContractIdError, + InvalidIndexedPropertyConstraintError, + InvalidIndexPropertyTypeError, + SystemPropertyIndexAlreadyPresentError, + UndefinedIndexPropertyError, + UniqueIndicesLimitReachedError, + InconsistentCompoundIndexDataError, + InvalidDocumentTransitionActionError, + InvalidDocumentTransitionIdError, + DataContractNotPresentError, + InvalidDocumentTypeError, + MissingDataContractIdError, + MissingDocumentTransitionActionError, + MissingDocumentTransitionTypeError, + MissingDocumentTypeError, + DuplicatedIdentityPublicKeyError, + DuplicatedIdentityPublicKeyIdError, + MissingMasterPublicKeyError, + IdentityAssetLockProofLockedTransactionMismatchError, + IdentityAssetLockTransactionIsNotFoundError, + IdentityAssetLockTransactionOutPointAlreadyExistsError, + IdentityAssetLockTransactionOutputNotFoundError, + InvalidAssetLockProofCoreChainHeightError, + InvalidAssetLockProofTransactionHeightError, + InvalidIdentityAssetLockTransactionError, + InvalidIdentityAssetLockTransactionOutputError, + InvalidIdentityPublicKeyDataError, + InvalidIdentityPublicKeySecurityLevelError, + InvalidStateTransitionTypeError, + MissingStateTransitionTypeError, + StateTransitionMaxSizeExceededError, + IdentityNotFoundError, + InvalidIdentityPublicKeyTypeError, + InvalidStateTransitionSignatureError, + MissingPublicKeyError, + BalanceIsNotEnoughError, + DataContractAlreadyPresentError, + DataTriggerConditionError, + DataTriggerExecutionError, + DataTriggerInvalidResultError, + DocumentAlreadyPresentError, + DocumentNotFoundError, + DocumentOwnerIdMismatchError, + DocumentTimestampsMismatchError, + DocumentTimestampWindowViolationError, + DuplicateUniqueIndexError, + InvalidDocumentRevisionError, + IdentityAlreadyExistsError, + InvalidJsonSchemaRefError, + JsonSchemaCompilationError, + DuplicateDocumentTransitionsWithIdsError, + DuplicateDocumentTransitionsWithIndicesError, + InvalidAssetLockTransactionOutputReturnSizeError, + InvalidInstantAssetLockProofError, + InvalidInstantAssetLockProofSignatureError, + IncompatibleRe2PatternError, + InvalidDataContractVersionError, + IncompatibleDataContractSchemaError, + DataContractImmutablePropertiesUpdateError, + DataContractUniqueIndicesChangedError, + DuplicateIndexNameError, + DataContractInvalidIndexDefinitionUpdateError, + DataContractHaveNewUniqueIndexError, + IdentityPublicKeyDisabledAtWindowViolationError, + IdentityPublicKeyIsReadOnlyError, + InvalidIdentityPublicKeyIdError, + InvalidIdentityRevisionError, + MaxIdentityPublicKeyLimitReachedError, + InvalidIdentityKeySignatureError, + InvalidSignaturePublicKeySecurityLevelError, + PublicKeyIsDisabledError, + PublicKeySecurityLevelNotMetError, + WrongPublicKeyPurposeError, + IdentityPublicKeyIsDisabledError, +} = dpp_module; + +export function patchConsensusErrors() { + extend(ProtocolVersionParsingError, AbstractConsensusError); + extend(UnsupportedProtocolVersionError, AbstractConsensusError); + extend(IncompatibleProtocolVersionError, AbstractConsensusError); + extend(SerializedObjectParsingError, AbstractConsensusError); + extend(JsonSchemaError, AbstractConsensusError); + extend(InvalidIdentifierError, AbstractConsensusError); + extend(DataContractMaxDepthExceedError, AbstractConsensusError); + extend(DuplicateIndexError, AbstractConsensusError); + extend(InvalidCompoundIndexError, AbstractConsensusError); + extend(InvalidDataContractIdError, AbstractConsensusError); + extend(InvalidIndexedPropertyConstraintError, AbstractConsensusError); + extend(InvalidIndexPropertyTypeError, AbstractConsensusError); + extend(SystemPropertyIndexAlreadyPresentError, AbstractConsensusError); + extend(UndefinedIndexPropertyError, AbstractConsensusError); + extend(UniqueIndicesLimitReachedError, AbstractConsensusError); + extend(InconsistentCompoundIndexDataError, AbstractConsensusError); + extend(InvalidDocumentTransitionActionError, AbstractConsensusError); + extend(InvalidDocumentTransitionIdError, AbstractConsensusError); + extend(DataContractNotPresentError, AbstractConsensusError); + extend(InvalidDocumentTypeError, AbstractConsensusError); + extend(MissingDataContractIdError, AbstractConsensusError); + extend(MissingDocumentTransitionActionError, AbstractConsensusError); + extend(MissingDocumentTransitionTypeError, AbstractConsensusError); + extend(MissingDocumentTypeError, AbstractConsensusError); + extend(DuplicatedIdentityPublicKeyError, AbstractConsensusError); + extend(DuplicatedIdentityPublicKeyIdError, AbstractConsensusError); + extend(MissingMasterPublicKeyError, AbstractConsensusError); + extend(IdentityAssetLockProofLockedTransactionMismatchError, AbstractConsensusError); + extend(IdentityAssetLockTransactionIsNotFoundError, AbstractConsensusError); + extend(IdentityAssetLockTransactionOutPointAlreadyExistsError, AbstractConsensusError); + extend(IdentityAssetLockTransactionOutputNotFoundError, AbstractConsensusError); + extend(InvalidAssetLockProofCoreChainHeightError, AbstractConsensusError); + extend(InvalidAssetLockProofTransactionHeightError, AbstractConsensusError); + extend(InvalidIdentityAssetLockTransactionError, AbstractConsensusError); + extend(InvalidIdentityAssetLockTransactionOutputError, AbstractConsensusError); + extend(InvalidIdentityPublicKeyDataError, AbstractConsensusError); + extend(InvalidIdentityPublicKeySecurityLevelError, AbstractConsensusError); + extend(InvalidStateTransitionTypeError, AbstractConsensusError); + extend(MissingStateTransitionTypeError, AbstractConsensusError); + extend(StateTransitionMaxSizeExceededError, AbstractConsensusError); + extend(IdentityNotFoundError, AbstractConsensusError); + extend(InvalidIdentityPublicKeyTypeError, AbstractConsensusError); + extend(InvalidStateTransitionSignatureError, AbstractConsensusError); + extend(MissingPublicKeyError, AbstractConsensusError); + extend(BalanceIsNotEnoughError, AbstractConsensusError); + extend(DataContractAlreadyPresentError, AbstractConsensusError); + extend(DataTriggerConditionError, AbstractConsensusError); + extend(DataTriggerExecutionError, AbstractConsensusError); + extend(DataTriggerInvalidResultError, AbstractConsensusError); + extend(DocumentAlreadyPresentError, AbstractConsensusError); + extend(DocumentNotFoundError, AbstractConsensusError); + extend(DocumentOwnerIdMismatchError, AbstractConsensusError); + extend(DocumentTimestampsMismatchError, AbstractConsensusError); + extend(DocumentTimestampWindowViolationError, AbstractConsensusError); + extend(DuplicateUniqueIndexError, AbstractConsensusError); + extend(InvalidDocumentRevisionError, AbstractConsensusError); + extend(IdentityAlreadyExistsError, AbstractConsensusError); + extend(InvalidJsonSchemaRefError, AbstractConsensusError); + extend(JsonSchemaCompilationError, AbstractConsensusError); + extend(DuplicateDocumentTransitionsWithIdsError, AbstractConsensusError); + extend(DuplicateDocumentTransitionsWithIndicesError, AbstractConsensusError); + extend(InvalidAssetLockTransactionOutputReturnSizeError, AbstractConsensusError); + extend(InvalidInstantAssetLockProofError, AbstractConsensusError); + extend(InvalidInstantAssetLockProofSignatureError, AbstractConsensusError); + extend(IncompatibleRe2PatternError, AbstractConsensusError); + extend(InvalidDataContractVersionError, AbstractConsensusError); + extend(IncompatibleDataContractSchemaError, AbstractConsensusError); + extend(DataContractImmutablePropertiesUpdateError, AbstractConsensusError); + extend(DataContractUniqueIndicesChangedError, AbstractConsensusError); + extend(DuplicateIndexNameError, AbstractConsensusError); + extend(DataContractInvalidIndexDefinitionUpdateError, AbstractConsensusError); + extend(DataContractHaveNewUniqueIndexError, AbstractConsensusError); + extend(IdentityPublicKeyDisabledAtWindowViolationError, AbstractConsensusError); + extend(IdentityPublicKeyIsReadOnlyError, AbstractConsensusError); + extend(InvalidIdentityPublicKeyIdError, AbstractConsensusError); + extend(InvalidIdentityRevisionError, AbstractConsensusError); + extend(MaxIdentityPublicKeyLimitReachedError, AbstractConsensusError); + extend(InvalidIdentityKeySignatureError, AbstractConsensusError); + extend(InvalidSignaturePublicKeySecurityLevelError, AbstractConsensusError); + extend(PublicKeyIsDisabledError, AbstractConsensusError); + extend(PublicKeySecurityLevelNotMetError, AbstractConsensusError); + extend(WrongPublicKeyPurposeError, AbstractConsensusError); + extend(IdentityPublicKeyIsDisabledError, AbstractConsensusError); +} diff --git a/packages/wasm-dpp/lib/patchIdentifier.ts b/packages/wasm-dpp/lib/identifier/patchIdentifier.ts similarity index 96% rename from packages/wasm-dpp/lib/patchIdentifier.ts rename to packages/wasm-dpp/lib/identifier/patchIdentifier.ts index 1028b25b570..f30a91cdbcb 100644 --- a/packages/wasm-dpp/lib/patchIdentifier.ts +++ b/packages/wasm-dpp/lib/identifier/patchIdentifier.ts @@ -1,4 +1,4 @@ -import * as dpp_module from "../wasm/wasm_dpp"; +import * as dpp_module from "../dpp"; // import { inspect } from 'util'; export default function (dppModule: typeof dpp_module) { diff --git a/packages/wasm-dpp/index.ts b/packages/wasm-dpp/lib/index.ts similarity index 75% rename from packages/wasm-dpp/index.ts rename to packages/wasm-dpp/lib/index.ts index efea10ea715..b1363e52074 100644 --- a/packages/wasm-dpp/index.ts +++ b/packages/wasm-dpp/lib/index.ts @@ -1,7 +1,8 @@ -import init, * as dpp_module from './wasm/wasm_dpp'; +import init from '../wasm/wasm_dpp'; +import * as dpp_module from './dpp'; // @ts-ignore -import wasmBase from './wasm/wasm_dpp_bg.js'; -import patchIdentifier from "./lib/patchIdentifier"; +import wasmBase from '../wasm/wasm_dpp_bg.js'; +import patchIdentifier from "./identifier/patchIdentifier"; let isInitialized = false; diff --git a/packages/wasm-dpp/lib/test/expect/expectError.js b/packages/wasm-dpp/lib/test/expect/expectError.js index cb54e60cc37..a7e0aff5662 100644 --- a/packages/wasm-dpp/lib/test/expect/expectError.js +++ b/packages/wasm-dpp/lib/test/expect/expectError.js @@ -12,12 +12,14 @@ const expectError = { const wasmDpp = await loadWasmDpp(); if (!errorClass) { // eslint-disable-next-line no-param-reassign - errorClass = wasmDpp.ValidationResult; + errorClass = wasmDpp.AbstractConsensusError; } expect(result).to.be.an.instanceOf(wasmDpp.ValidationResult); expect(result.getErrors()).to.have.lengthOf(count); - result.getErrors().forEach((error) => expect(error).to.be.an.instanceOf(errorClass)); + result.getErrors().forEach((error) => { + expect(error).to.be.an.instanceOf(errorClass); + }); }, /** diff --git a/packages/wasm-dpp/lib/utils/extend.ts b/packages/wasm-dpp/lib/utils/extend.ts new file mode 100644 index 00000000000..b0343e316a8 --- /dev/null +++ b/packages/wasm-dpp/lib/utils/extend.ts @@ -0,0 +1,6 @@ +export function extend(Derived: any, Base: any) { + Object.setPrototypeOf( + Derived.prototype, + Base.prototype, + ); +} diff --git a/packages/wasm-dpp/package.json b/packages/wasm-dpp/package.json index bd8082a72b8..de9b2376d90 100644 --- a/packages/wasm-dpp/package.json +++ b/packages/wasm-dpp/package.json @@ -3,7 +3,7 @@ "version": "0.24.0-dev.11", "description": "The JavaScript implementation of the Dash Platform Protocol", "main": "dist/index.js", - "types": "dist/index.d.ts", + "types": "dist/lib/index.d.ts", "scripts": { "build": "yarn exec scripts/build.sh && webpack", "test": "yarn run test:node && yarn run test:browsers", diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index ca2707f39c5..74c754d1aa5 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -1,10 +1,10 @@ use dpp::data_contract::state_transition::data_contract_create_transition::validation::state::validate_data_contract_create_transition_state::validate_data_contract_create_transition_state as dpp_validate_data_contract_create_transition_state; use wasm_bindgen::prelude::*; +use crate::validation::ValidationResultWasm; use crate::{ errors::from_dpp_err, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - validation_result::ValidationResultWasm, DataContractCreateTransitionWasm, }; @@ -19,6 +19,6 @@ pub async fn validate_data_contract_create_transition_state( &state_transition.into(), ) .await - .map(Into::into) + .map(Into::::into) .map_err(from_dpp_err) } diff --git a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs index 38378a7a168..3a59104bcfb 100644 --- a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs +++ b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs @@ -17,7 +17,7 @@ use crate::{ consensus_error::from_consensus_error, from_dpp_err, protocol_error::from_protocol_error, RustConversionError, }, - validation_result::ValidationResultWasm, + validation::ValidationResultWasm, with_js_error, DataContractCreateTransitionWasm, DataContractParameters, DataContractWasm, }; diff --git a/packages/wasm-dpp/src/errors/consensus/basic/data_contract/data_contract_max_depth_exceed_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/data_contract/data_contract_max_depth_exceed_error.rs index a7dee9fbfa2..38b1df3a3d9 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/data_contract/data_contract_max_depth_exceed_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/data_contract/data_contract_max_depth_exceed_error.rs @@ -1,19 +1,19 @@ use wasm_bindgen::prelude::*; -#[wasm_bindgen(js_name=DataContractMaxDepthError)] -pub struct DataContractMaxDepthErrorWasm { +#[wasm_bindgen(js_name=DataContractMaxDepthExceedError)] +pub struct DataContractMaxDepthExceedErrorWasm { depth: usize, code: u32, } -impl DataContractMaxDepthErrorWasm { +impl DataContractMaxDepthExceedErrorWasm { pub fn new(depth: usize, code: u32) -> Self { - DataContractMaxDepthErrorWasm { depth, code } + DataContractMaxDepthExceedErrorWasm { depth, code } } } #[wasm_bindgen(js_class=DataContractMaxDepthError)] -impl DataContractMaxDepthErrorWasm { +impl DataContractMaxDepthExceedErrorWasm { #[wasm_bindgen(js_name=getDepth)] pub fn get_expected_version(&self) -> usize { self.depth diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs index f70812c43d0..159c6f58517 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs @@ -3,19 +3,19 @@ use std::iter::FromIterator; use wasm_bindgen::prelude::*; #[wasm_bindgen(js_name=DuplicateDocumentTransitionsWithIdsError)] -pub struct DuplicateDocumentTransitionsWithIdsError { +pub struct DuplicateDocumentTransitionsWithIdsErrorWasm { references: Vec<(String, Vec)>, code: u32, } -impl DuplicateDocumentTransitionsWithIdsError { +impl DuplicateDocumentTransitionsWithIdsErrorWasm { pub fn new(references: Vec<(String, Vec)>, code: u32) -> Self { - DuplicateDocumentTransitionsWithIdsError { references, code } + DuplicateDocumentTransitionsWithIdsErrorWasm { references, code } } } #[wasm_bindgen(js_class=DuplicateDocumentTransitionsWithIdsError)] -impl DuplicateDocumentTransitionsWithIdsError { +impl DuplicateDocumentTransitionsWithIdsErrorWasm { #[wasm_bindgen(js_name=getReferences)] pub fn get_references(&self) -> js_sys::Array { self.references diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs new file mode 100644 index 00000000000..ea8aba9e100 --- /dev/null +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs @@ -0,0 +1,36 @@ +use crate::buffer::Buffer; +use std::iter::FromIterator; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(js_name=DuplicateDocumentTransitionsWithIndicesError)] +pub struct DuplicateDocumentTransitionsWithIndicesErrorWasm { + references: Vec<(String, Vec)>, + code: u32, +} + +impl DuplicateDocumentTransitionsWithIndicesErrorWasm { + pub fn new(references: Vec<(String, Vec)>, code: u32) -> Self { + DuplicateDocumentTransitionsWithIndicesErrorWasm { references, code } + } +} + +#[wasm_bindgen(js_class=DuplicateDocumentTransitionsWithIndicesError)] +impl DuplicateDocumentTransitionsWithIndicesErrorWasm { + #[wasm_bindgen(js_name=getReferences)] + pub fn get_references(&self) -> js_sys::Array { + self.references + .iter() + .map(|v| { + js_sys::Array::from_iter(vec![ + JsValue::from(v.0.clone()), + JsValue::from(Buffer::from_bytes(&v.1)), + ]) + }) + .collect() + } + + #[wasm_bindgen(js_name=getCode)] + pub fn get_code(&self) -> u32 { + self.code + } +} diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/missing_document_transition_type_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/missing_document_transition_type_error.rs new file mode 100644 index 00000000000..51f077cf613 --- /dev/null +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/missing_document_transition_type_error.rs @@ -0,0 +1,20 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(js_name=MissingDocumentTransitionTypeError)] +pub struct MissingDocumentTransitionTypeErrorWasm { + code: u32, +} + +impl MissingDocumentTransitionTypeErrorWasm { + pub fn new(code: u32) -> Self { + MissingDocumentTransitionTypeErrorWasm { code } + } +} + +#[wasm_bindgen(js_class=MissingDocumentTransitionTypeError)] +impl MissingDocumentTransitionTypeErrorWasm { + #[wasm_bindgen(js_name=getCode)] + pub fn get_code(&self) -> u32 { + self.code + } +} diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/mod.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/mod.rs index 4f580104f26..43c56685b6f 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/document/mod.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/mod.rs @@ -1,19 +1,23 @@ mod data_contract_not_present_error; mod duplicate_document_transitions_with_ids_error; +mod duplicate_document_transitions_with_indices_error; mod inconsistent_compound_index_data_error; mod invalid_document_transition_action_error; mod invalid_document_transition_id_error; mod invalid_document_type_error; mod missing_data_contract_id_error; mod missing_document_transition_action_error; +mod missing_document_transition_type_error; mod missing_document_type_error; pub use data_contract_not_present_error::*; pub use duplicate_document_transitions_with_ids_error::*; +pub use duplicate_document_transitions_with_indices_error::*; pub use inconsistent_compound_index_data_error::*; pub use invalid_document_transition_action_error::*; pub use invalid_document_transition_id_error::*; pub use invalid_document_type_error::*; pub use missing_data_contract_id_error::*; pub use missing_document_transition_action_error::*; +pub use missing_document_transition_type_error::*; pub use missing_document_type_error::*; diff --git a/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_error.rs index a832527d715..04f8fa90c23 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_error.rs @@ -16,12 +16,12 @@ impl From<&DuplicatedIdentityPublicKeyError> for DuplicatedIdentityPublicKeyErro #[wasm_bindgen(js_class=DuplicatedIdentityPublicKeyError)] impl DuplicatedIdentityPublicKeyErrorWasm { #[wasm_bindgen(js_name=getDuplicatedPublicKeysIds)] - pub fn duplicated_public_keys_ids(&self) -> Vec { + pub fn duplicated_public_keys_ids(&self) -> js_sys::Array { // TODO: key ids probably should be u32 self.inner .duplicated_public_keys_ids() .iter() - .map(|id| *id as u32) + .map(|id| JsValue::from(*id as u32)) .collect() } diff --git a/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_id_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_id_error.rs index 41cde66b3ac..bbf92ba535f 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_id_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/identity/duplicated_identity_public_key_id_error.rs @@ -16,12 +16,12 @@ impl From<&DuplicatedIdentityPublicKeyIdError> for DuplicatedIdentityPublicKeyId #[wasm_bindgen(js_class=DuplicatedIdentityPublicKeyIdError)] impl DuplicatedIdentityPublicKeyIdErrorWasm { #[wasm_bindgen(js_name=getDuplicatedIds)] - pub fn duplicated_ids(&self) -> Vec { + pub fn duplicated_ids(&self) -> js_sys::Array { // TODO: key ids probably should be u32 self.inner .duplicated_ids() .iter() - .map(|id| *id as u32) + .map(|id| JsValue::from(*id as u32)) .collect() } diff --git a/packages/wasm-dpp/src/errors/consensus/basic/identity/invalid_identity_public_key_security_level_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/identity/invalid_identity_public_key_security_level_error.rs index 049d8c7fb0a..99f323eca02 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/identity/invalid_identity_public_key_security_level_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/identity/invalid_identity_public_key_security_level_error.rs @@ -25,12 +25,12 @@ impl InvalidIdentityPublicKeySecurityLevelErrorWasm { self.inner.public_key_id() as u32 } - #[wasm_bindgen(js_name=getPurpose)] + #[wasm_bindgen(js_name=getPublicKeyPurpose)] pub fn purpose(&self) -> u8 { self.inner.purpose() as u8 } - #[wasm_bindgen(js_name=getSecurityLevel)] + #[wasm_bindgen(js_name=getPublicKeySecurityLevel)] pub fn security_level(&self) -> u8 { self.inner.security_level() as u8 } diff --git a/packages/wasm-dpp/src/errors/consensus/basic/json_schema_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/json_schema_error.rs index b8bcf2ba4db..4349e1820f9 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/json_schema_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/json_schema_error.rs @@ -141,7 +141,7 @@ impl From<&ValidationErrorKind> for Params { .build(), ValidationErrorKind::MinItems { limit } => ParamsBuilder::new() .set_keyword("minItems") - .add_param("maximum", Value::from(*limit)) + .add_param("minItems", Value::from(*limit)) .build(), ValidationErrorKind::Minimum { limit } => ParamsBuilder::new() .set_keyword("minimum") diff --git a/packages/wasm-dpp/src/errors/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus_error.rs index 3f089244c11..7dbe69b85e7 100644 --- a/packages/wasm-dpp/src/errors/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus_error.rs @@ -27,7 +27,7 @@ use dpp::consensus::basic::identity::{ }; use dpp::consensus::basic::BasicError; use dpp::consensus::signature::SignatureError; -use dpp::StateError; +use dpp::{ProtocolError, StateError}; use wasm_bindgen::JsValue; use crate::errors::consensus::basic::data_contract::{ @@ -36,8 +36,9 @@ use crate::errors::consensus::basic::data_contract::{ IncompatibleDataContractSchemaErrorWasm, InvalidDataContractIdErrorWasm, }; use crate::errors::consensus::basic::document::{ - DuplicateDocumentTransitionsWithIdsError, InvalidDocumentTransitionActionErrorWasm, - InvalidDocumentTransitionIdErrorWasm, MissingDataContractIdErrorWasm, + DuplicateDocumentTransitionsWithIdsErrorWasm, DuplicateDocumentTransitionsWithIndicesErrorWasm, + InvalidDocumentTransitionActionErrorWasm, InvalidDocumentTransitionIdErrorWasm, + MissingDataContractIdErrorWasm, MissingDocumentTypeErrorWasm, }; use crate::errors::consensus::basic::state_transition::{ InvalidStateTransitionTypeErrorWasm, MissingStateTransitionTypeErrorWasm, @@ -62,7 +63,7 @@ use crate::errors::consensus::state::identity::{ use dpp::errors::DataTriggerError; use super::consensus::basic::data_contract::{ - DataContractMaxDepthErrorWasm, DuplicateIndexErrorWasm, DuplicateIndexNameErrorWasm, + DataContractMaxDepthExceedErrorWasm, DuplicateIndexErrorWasm, DuplicateIndexNameErrorWasm, IncompatibleRe2PatternErrorWasm, InvalidCompoundIndexErrorWasm, InvalidDataContractVersionErrorWasm, InvalidIndexPropertyTypeErrorWasm, InvalidIndexedPropertyConstraintErrorWasm, InvalidJsonSchemaRefErrorWasm, @@ -75,7 +76,7 @@ use super::consensus::basic::decode::{ use super::consensus::basic::document::{ DataContractNotPresentErrorWasm, InconsistentCompoundIndexDataErrorWasm, InvalidDocumentTypeErrorWasm, MissingDocumentTransitionActionErrorWasm, - MissingDocumentTypeErrorWasm, + MissingDocumentTransitionTypeErrorWasm, }; use super::consensus::basic::identity::{ InvalidIdentityPublicKeyTypeErrorWasm, MissingPublicKeyErrorWasm, @@ -99,7 +100,7 @@ pub fn from_consensus_error_ref(e: &DPPConsensusError) -> JsValue { DPPConsensusError::IncompatibleProtocolVersionError(e) => { IncompatibleProtocolVersionErrorWasm::from(e).into() } - DPPConsensusError::DuplicatedIdentityPublicKeyIdError(e) => { + DPPConsensusError::DuplicatedIdentityPublicKeyBasicIdError(e) => { DuplicatedIdentityPublicKeyIdErrorWasm::from(e).into() } DPPConsensusError::InvalidIdentityPublicKeyDataError(e) => { @@ -108,7 +109,7 @@ pub fn from_consensus_error_ref(e: &DPPConsensusError) -> JsValue { DPPConsensusError::InvalidIdentityPublicKeySecurityLevelError(e) => { InvalidIdentityPublicKeySecurityLevelErrorWasm::from(e).into() } - DPPConsensusError::DuplicatedIdentityPublicKeyError(e) => { + DPPConsensusError::DuplicatedIdentityPublicKeyBasicError(e) => { DuplicatedIdentityPublicKeyErrorWasm::from(e).into() } DPPConsensusError::MissingMasterPublicKeyError(e) => { @@ -351,7 +352,7 @@ fn from_basic_error(basic_error: &Box) -> JsValue { version, } => InvalidDataContractVersionErrorWasm::new(*expected_version, *version, code).into(), BasicError::DataContractMaxDepthExceedError(depth) => { - DataContractMaxDepthErrorWasm::new(*depth, code).into() + DataContractMaxDepthExceedErrorWasm::new(*depth, code).into() } BasicError::InvalidDocumentTypeError { document_type, @@ -457,6 +458,9 @@ fn from_basic_error(basic_error: &Box) -> JsValue { code, ) .into(), + BasicError::MissingDocumentTransitionTypeError => { + MissingDocumentTransitionTypeErrorWasm::new(code).into() + } BasicError::MissingDocumentTypeError => MissingDocumentTypeErrorWasm::new(code).into(), BasicError::MissingDocumentTransitionActionError => { MissingDocumentTransitionActionErrorWasm::new(code).into() @@ -472,8 +476,11 @@ fn from_basic_error(basic_error: &Box) -> JsValue { InvalidDocumentTransitionIdErrorWasm::new(expected_id.clone(), invalid_id.clone(), code) .into() } + BasicError::DuplicateDocumentTransitionsWithIndicesError { references } => { + DuplicateDocumentTransitionsWithIndicesErrorWasm::new(references.clone(), code).into() + } BasicError::DuplicateDocumentTransitionsWithIdsError { references } => { - DuplicateDocumentTransitionsWithIdsError::new(references.clone(), code).into() + DuplicateDocumentTransitionsWithIdsErrorWasm::new(references.clone(), code).into() } BasicError::MissingDataContractIdError => MissingDataContractIdErrorWasm::new(code).into(), BasicError::InvalidIdentifierError { diff --git a/packages/wasm-dpp/src/identifier.rs b/packages/wasm-dpp/src/identifier/mod.rs similarity index 100% rename from packages/wasm-dpp/src/identifier.rs rename to packages/wasm-dpp/src/identifier/mod.rs diff --git a/packages/wasm-dpp/src/identity_facade.rs b/packages/wasm-dpp/src/identity/identity_facade.rs similarity index 97% rename from packages/wasm-dpp/src/identity_facade.rs rename to packages/wasm-dpp/src/identity/identity_facade.rs index 284f2c4181e..63e0c5cc87f 100644 --- a/packages/wasm-dpp/src/identity_facade.rs +++ b/packages/wasm-dpp/src/identity/identity_facade.rs @@ -6,7 +6,7 @@ use dpp::identity::validation::PublicKeysValidator; use dpp::identity::IdentityFacade; use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; -use crate::validation_result::ValidationResultWasm; +use crate::validation::ValidationResultWasm; use dpp::version::ProtocolVersionValidator; use dpp::NonConsensusError; diff --git a/packages/wasm-dpp/src/identity_public_key/key_type.rs b/packages/wasm-dpp/src/identity/identity_public_key/key_type.rs similarity index 100% rename from packages/wasm-dpp/src/identity_public_key/key_type.rs rename to packages/wasm-dpp/src/identity/identity_public_key/key_type.rs diff --git a/packages/wasm-dpp/src/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs similarity index 98% rename from packages/wasm-dpp/src/identity_public_key/mod.rs rename to packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 118ee778aa0..93aa1d6788a 100644 --- a/packages/wasm-dpp/src/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -14,9 +14,6 @@ mod security_level; pub use security_level::*; mod key_type; -mod public_keys_validator; - -pub use public_keys_validator::*; pub use key_type::*; diff --git a/packages/wasm-dpp/src/identity_public_key/purpose.rs b/packages/wasm-dpp/src/identity/identity_public_key/purpose.rs similarity index 100% rename from packages/wasm-dpp/src/identity_public_key/purpose.rs rename to packages/wasm-dpp/src/identity/identity_public_key/purpose.rs diff --git a/packages/wasm-dpp/src/identity_public_key/security_level.rs b/packages/wasm-dpp/src/identity/identity_public_key/security_level.rs similarity index 100% rename from packages/wasm-dpp/src/identity_public_key/security_level.rs rename to packages/wasm-dpp/src/identity/identity_public_key/security_level.rs diff --git a/packages/wasm-dpp/src/identity.rs b/packages/wasm-dpp/src/identity/mod.rs similarity index 98% rename from packages/wasm-dpp/src/identity.rs rename to packages/wasm-dpp/src/identity/mod.rs index d475a27eeef..a6b9f67ecb4 100644 --- a/packages/wasm-dpp/src/identity.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -1,3 +1,7 @@ +pub mod identity_facade; +mod identity_public_key; +mod validation; + use js_sys::Array; use serde_json::Value; use wasm_bindgen::prelude::*; @@ -12,8 +16,8 @@ use crate::errors::from_dpp_err; use crate::identifier::IdentifierWrapper; use crate::utils; use crate::utils::to_vec_of_serde_values; -use crate::IdentityPublicKeyWasm; use crate::MetadataWasm; +pub use identity_public_key::*; #[wasm_bindgen(js_name=Identity)] #[derive(Clone)] diff --git a/packages/wasm-dpp/src/identity/validation/mod.rs b/packages/wasm-dpp/src/identity/validation/mod.rs new file mode 100644 index 00000000000..c65f318e96c --- /dev/null +++ b/packages/wasm-dpp/src/identity/validation/mod.rs @@ -0,0 +1,3 @@ +mod public_keys_validator; + +pub use public_keys_validator::*; diff --git a/packages/wasm-dpp/src/identity/validation/public_keys_validator.rs b/packages/wasm-dpp/src/identity/validation/public_keys_validator.rs new file mode 100644 index 00000000000..aca52fca9de --- /dev/null +++ b/packages/wasm-dpp/src/identity/validation/public_keys_validator.rs @@ -0,0 +1,70 @@ +use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; + +use crate::utils::{to_vec_of_serde_values, ToSerdeJSONExt}; +use crate::validation::ValidationResultWasm; +use dpp::identity::validation::{ + PublicKeysValidator, TPublicKeysValidator, PUBLIC_KEY_SCHEMA_FOR_TRANSITION, +}; + +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(js_name = PublicKeysValidator)] +pub struct PublicKeysValidatorWasm { + public_key_validator: PublicKeysValidator, + public_key_in_state_transition_validator: PublicKeysValidator, +} + +#[wasm_bindgen(js_class = PublicKeysValidator)] +impl PublicKeysValidatorWasm { + #[wasm_bindgen(constructor)] + pub fn new(adapter: JsBlsAdapter) -> Result { + Ok(Self { + public_key_validator: PublicKeysValidator::new(BlsAdapter(JsBlsAdapter::from( + adapter.clone(), + )))?, + public_key_in_state_transition_validator: PublicKeysValidator::new_with_schema( + PUBLIC_KEY_SCHEMA_FOR_TRANSITION.clone(), + BlsAdapter(adapter), + )?, + }) + } + + #[wasm_bindgen(js_name=validateKeys)] + pub fn validate_keys( + &self, + public_keys: js_sys::Array, + ) -> Result { + let raw_public_keys = to_vec_of_serde_values(public_keys.iter())?; + + self.public_key_validator + .validate_keys(&raw_public_keys) + .map(ValidationResultWasm::from) + .map_err(|e| JsValue::from(e.to_string())) + } + + #[wasm_bindgen(js_name=validatePublicKeyStructure)] + pub fn validate_public_key_structure( + &self, + public_key: JsValue, + ) -> Result { + let pk_serde_json = public_key.to_serde_json_value()?; + + self.public_key_validator + .validate_public_key_structure(&pk_serde_json) + .map(ValidationResultWasm::from) + .map_err(|e| JsValue::from(e.to_string())) + } + + #[wasm_bindgen(js_name=validateKeysInStateTransition)] + pub fn validate_keys_in_state_transition( + &self, + public_keys: js_sys::Array, + ) -> Result { + let raw_public_keys = to_vec_of_serde_values(public_keys.iter())?; + + self.public_key_in_state_transition_validator + .validate_keys(&raw_public_keys) + .map(ValidationResultWasm::from) + .map_err(|e| JsValue::from(e.to_string())) + } +} diff --git a/packages/wasm-dpp/src/identity_public_key/public_keys_validator.rs b/packages/wasm-dpp/src/identity_public_key/public_keys_validator.rs deleted file mode 100644 index e5faf2834af..00000000000 --- a/packages/wasm-dpp/src/identity_public_key/public_keys_validator.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; - -use crate::utils::{to_vec_of_serde_values, ToSerdeJSONExt}; -use crate::validation_result::ValidationResultWasm; -use dpp::identity::validation::{PublicKeysValidator, TPublicKeysValidator}; - -use wasm_bindgen::prelude::*; - -#[wasm_bindgen(js_name = PublicKeysValidator)] -pub struct PublicKeysValidatorWasm(PublicKeysValidator); - -#[wasm_bindgen(js_class = PublicKeysValidator)] -impl PublicKeysValidatorWasm { - #[wasm_bindgen(constructor)] - pub fn new(adapter: JsBlsAdapter) -> PublicKeysValidatorWasm { - Self(PublicKeysValidator::new(BlsAdapter(adapter)).unwrap()) - } - - #[wasm_bindgen(js_name=validateKeys)] - pub fn validate_keys( - &self, - public_keys: js_sys::Array, - ) -> Result { - let raw_public_keys = to_vec_of_serde_values(public_keys.iter())?; - - self.0 - .validate_keys(&raw_public_keys) - .map(ValidationResultWasm::from) - .map_err(|e| JsValue::from(e.to_string())) - } - - #[wasm_bindgen(js_name=validatePublicKeyStructure)] - pub fn validate_public_key_structure( - &self, - public_key: JsValue, - ) -> Result { - let pk_serde_json = public_key.to_serde_json_value()?; - - self.0 - .validate_public_key_structure(&pk_serde_json) - .map(ValidationResultWasm::from) - .map_err(|e| JsValue::from(e.to_string())) - } -} diff --git a/packages/wasm-dpp/src/lib.rs b/packages/wasm-dpp/src/lib.rs index 199dbf8fc42..85f0a3d858c 100644 --- a/packages/wasm-dpp/src/lib.rs +++ b/packages/wasm-dpp/src/lib.rs @@ -3,9 +3,6 @@ pub use data_contract::*; pub use data_contract_factory::*; pub use document::*; pub use identity::*; -pub use identity::*; -pub use identity_facade::*; -pub use identity_public_key::*; pub use metadata::*; pub use state_transition::*; @@ -16,8 +13,6 @@ mod document; pub mod errors; mod identifier; mod identity; -mod identity_facade; -mod identity_public_key; mod metadata; mod state_repository; mod state_transition; @@ -26,4 +21,4 @@ mod utils; mod bls_adapter; mod buffer; -pub mod validation_result; +mod validation; diff --git a/packages/wasm-dpp/src/validation/mod.rs b/packages/wasm-dpp/src/validation/mod.rs new file mode 100644 index 00000000000..4e80aa1f5db --- /dev/null +++ b/packages/wasm-dpp/src/validation/mod.rs @@ -0,0 +1,3 @@ +mod validation_result; + +pub use validation_result::*; diff --git a/packages/wasm-dpp/src/validation_result.rs b/packages/wasm-dpp/src/validation/validation_result.rs similarity index 100% rename from packages/wasm-dpp/src/validation_result.rs rename to packages/wasm-dpp/src/validation/validation_result.rs diff --git a/packages/wasm-dpp/test/integration/identity/validation/validatePublicKeysFactory.spec.js b/packages/wasm-dpp/test/integration/identity/validation/validatePublicKeysFactory.spec.js index ebc6fedb06e..fff8b951e32 100644 --- a/packages/wasm-dpp/test/integration/identity/validation/validatePublicKeysFactory.spec.js +++ b/packages/wasm-dpp/test/integration/identity/validation/validatePublicKeysFactory.spec.js @@ -1,41 +1,9 @@ -const { getRE2Class } = require('@dashevo/wasm-re2'); - const crypto = require('crypto'); -const createAjv = require('@dashevo/dpp/lib/ajv/createAjv'); - -const JsonSchemaValidator = require( - '@dashevo/dpp/lib/validation/JsonSchemaValidator', -); - -const validatePublicKeysFactory = require( - '@dashevo/dpp/lib/identity/validation/validatePublicKeysFactory', -); - const getIdentityFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityFixture'); -const DuplicatedIdentityPublicKeyError = require( - '@dashevo/dpp/lib/errors/consensus/basic/identity/DuplicatedIdentityPublicKeyError', -); -const DuplicatedIdentityPublicKeyIdError = require( - '@dashevo/dpp/lib/errors/consensus/basic/identity/DuplicatedIdentityPublicKeyIdError', -); - -const InvalidIdentityPublicKeyDataError = require( - '@dashevo/dpp/lib/errors/consensus/basic/identity/InvalidIdentityPublicKeyDataError', -); - -const InvalidIdentityPublicKeySecurityLevelError = require( - '@dashevo/dpp/lib/errors/consensus/basic/identity/InvalidIdentityPublicKeySecurityLevelError', -); - -const IdentityPublicKey = require( - '@dashevo/dpp/lib/identity/IdentityPublicKey', -); const BlsSignatures = require('@dashevo/dpp/lib/bls/bls'); -const identityPublicKeySchema = require('@dashevo/dpp/schema/identity/publicKey.json'); -const stateTransitionPublicKeySchema = require('@dashevo/dpp/schema/identity/stateTransition/publicKey.json'); const { expectValidationError, expectJsonSchemaError, @@ -46,24 +14,29 @@ const { default: loadWasmDpp } = require('../../../../dist'); describe('validatePublicKeysFactory', () => { let rawPublicKeys; let validatePublicKeys; - let validator; let bls; - let PublicKeysValidator; let publicKeysValidator; - let InvalidIdentityPublicKeyDataErrorWasm; + + let PublicKeysValidator; let PublicKeyValidationError; + let IdentityPublicKey; + + let DuplicatedIdentityPublicKeyError; + let DuplicatedIdentityPublicKeyIdError; + let InvalidIdentityPublicKeyDataError; + let InvalidIdentityPublicKeySecurityLevelError; beforeEach(async () => { ({ publicKeys: rawPublicKeys } = getIdentityFixture().toObject()); ({ - PublicKeysValidator, - InvalidIdentityPublicKeyDataError: InvalidIdentityPublicKeyDataErrorWasm, + PublicKeysValidator, IdentityPublicKey, + InvalidIdentityPublicKeyDataError, + DuplicatedIdentityPublicKeyError, DuplicatedIdentityPublicKeyIdError, + InvalidIdentityPublicKeyDataError, InvalidIdentityPublicKeySecurityLevelError, PublicKeyValidationError, } = await loadWasmDpp()); - const RE2 = await getRE2Class(); - const ajv = createAjv(RE2); bls = await BlsSignatures.getInstance(); const blsAdapter = { @@ -80,23 +53,17 @@ describe('validatePublicKeysFactory', () => { }, }; - validator = new JsonSchemaValidator(ajv); - - validatePublicKeys = validatePublicKeysFactory( - validator, - identityPublicKeySchema, - bls, - ); - publicKeysValidator = new PublicKeysValidator(blsAdapter); + + validatePublicKeys = (keys) => publicKeysValidator.validateKeys(keys); }); describe('id', () => { - it('should be present', () => { + it('should be present', async () => { delete rawPublicKeys[1].id; const result = publicKeysValidator.validateKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -105,12 +72,12 @@ describe('validatePublicKeysFactory', () => { expect(error.getParams().missingProperty).to.equal('id'); }); - it('should be a number', () => { + it('should be a number', async () => { rawPublicKeys[1].id = 'string'; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -118,12 +85,12 @@ describe('validatePublicKeysFactory', () => { expect(error.getKeyword()).to.equal('type'); }); - it('should be an integer', () => { + it('should be an integer', async () => { rawPublicKeys[1].id = 1.1; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -131,12 +98,12 @@ describe('validatePublicKeysFactory', () => { expect(error.getKeyword()).to.equal('type'); }); - it('should be greater or equal to one', () => { + it('should be greater or equal to one', async () => { rawPublicKeys[1].id = -1; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -146,12 +113,12 @@ describe('validatePublicKeysFactory', () => { }); describe('type', () => { - it('should be present', () => { + it('should be present', async () => { delete rawPublicKeys[1].type; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result, 4); const [error] = result.getErrors(); @@ -159,27 +126,30 @@ describe('validatePublicKeysFactory', () => { expect(error.getKeyword()).to.equal('minItems'); }); - it('should be a number', () => { + it('should be a number', async () => { rawPublicKeys[1].type = 'string'; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result, 2); - const [error] = result.getErrors(); + const [typeError, enumError] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/type'); - expect(error.getKeyword()).to.equal('type'); + expect(typeError.getInstancePath()).to.equal('/type'); + expect(typeError.getKeyword()).to.equal('type'); + + expect(enumError.getInstancePath()).to.equal('/type'); + expect(enumError.getKeyword()).to.equal('enum'); }); }); describe('data', () => { - it('should be present', () => { + it('should be present', async () => { delete rawPublicKeys[1].data; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -188,28 +158,29 @@ describe('validatePublicKeysFactory', () => { expect(error.getParams().missingProperty).to.equal('data'); }); - it('should be a byte array', () => { + it('should be a byte array', async () => { rawPublicKeys[1].data = new Array(33).fill('string'); const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result, 2); + await expectJsonSchemaError(result, 33); const [error, byteArrayError] = result.getErrors(); expect(error.getInstancePath()).to.equal('/data/0'); expect(error.getKeyword()).to.equal('type'); - expect(byteArrayError.getKeyword()).to.equal('byteArray'); + expect(byteArrayError.getInstancePath()).to.equal('/data/1'); + expect(byteArrayError.getKeyword()).to.equal('type'); }); describe('ECDSA_SECP256K1', () => { - it('should be no less than 33 bytes', () => { + it('should be no less than 33 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(32); const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -217,12 +188,12 @@ describe('validatePublicKeysFactory', () => { expect(error.getKeyword()).to.equal('minItems'); }); - it('should be no longer than 33 bytes', () => { + it('should be no longer than 33 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(34); const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -232,13 +203,13 @@ describe('validatePublicKeysFactory', () => { }); describe('BLS12_381', () => { - it('should be no less than 48 bytes', () => { + it('should be no less than 48 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(47); rawPublicKeys[1].type = 1; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -246,13 +217,13 @@ describe('validatePublicKeysFactory', () => { expect(error.getKeyword()).to.equal('minItems'); }); - it('should be no longer than 48 bytes', () => { + it('should be no longer than 48 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(49); rawPublicKeys[1].type = 1; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -262,13 +233,13 @@ describe('validatePublicKeysFactory', () => { }); describe('ECDSA_HASH160', () => { - it('should be no less than 20 bytes', () => { + it('should be no less than 20 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(19); rawPublicKeys[1].type = 2; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -276,13 +247,13 @@ describe('validatePublicKeysFactory', () => { expect(error.getKeyword()).to.equal('minItems'); }); - it('should be no longer than 20 bytes', () => { + it('should be no longer than 20 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(21); rawPublicKeys[1].type = 2; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -292,13 +263,13 @@ describe('validatePublicKeysFactory', () => { }); describe('BIP13_SCRIPT_HASH', () => { - it('should be no less than 20 bytes', () => { + it('should be no less than 20 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(19); rawPublicKeys[1].type = 3; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -306,13 +277,13 @@ describe('validatePublicKeysFactory', () => { expect(error.getKeyword()).to.equal('minItems'); }); - it('should be no longer than 20 bytes', () => { + it('should be no longer than 20 bytes', async () => { rawPublicKeys[1].data = Buffer.alloc(21); rawPublicKeys[1].type = 3; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); @@ -322,12 +293,12 @@ describe('validatePublicKeysFactory', () => { }); }); - it('should return invalid result if there are duplicate key ids', () => { + it('should return invalid result if there are duplicate key ids', async () => { rawPublicKeys[1].id = rawPublicKeys[0].id; const result = validatePublicKeys(rawPublicKeys); - expectValidationError(result, DuplicatedIdentityPublicKeyIdError); + await expectValidationError(result, DuplicatedIdentityPublicKeyIdError); const [error] = result.getErrors(); @@ -335,12 +306,12 @@ describe('validatePublicKeysFactory', () => { expect(error.getDuplicatedIds()).to.deep.equal([rawPublicKeys[1].id]); }); - it('should return invalid result if there are duplicate keys', () => { + it('should return invalid result if there are duplicate keys', async () => { rawPublicKeys[1].data = rawPublicKeys[0].data; const result = validatePublicKeys(rawPublicKeys); - expectValidationError(result, DuplicatedIdentityPublicKeyError); + await expectValidationError(result, DuplicatedIdentityPublicKeyError); const [error] = result.getErrors(); @@ -348,28 +319,28 @@ describe('validatePublicKeysFactory', () => { expect(error.getDuplicatedPublicKeysIds()).to.deep.equal([rawPublicKeys[1].id]); }); - it('should return invalid result if key data is not a valid DER', () => { + it('should return invalid result if key data is not a valid DER', async () => { rawPublicKeys[1].data = Buffer.alloc(33); const result = validatePublicKeys(rawPublicKeys); - expectValidationError(result, InvalidIdentityPublicKeyDataError); + await expectValidationError(result, InvalidIdentityPublicKeyDataError); const [error] = result.getErrors(); expect(error.getCode()).to.equal(1040); expect(error.getPublicKeyId()).to.deep.equal(rawPublicKeys[1].id); - expect(error.getValidationError()).to.be.instanceOf(TypeError); - expect(error.getValidationError().message).to.equal('Invalid DER format public key'); + expect(error.getValidationError()).to.be.instanceOf(PublicKeyValidationError); + expect(error.getValidationError().message).to.equal('Key secp256k1 error: malformed public key'); }); - it('should return invalid result if key has an invalid combination of purpose and security level', () => { + it('should return invalid result if key has an invalid combination of purpose and security level', async () => { rawPublicKeys[1].purpose = IdentityPublicKey.PURPOSES.ENCRYPTION; rawPublicKeys[1].securityLevel = IdentityPublicKey.SECURITY_LEVELS.MASTER; const result = validatePublicKeys(rawPublicKeys); - expectValidationError(result, InvalidIdentityPublicKeySecurityLevelError); + await expectValidationError(result, InvalidIdentityPublicKeySecurityLevelError); const [error] = result.getErrors(); @@ -395,7 +366,7 @@ describe('validatePublicKeysFactory', () => { data: Buffer.from('01fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694', 'hex'), }]; - const result = publicKeysValidator.validateKeys(rawPublicKeys); + const result = validatePublicKeys(rawPublicKeys); expect(result.isValid()).to.be.true(); }); @@ -427,7 +398,7 @@ describe('validatePublicKeysFactory', () => { const result = publicKeysValidator.validateKeys(rawPublicKeys); - await expectValidationError(result, InvalidIdentityPublicKeyDataErrorWasm); + await expectValidationError(result, InvalidIdentityPublicKeyDataError); const [error] = result.getErrors(); @@ -451,11 +422,7 @@ describe('validatePublicKeysFactory', () => { describe('State Transition Schema', () => { beforeEach(() => { - validatePublicKeys = validatePublicKeysFactory( - validator, - stateTransitionPublicKeySchema, - bls, - ); + validatePublicKeys = (keys) => publicKeysValidator.validateKeysInStateTransition(keys); rawPublicKeys.forEach((rawPublicKey) => { // eslint-disable-next-line no-param-reassign @@ -464,16 +431,16 @@ describe('validatePublicKeysFactory', () => { }); describe('signature', () => { - it('should be present', () => { + it('should be present', async () => { delete rawPublicKeys[0].signature; const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); - expect(error.instancePath).to.equal(''); + expect(error.getInstancePath()).to.equal(''); expect(error.getKeyword()).to.equal('required'); expect(error.getParams().missingProperty).to.equal('signature'); }); @@ -483,39 +450,37 @@ describe('validatePublicKeysFactory', () => { const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result, 2); + await expectJsonSchemaError(result, 65); - const [error, byteArrayError] = result.getErrors(); + const [error] = result.getErrors(); - expect(error.instancePath).to.equal('/signature/0'); expect(error.getKeyword()).to.equal('type'); - - expect(byteArrayError.getKeyword()).to.equal('byteArray'); + expect(error.getInstancePath()).to.equal('/signature/0'); }); - it('should be not shorter than 65 bytes', () => { + it('should be not shorter than 65 bytes', async () => { rawPublicKeys[0].signature = Buffer.alloc(64); const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); - expect(error.instancePath).to.equal('/signature'); + expect(error.getInstancePath()).to.equal('/signature'); expect(error.getKeyword()).to.equal('minItems'); }); - it('should be not longer than 65 bytes', () => { + it('should be not longer than 65 bytes', async () => { rawPublicKeys[0].signature = Buffer.alloc(66); const result = validatePublicKeys(rawPublicKeys); - expectJsonSchemaError(result); + await expectJsonSchemaError(result); const [error] = result.getErrors(); - expect(error.instancePath).to.equal('/signature'); + expect(error.getInstancePath()).to.equal('/signature'); expect(error.getKeyword()).to.equal('maxItems'); }); }); diff --git a/packages/wasm-dpp/test/unit/identity/IdentityPublicKey.spec.js b/packages/wasm-dpp/test/unit/identity/IdentityPublicKey.spec.js index aad2f4dad91..5652950a6ef 100644 --- a/packages/wasm-dpp/test/unit/identity/IdentityPublicKey.spec.js +++ b/packages/wasm-dpp/test/unit/identity/IdentityPublicKey.spec.js @@ -4,24 +4,18 @@ describe('IdentityPublicKey', () => { let rawPublicKey; let publicKey; let IdentityPublicKey; - let KeyPurpose; - let KeyType; - let KeySecurityLevel; beforeEach(async () => { - ({ - IdentityPublicKey, KeyPurpose, KeyType, KeySecurityLevel, - } = await loadWasmDpp()); + ({ IdentityPublicKey } = await loadWasmDpp()); rawPublicKey = { id: 0, - type: KeyType.ECDSA_SECP256K1, + type: IdentityPublicKey.TYPES.ECDSA_SECP256K1, data: Buffer.from('AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH', 'base64'), - purpose: KeyPurpose.AUTHENTICATION, - securityLevel: KeySecurityLevel.MASTER, + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.MASTER, readOnly: false, }; - publicKey = new IdentityPublicKey(rawPublicKey); }); @@ -89,9 +83,9 @@ describe('IdentityPublicKey', () => { describe('#setPurpose', () => { it('should set data', () => { - publicKey.setPurpose(KeyPurpose.DECRYPTION); + publicKey.setPurpose(IdentityPublicKey.PURPOSES.DECRYPTION); - expect(publicKey.getPurpose()).to.equal(KeyPurpose.DECRYPTION); + expect(publicKey.getPurpose()).to.equal(IdentityPublicKey.PURPOSES.DECRYPTION); }); }); @@ -103,9 +97,9 @@ describe('IdentityPublicKey', () => { describe('#setSecurityLevel', () => { it('should set data', () => { - publicKey.setSecurityLevel(KeySecurityLevel.MEDIUM); + publicKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.MEDIUM); - expect(publicKey.getSecurityLevel()).to.equal(KeySecurityLevel.MEDIUM); + expect(publicKey.getSecurityLevel()).to.equal(IdentityPublicKey.SECURITY_LEVELS.MEDIUM); }); }); @@ -151,10 +145,10 @@ describe('IdentityPublicKey', () => { it('should return data in case ECDSA_HASH160', () => { rawPublicKey = { id: 0, - type: KeyType.ECDSA_HASH160, + type: IdentityPublicKey.TYPES.ECDSA_HASH160, data: Buffer.from('AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH', 'base64'), - purpose: KeyPurpose.AUTHENTICATION, - securityLevel: KeySecurityLevel.MASTER, + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.MASTER, readOnly: false, disabledAt: 123, }; @@ -171,10 +165,10 @@ describe('IdentityPublicKey', () => { it('should return original public key hash in case BLS12_381', () => { rawPublicKey = { id: 0, - type: KeyType.BLS12_381, + type: IdentityPublicKey.TYPES.BLS12_381, data: Buffer.from('01fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694', 'hex'), - purpose: KeyPurpose.AUTHENTICATION, - securityLevel: KeySecurityLevel.MASTER, + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.MASTER, readOnly: false, disabledAt: 123, }; @@ -191,10 +185,10 @@ describe('IdentityPublicKey', () => { it('should return data in case BIP13_SCRIPT_HASH', () => { rawPublicKey = { id: 0, - type: KeyType.BIP13_SCRIPT_HASH, + type: IdentityPublicKey.TYPES.BIP13_SCRIPT_HASH, data: Buffer.from('54c557e07dde5bb6cb791c7a540e0a4796f5e97e', 'hex'), - purpose: KeyPurpose.AUTHENTICATION, - securityLevel: KeySecurityLevel.MASTER, + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.MASTER, readOnly: false, disabledAt: 123, }; @@ -215,10 +209,10 @@ describe('IdentityPublicKey', () => { expect(jsonPublicKey).to.deep.equal({ id: 0, - type: KeyType.ECDSA_SECP256K1, + type: IdentityPublicKey.TYPES.ECDSA_SECP256K1, data: 'AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH', - purpose: KeyPurpose.AUTHENTICATION, - securityLevel: KeySecurityLevel.MASTER, + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.MASTER, readOnly: false, }); }); @@ -230,10 +224,10 @@ describe('IdentityPublicKey', () => { expect(jsonPublicKey).to.deep.equal({ id: 0, - type: KeyType.ECDSA_SECP256K1, + type: IdentityPublicKey.TYPES.ECDSA_SECP256K1, data: 'AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH', - purpose: KeyPurpose.AUTHENTICATION, - securityLevel: KeySecurityLevel.MASTER, + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.MASTER, readOnly: false, disabledAt: 42, }); @@ -242,7 +236,7 @@ describe('IdentityPublicKey', () => { describe('#isMaster', () => { it('should return true when public key has MASTER security level', () => { - publicKey.setSecurityLevel(KeySecurityLevel.MASTER); + publicKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.MASTER); const result = publicKey.isMaster(); @@ -250,7 +244,7 @@ describe('IdentityPublicKey', () => { }); it('should return false when public key doesn\'t have MASTER security level', () => { - publicKey.setSecurityLevel(KeySecurityLevel.HIGH); + publicKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.HIGH); const result = publicKey.isMaster(); diff --git a/packages/wasm-dpp/tsconfig.json b/packages/wasm-dpp/tsconfig.json index 714ea219c34..17eeea3831b 100644 --- a/packages/wasm-dpp/tsconfig.json +++ b/packages/wasm-dpp/tsconfig.json @@ -13,6 +13,6 @@ ] }, "include": [ - "index.ts", "wasm/wasm_dpp.js, lib/*" + "lib/**/*.ts", "wasm/wasm_dpp.js" ], } \ No newline at end of file diff --git a/packages/wasm-dpp/webpack.config.js b/packages/wasm-dpp/webpack.config.js index 09ab53f512e..b9d8edfd7e6 100644 --- a/packages/wasm-dpp/webpack.config.js +++ b/packages/wasm-dpp/webpack.config.js @@ -2,7 +2,7 @@ const path = require('path'); const webpack = require('webpack'); module.exports = { - entry: './index.ts', + entry: './lib/index.ts', output: { path: path.resolve(__dirname, 'dist'), filename: 'index.js',