Skip to main content

dpp/errors/consensus/state/
state_error.rs

1use crate::errors::ProtocolError;
2use bincode::{Decode, Encode};
3use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
4use thiserror::Error;
5
6use crate::consensus::state::address_funds::{AddressDoesNotExistError, AddressInvalidNonceError, AddressNotEnoughFundsError, AddressesNotEnoughFundsError};
7use crate::consensus::state::shielded::insufficient_pool_notes_error::InsufficientPoolNotesError;
8use crate::consensus::state::shielded::insufficient_shielded_fee_error::InsufficientShieldedFeeError;
9use crate::consensus::state::shielded::invalid_anchor_error::InvalidAnchorError;
10use crate::consensus::state::shielded::invalid_shielded_proof_error::InvalidShieldedProofError;
11use crate::consensus::state::shielded::nullifier_already_spent_error::NullifierAlreadySpentError;
12use crate::consensus::state::data_contract::data_contract_already_present_error::DataContractAlreadyPresentError;
13use crate::consensus::state::data_contract::data_contract_config_update_error::DataContractConfigUpdateError;
14use crate::consensus::state::data_contract::data_contract_is_readonly_error::DataContractIsReadonlyError;
15use crate::consensus::state::data_trigger::DataTriggerError;
16use crate::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError;
17use crate::consensus::state::document::document_not_found_error::DocumentNotFoundError;
18use crate::consensus::state::document::document_owner_id_mismatch_error::DocumentOwnerIdMismatchError;
19use crate::consensus::state::document::document_timestamp_window_violation_error::DocumentTimestampWindowViolationError;
20use crate::consensus::state::document::document_timestamps_mismatch_error::DocumentTimestampsMismatchError;
21use crate::consensus::state::document::duplicate_unique_index_error::DuplicateUniqueIndexError;
22use crate::consensus::state::document::invalid_document_revision_error::InvalidDocumentRevisionError;
23use crate::consensus::state::identity::duplicated_identity_public_key_id_state_error::DuplicatedIdentityPublicKeyIdStateError;
24use crate::consensus::state::identity::duplicated_identity_public_key_state_error::DuplicatedIdentityPublicKeyStateError;
25use crate::consensus::state::identity::identity_public_key_is_disabled_error::IdentityPublicKeyIsDisabledError;
26use crate::consensus::state::identity::identity_public_key_is_read_only_error::IdentityPublicKeyIsReadOnlyError;
27use crate::consensus::state::identity::invalid_identity_public_key_id_error::InvalidIdentityPublicKeyIdError;
28use crate::consensus::state::identity::invalid_identity_revision_error::InvalidIdentityRevisionError;
29use crate::consensus::state::identity::max_identity_public_key_limit_reached_error::MaxIdentityPublicKeyLimitReachedError;
30use crate::consensus::state::identity::missing_identity_public_key_ids_error::MissingIdentityPublicKeyIdsError;
31use crate::consensus::state::identity::{IdentityAlreadyExistsError, IdentityInsufficientBalanceError, RecipientIdentityDoesNotExistError};
32use crate::consensus::ConsensusError;
33use crate::consensus::state::data_contract::data_contract_not_found_error::DataContractNotFoundError;
34use crate::consensus::state::data_contract::data_contract_update_action_not_allowed_error::DataContractUpdateActionNotAllowedError;
35use crate::consensus::state::data_contract::data_contract_update_permission_error::DataContractUpdatePermissionError;
36use crate::consensus::state::data_contract::document_type_update_error::DocumentTypeUpdateError;
37use crate::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError;
38use crate::consensus::state::document::document_contest_document_with_same_id_already_present_error::DocumentContestDocumentWithSameIdAlreadyPresentError;
39use crate::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError;
40use crate::consensus::state::document::document_contest_index_mismatch_error::DocumentContestIndexMismatchError;
41use crate::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError;
42use crate::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError;
43use crate::consensus::state::document::document_contest_not_required_error::DocumentContestNotRequiredError;
44use crate::consensus::state::document::referenced_document_type_deletable_error::ReferencedDocumentTypeDeletableError;
45use crate::consensus::state::document::referenced_document_type_not_found_error::ReferencedDocumentTypeNotFoundError;
46use crate::consensus::state::document::referenced_entity_not_found_error::ReferencedEntityNotFoundError;
47use crate::consensus::state::document::referenced_identity_key_disabled_error::ReferencedIdentityKeyDisabledError;
48use crate::consensus::state::document::referenced_identity_key_not_found_error::ReferencedIdentityKeyNotFoundError;
49use crate::consensus::state::document::referenced_document_property_agreement_invalid_error::ReferencedDocumentPropertyAgreementInvalidError;
50use crate::consensus::state::document::referenced_document_property_mismatch_error::ReferencedDocumentPropertyMismatchError;
51use crate::consensus::state::document::referenced_key_id_property_invalid_error::ReferencedKeyIdPropertyInvalidError;
52use crate::consensus::state::document::document_incorrect_purchase_price_error::DocumentIncorrectPurchasePriceError;
53use crate::consensus::state::document::document_not_for_sale_error::DocumentNotForSaleError;
54use crate::consensus::state::group::{GroupActionAlreadyCompletedError, GroupActionAlreadySignedByIdentityError, GroupActionDoesNotExistError, IdentityMemberOfGroupNotFoundError, IdentityNotMemberOfGroupError, ModificationOfGroupActionMainParametersNotPermittedError};
55use crate::consensus::state::identity::identity_for_token_configuration_not_found_error::IdentityInTokenConfigurationNotFoundError;
56use crate::consensus::state::identity::identity_public_key_already_exists_for_unique_contract_bounds_error::IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError;
57use crate::consensus::state::identity::identity_to_freeze_does_not_exist_error::IdentityToFreezeDoesNotExistError;
58use crate::consensus::state::identity::invalid_identity_contract_nonce_error::InvalidIdentityNonceError;
59use crate::consensus::state::identity::missing_transfer_key_error::MissingTransferKeyError;
60use crate::consensus::state::identity::no_transfer_key_for_core_withdrawal_available_error::NoTransferKeyForCoreWithdrawalAvailableError;
61use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError;
62use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError;
63use crate::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError, IdentityTokenAccountNotFrozenError, InvalidGroupPositionError, NewAuthorizedActionTakerGroupDoesNotExistError, NewAuthorizedActionTakerIdentityDoesNotExistError, NewAuthorizedActionTakerMainGroupNotSetError, NewTokensDestinationIdentityDoesNotExistError, TokenMintPastMaxSupplyError, TokenSettingMaxSupplyToLessThanCurrentSupplyError, UnauthorizedTokenActionError, IdentityTokenAccountAlreadyFrozenError, TokenAlreadyPausedError, TokenIsPausedError, TokenNotPausedError, InvalidTokenClaimPropertyMismatch, InvalidTokenClaimNoCurrentRewards, InvalidTokenClaimWrongClaimant, PreProgrammedDistributionTimestampInPastError, TokenTransferRecipientIdentityNotExistError, IdentityHasNotAgreedToPayRequiredTokenAmountError, RequiredTokenPaymentInfoNotSetError, IdentityTryingToPayWithWrongTokenError, TokenDirectPurchaseUserPriceTooLow, TokenAmountUnderMinimumSaleAmount, TokenNotForDirectSale, InvalidTokenPositionStateError};
64use crate::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError;
65use crate::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError;
66use crate::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError;
67use crate::consensus::state::voting::masternode_vote_already_present_error::MasternodeVoteAlreadyPresentError;
68use crate::consensus::state::voting::masternode_voted_too_many_times::MasternodeVotedTooManyTimesError;
69use crate::consensus::state::voting::vote_poll_not_available_for_voting_error::VotePollNotAvailableForVotingError;
70use crate::consensus::state::voting::vote_poll_not_found_error::VotePollNotFoundError;
71
72use super::document::document_timestamps_are_equal_error::DocumentTimestampsAreEqualError;
73
74#[derive(
75    Error, Debug, PartialEq, Encode, Decode, PlatformSerialize, PlatformDeserialize, Clone,
76)]
77pub enum StateError {
78    /*
79
80    DO NOT CHANGE ORDER OF VARIANTS WITHOUT INTRODUCING OF NEW VERSION
81
82    */
83    #[error(transparent)]
84    DataContractAlreadyPresentError(DataContractAlreadyPresentError),
85
86    #[error(transparent)]
87    DataTriggerError(DataTriggerError),
88
89    #[error(transparent)]
90    DocumentAlreadyPresentError(DocumentAlreadyPresentError),
91
92    #[error(transparent)]
93    DocumentContestCurrentlyLockedError(DocumentContestCurrentlyLockedError),
94
95    #[error(transparent)]
96    DocumentContestNotJoinableError(DocumentContestNotJoinableError),
97
98    #[error(transparent)]
99    DocumentContestIdentityAlreadyContestantError(DocumentContestIdentityAlreadyContestantError),
100
101    #[error(transparent)]
102    DocumentContestNotPaidForError(DocumentContestNotPaidForError),
103
104    #[error(transparent)]
105    DocumentContestDocumentWithSameIdAlreadyPresentError(
106        DocumentContestDocumentWithSameIdAlreadyPresentError,
107    ),
108
109    #[error(transparent)]
110    DocumentNotFoundError(DocumentNotFoundError),
111
112    #[error(transparent)]
113    DocumentNotForSaleError(DocumentNotForSaleError),
114
115    #[error(transparent)]
116    DocumentIncorrectPurchasePriceError(DocumentIncorrectPurchasePriceError),
117
118    #[error(transparent)]
119    DocumentOwnerIdMismatchError(DocumentOwnerIdMismatchError),
120
121    #[error(transparent)]
122    DocumentTimestampsMismatchError(DocumentTimestampsMismatchError),
123
124    #[error(transparent)]
125    DocumentTimestampWindowViolationError(DocumentTimestampWindowViolationError),
126
127    #[error(transparent)]
128    DuplicateUniqueIndexError(DuplicateUniqueIndexError),
129
130    #[error(transparent)]
131    InvalidDocumentRevisionError(InvalidDocumentRevisionError),
132
133    #[error(transparent)]
134    IdentityAlreadyExistsError(IdentityAlreadyExistsError),
135
136    #[error(transparent)]
137    IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError(
138        IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError,
139    ),
140
141    #[error(transparent)]
142    IdentityPublicKeyIsReadOnlyError(IdentityPublicKeyIsReadOnlyError),
143
144    #[error(transparent)]
145    MissingIdentityPublicKeyIdsError(MissingIdentityPublicKeyIdsError),
146
147    #[error(transparent)]
148    MissingTransferKeyError(MissingTransferKeyError),
149
150    #[error(transparent)]
151    NoTransferKeyForCoreWithdrawalAvailableError(NoTransferKeyForCoreWithdrawalAvailableError),
152
153    #[error(transparent)]
154    InvalidIdentityPublicKeyIdError(InvalidIdentityPublicKeyIdError),
155
156    #[error(transparent)]
157    InvalidIdentityRevisionError(InvalidIdentityRevisionError),
158
159    #[error(transparent)]
160    InvalidIdentityNonceError(InvalidIdentityNonceError),
161
162    #[error(transparent)]
163    MaxIdentityPublicKeyLimitReachedError(MaxIdentityPublicKeyLimitReachedError),
164
165    #[error(transparent)]
166    DuplicatedIdentityPublicKeyStateError(DuplicatedIdentityPublicKeyStateError),
167
168    #[error(transparent)]
169    DuplicatedIdentityPublicKeyIdStateError(DuplicatedIdentityPublicKeyIdStateError),
170
171    #[error(transparent)]
172    IdentityPublicKeyIsDisabledError(IdentityPublicKeyIsDisabledError),
173
174    #[error(transparent)]
175    IdentityInsufficientBalanceError(IdentityInsufficientBalanceError),
176
177    #[error(transparent)]
178    DocumentTimestampsAreEqualError(DocumentTimestampsAreEqualError),
179
180    #[error(transparent)]
181    DataContractIsReadonlyError(DataContractIsReadonlyError),
182
183    #[error(transparent)]
184    DataContractConfigUpdateError(DataContractConfigUpdateError),
185
186    #[error(transparent)]
187    DocumentTypeUpdateError(DocumentTypeUpdateError),
188
189    #[error(transparent)]
190    PrefundedSpecializedBalanceInsufficientError(PrefundedSpecializedBalanceInsufficientError),
191
192    #[error(transparent)]
193    PrefundedSpecializedBalanceNotFoundError(PrefundedSpecializedBalanceNotFoundError),
194
195    #[error(transparent)]
196    DataContractUpdatePermissionError(DataContractUpdatePermissionError),
197
198    #[error(transparent)]
199    MasternodeNotFoundError(MasternodeNotFoundError),
200
201    #[error(transparent)]
202    MasternodeIncorrectVoterIdentityIdError(MasternodeIncorrectVoterIdentityIdError),
203
204    #[error(transparent)]
205    MasternodeIncorrectVotingAddressError(MasternodeIncorrectVotingAddressError),
206
207    #[error(transparent)]
208    VotePollNotFoundError(VotePollNotFoundError),
209
210    #[error(transparent)]
211    VotePollNotAvailableForVotingError(VotePollNotAvailableForVotingError),
212
213    #[error(transparent)]
214    MasternodeVotedTooManyTimesError(MasternodeVotedTooManyTimesError),
215
216    #[error(transparent)]
217    MasternodeVoteAlreadyPresentError(MasternodeVoteAlreadyPresentError),
218
219    #[error(transparent)]
220    RecipientIdentityDoesNotExistError(RecipientIdentityDoesNotExistError),
221
222    #[error(transparent)]
223    IdentityDoesNotHaveEnoughTokenBalanceError(IdentityDoesNotHaveEnoughTokenBalanceError),
224
225    #[error(transparent)]
226    UnauthorizedTokenActionError(UnauthorizedTokenActionError),
227
228    #[error(transparent)]
229    IdentityTokenAccountFrozenError(IdentityTokenAccountFrozenError),
230
231    #[error(transparent)]
232    IdentityTokenAccountNotFrozenError(IdentityTokenAccountNotFrozenError),
233
234    #[error(transparent)]
235    IdentityNotMemberOfGroupError(IdentityNotMemberOfGroupError),
236
237    #[error(transparent)]
238    GroupActionDoesNotExistError(GroupActionDoesNotExistError),
239
240    #[error(transparent)]
241    GroupActionAlreadyCompletedError(GroupActionAlreadyCompletedError),
242
243    #[error(transparent)]
244    GroupActionAlreadySignedByIdentityError(GroupActionAlreadySignedByIdentityError),
245
246    #[error(transparent)]
247    DataContractUpdateActionNotAllowedError(DataContractUpdateActionNotAllowedError),
248
249    #[error(transparent)]
250    TokenSettingMaxSupplyToLessThanCurrentSupplyError(
251        TokenSettingMaxSupplyToLessThanCurrentSupplyError,
252    ),
253
254    #[error(transparent)]
255    TokenMintPastMaxSupplyError(TokenMintPastMaxSupplyError),
256
257    #[error(transparent)]
258    InvalidTokenClaimPropertyMismatch(InvalidTokenClaimPropertyMismatch),
259
260    #[error(transparent)]
261    InvalidTokenClaimNoCurrentRewards(InvalidTokenClaimNoCurrentRewards),
262
263    #[error(transparent)]
264    InvalidTokenClaimWrongClaimant(InvalidTokenClaimWrongClaimant),
265
266    #[error(transparent)]
267    NewTokensDestinationIdentityDoesNotExistError(NewTokensDestinationIdentityDoesNotExistError),
268
269    #[error(transparent)]
270    NewAuthorizedActionTakerIdentityDoesNotExistError(
271        NewAuthorizedActionTakerIdentityDoesNotExistError,
272    ),
273
274    #[error(transparent)]
275    NewAuthorizedActionTakerGroupDoesNotExistError(NewAuthorizedActionTakerGroupDoesNotExistError),
276
277    #[error(transparent)]
278    NewAuthorizedActionTakerMainGroupNotSetError(NewAuthorizedActionTakerMainGroupNotSetError),
279
280    #[error(transparent)]
281    InvalidGroupPositionError(InvalidGroupPositionError),
282
283    #[error(transparent)]
284    TokenIsPausedError(TokenIsPausedError),
285
286    #[error(transparent)]
287    IdentityTokenAccountAlreadyFrozenError(IdentityTokenAccountAlreadyFrozenError),
288
289    #[error(transparent)]
290    TokenAlreadyPausedError(TokenAlreadyPausedError),
291
292    #[error(transparent)]
293    TokenNotPausedError(TokenNotPausedError),
294
295    #[error(transparent)]
296    TokenTransferRecipientIdentityNotExistError(TokenTransferRecipientIdentityNotExistError),
297
298    #[error(transparent)]
299    PreProgrammedDistributionTimestampInPastError(PreProgrammedDistributionTimestampInPastError),
300
301    #[error(transparent)]
302    IdentityHasNotAgreedToPayRequiredTokenAmountError(
303        IdentityHasNotAgreedToPayRequiredTokenAmountError,
304    ),
305
306    #[error(transparent)]
307    RequiredTokenPaymentInfoNotSetError(RequiredTokenPaymentInfoNotSetError),
308
309    #[error(transparent)]
310    IdentityTryingToPayWithWrongTokenError(IdentityTryingToPayWithWrongTokenError),
311
312    #[error(transparent)]
313    TokenDirectPurchaseUserPriceTooLow(TokenDirectPurchaseUserPriceTooLow),
314
315    #[error(transparent)]
316    TokenAmountUnderMinimumSaleAmount(TokenAmountUnderMinimumSaleAmount),
317
318    #[error(transparent)]
319    TokenNotForDirectSale(TokenNotForDirectSale),
320
321    #[error(transparent)]
322    IdentityInTokenConfigurationNotFoundError(IdentityInTokenConfigurationNotFoundError),
323
324    #[error(transparent)]
325    IdentityMemberOfGroupNotFoundError(IdentityMemberOfGroupNotFoundError),
326
327    #[error(transparent)]
328    ModificationOfGroupActionMainParametersNotPermittedError(
329        ModificationOfGroupActionMainParametersNotPermittedError,
330    ),
331
332    #[error(transparent)]
333    IdentityToFreezeDoesNotExistError(IdentityToFreezeDoesNotExistError),
334
335    #[error(transparent)]
336    DataContractNotFoundError(DataContractNotFoundError),
337
338    #[error(transparent)]
339    InvalidTokenPositionStateError(InvalidTokenPositionStateError),
340
341    #[error(transparent)]
342    AddressDoesNotExistError(AddressDoesNotExistError),
343
344    #[error(transparent)]
345    AddressNotEnoughFundsError(AddressNotEnoughFundsError),
346
347    #[error(transparent)]
348    AddressesNotEnoughFundsError(AddressesNotEnoughFundsError),
349
350    #[error(transparent)]
351    AddressInvalidNonceError(AddressInvalidNonceError),
352
353    #[error(transparent)]
354    InvalidAnchorError(InvalidAnchorError),
355
356    #[error(transparent)]
357    NullifierAlreadySpentError(NullifierAlreadySpentError),
358
359    #[error(transparent)]
360    InvalidShieldedProofError(InvalidShieldedProofError),
361
362    #[error(transparent)]
363    InsufficientPoolNotesError(InsufficientPoolNotesError),
364
365    #[error(transparent)]
366    InsufficientShieldedFeeError(InsufficientShieldedFeeError),
367
368    #[error(transparent)]
369    DocumentContestIndexMismatchError(DocumentContestIndexMismatchError),
370
371    #[error(transparent)]
372    DocumentContestNotRequiredError(DocumentContestNotRequiredError),
373
374    #[error(transparent)]
375    ReferencedEntityNotFoundError(ReferencedEntityNotFoundError),
376
377    #[error(transparent)]
378    ReferencedDocumentTypeNotFoundError(ReferencedDocumentTypeNotFoundError),
379
380    #[error(transparent)]
381    ReferencedDocumentTypeDeletableError(ReferencedDocumentTypeDeletableError),
382
383    #[error(transparent)]
384    ReferencedIdentityKeyNotFoundError(ReferencedIdentityKeyNotFoundError),
385
386    #[error(transparent)]
387    ReferencedIdentityKeyDisabledError(ReferencedIdentityKeyDisabledError),
388
389    #[error(transparent)]
390    ReferencedKeyIdPropertyInvalidError(ReferencedKeyIdPropertyInvalidError),
391
392    #[error(transparent)]
393    ReferencedDocumentPropertyAgreementInvalidError(
394        ReferencedDocumentPropertyAgreementInvalidError,
395    ),
396
397    #[error(transparent)]
398    ReferencedDocumentPropertyMismatchError(ReferencedDocumentPropertyMismatchError),
399}
400
401impl From<StateError> for ConsensusError {
402    fn from(error: StateError) -> Self {
403        Self::StateError(error)
404    }
405}
406
407#[cfg(test)]
408mod tests {
409    use super::*;
410    use platform_value::Identifier;
411
412    /// `StateError` is encoded by variant position, so inserting a variant
413    /// anywhere but the end silently reassigns the discriminant of every
414    /// variant after it — consensus errors travel to WASM and JavaScript
415    /// clients, which would then decode an existing error as a different one.
416    /// These are the frozen discriminants of the first variant, of the variant
417    /// that follows the document contest block (the one an insertion there
418    /// would shift first), and of the last two.
419    fn discriminant_of(error: StateError) -> u8 {
420        let bytes = bincode::encode_to_vec(error, bincode::config::standard())
421            .expect("expected to encode the state error");
422        // Discriminants below 251 are a single byte under bincode's varint.
423        bytes[0]
424    }
425
426    #[test]
427    fn state_error_discriminants_are_frozen() {
428        assert_eq!(
429            discriminant_of(StateError::DataContractAlreadyPresentError(
430                DataContractAlreadyPresentError::new(Identifier::from([1; 32]))
431            )),
432            0
433        );
434        assert_eq!(
435            discriminant_of(StateError::DocumentNotFoundError(
436                DocumentNotFoundError::new(Identifier::from([1; 32]))
437            )),
438            8
439        );
440        assert_eq!(
441            discriminant_of(StateError::InsufficientShieldedFeeError(
442                InsufficientShieldedFeeError::new("fee".to_string())
443            )),
444            90
445        );
446        assert_eq!(
447            discriminant_of(StateError::DocumentContestIndexMismatchError(
448                DocumentContestIndexMismatchError::new(
449                    Identifier::from([1; 32]),
450                    "expected".to_string(),
451                    "provided".to_string(),
452                )
453            )),
454            91
455        );
456        assert_eq!(
457            discriminant_of(StateError::DocumentContestNotRequiredError(
458                DocumentContestNotRequiredError::new(
459                    Identifier::from([1; 32]),
460                    "provided".to_string(),
461                )
462            )),
463            92
464        );
465        assert_eq!(
466            discriminant_of(StateError::ReferencedEntityNotFoundError(
467                ReferencedEntityNotFoundError::new(
468                    Identifier::from([1; 32]),
469                    crate::data_contract::document_type::DocumentPropertyReferenceTarget::Identity,
470                    "toUserId".to_string(),
471                )
472            )),
473            93
474        );
475        assert_eq!(
476            discriminant_of(StateError::ReferencedDocumentTypeNotFoundError(
477                ReferencedDocumentTypeNotFoundError::new(
478                    Identifier::from([1; 32]),
479                    "note".to_string(),
480                    "parentNoteId".to_string(),
481                )
482            )),
483            94
484        );
485        assert_eq!(
486            discriminant_of(StateError::ReferencedDocumentTypeDeletableError(
487                ReferencedDocumentTypeDeletableError::new(
488                    Identifier::from([1; 32]),
489                    "note".to_string(),
490                    "parentNoteId".to_string(),
491                )
492            )),
493            95
494        );
495        assert_eq!(
496            discriminant_of(StateError::ReferencedIdentityKeyNotFoundError(
497                ReferencedIdentityKeyNotFoundError::new(
498                    Identifier::from([1; 32]),
499                    2,
500                    "toUserId".to_string(),
501                )
502            )),
503            96
504        );
505        assert_eq!(
506            discriminant_of(StateError::ReferencedIdentityKeyDisabledError(
507                ReferencedIdentityKeyDisabledError::new(
508                    Identifier::from([1; 32]),
509                    2,
510                    "toUserId".to_string(),
511                )
512            )),
513            97
514        );
515        assert_eq!(
516            discriminant_of(StateError::ReferencedKeyIdPropertyInvalidError(
517                ReferencedKeyIdPropertyInvalidError::new(
518                    "recipientKeyIndex".to_string(),
519                    "toUserId".to_string(),
520                    "missing".to_string(),
521                )
522            )),
523            98
524        );
525        assert_eq!(
526            discriminant_of(StateError::ReferencedDocumentPropertyAgreementInvalidError(
527                ReferencedDocumentPropertyAgreementInvalidError::new(
528                    "like.postId".to_string(),
529                    "hashtag".to_string(),
530                    "hashtag".to_string(),
531                    "missing".to_string(),
532                )
533            )),
534            99
535        );
536        assert_eq!(
537            discriminant_of(StateError::ReferencedDocumentPropertyMismatchError(
538                ReferencedDocumentPropertyMismatchError::new(
539                    "postId".to_string(),
540                    "hashtag".to_string(),
541                    "hashtag".to_string(),
542                )
543            )),
544            100
545        );
546    }
547}