From ee42690ed3bb5b8f86e76cb2f178152ca708f28e Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 10:02:55 +0100 Subject: [PATCH 1/8] remaining, clearing iterable map exceeds gas usage --- Cargo.lock | 2 +- crates/contract-interface/src/lib.rs | 1 + .../src/types/attestation.rs | 52 +- crates/contract/src/dto_mapping.rs | 129 +---- crates/contract/src/lib.rs | 101 ++-- crates/contract/src/primitives/time.rs | 2 - crates/contract/src/storage_keys.rs | 2 +- crates/contract/src/tee/proposal.rs | 2 - crates/contract/src/tee/tee_state.rs | 546 ++++++++++++++---- crates/contract/src/v3_0_2_state.rs | 80 ++- .../tests/inprocess/attestation_submission.rs | 4 +- crates/contract/tests/sandbox/tee.rs | 10 +- crates/contract/tests/sandbox/utils/consts.rs | 4 +- .../snapshots/abi__abi_has_not_changed.snap | 72 ++- crates/mpc-attestation/Cargo.toml | 2 +- crates/mpc-attestation/src/attestation.rs | 437 +++++++++++--- .../tests/test_attestation_verification.rs | 159 ++++- crates/node/src/indexer.rs | 4 +- crates/node/src/indexer/tx_sender.rs | 63 +- crates/node/src/tee/remote_attestation.rs | 14 +- .../convert_to_contract_dto.rs | 4 +- 21 files changed, 1278 insertions(+), 412 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b1179b48..891b33081 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4792,6 +4792,7 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" name = "mpc-attestation" version = "3.2.0" dependencies = [ + "assert_matches", "attestation", "borsh", "dcap-qvl", @@ -4799,7 +4800,6 @@ dependencies = [ "hex", "include-measurements", "mpc-primitives", - "rstest", "serde", "serde_json", "sha2", diff --git a/crates/contract-interface/src/lib.rs b/crates/contract-interface/src/lib.rs index cc0b4fea3..8ca071114 100644 --- a/crates/contract-interface/src/lib.rs +++ b/crates/contract-interface/src/lib.rs @@ -3,6 +3,7 @@ pub mod types { pub use attestation::{ AppCompose, Attestation, Collateral, DstackAttestation, EventLog, MockAttestation, TcbInfo, + VerifiedAttestation, VerifiedDstackAttestation, }; pub use config::{Config, InitConfig}; pub use crypto::{ diff --git a/crates/contract-interface/src/types/attestation.rs b/crates/contract-interface/src/types/attestation.rs index a5bba3802..63be2aa1d 100644 --- a/crates/contract-interface/src/types/attestation.rs +++ b/crates/contract-interface/src/types/attestation.rs @@ -29,6 +29,54 @@ pub enum Attestation { Mock(MockAttestation), } +#[derive( + Clone, + Debug, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Serialize, + Deserialize, + BorshSerialize, + BorshDeserialize, +)] +#[cfg_attr( + all(feature = "abi", not(target_arch = "wasm32")), + derive(schemars::JsonSchema) +)] +pub enum VerifiedAttestation { + Dtack(VerifiedDstackAttestation), + Mock(MockAttestation), +} + +#[derive( + Clone, + Debug, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Serialize, + Deserialize, + BorshSerialize, + BorshDeserialize, +)] +#[cfg_attr( + all(feature = "abi", not(target_arch = "wasm32")), + derive(schemars::JsonSchema) +)] +pub struct VerifiedDstackAttestation { + /// The digest of the MPC image running. + pub mpc_image_hash: Sha256Digest, + /// The digest of the launcher compose file running. + pub launcher_compose_hash: Sha256Digest, + /// Unix time stamp for when this attestation will be expired. + pub expiry_timestamp_seconds: u64, +} + #[derive( Clone, Eq, @@ -78,8 +126,8 @@ pub enum MockAttestation { WithConstraints { mpc_docker_image_hash: Option, launcher_docker_compose_hash: Option, - /// Unix time stamp for when this attestation expires. - expiry_time_stamp_seconds: Option, + /// Unix time stamp for when this attestation will be expired. + expiry_timestamp_seconds: Option, }, } diff --git a/crates/contract/src/dto_mapping.rs b/crates/contract/src/dto_mapping.rs index c90410e70..66e4d9565 100644 --- a/crates/contract/src/dto_mapping.rs +++ b/crates/contract/src/dto_mapping.rs @@ -6,7 +6,7 @@ use contract_interface::types as dtos; use mpc_attestation::{ - attestation::{Attestation, DstackAttestation, MockAttestation}, + attestation::{Attestation, DstackAttestation, MockAttestation, VerifiedAttestation}, collateral::{Collateral, QuoteCollateralV3}, EventLog, TcbInfo, }; @@ -70,11 +70,11 @@ impl IntoContractType for dtos::MockAttestation { dtos::MockAttestation::WithConstraints { mpc_docker_image_hash, launcher_docker_compose_hash, - expiry_time_stamp_seconds, + expiry_timestamp_seconds, } => MockAttestation::WithConstraints { mpc_docker_image_hash: mpc_docker_image_hash.map(Into::into), launcher_docker_compose_hash: launcher_docker_compose_hash.map(Into::into), - expiry_time_stamp_seconds, + expiry_timestamp_seconds, }, } } @@ -179,14 +179,21 @@ impl IntoContractType for dtos::EventLog { } } -impl IntoInterfaceType for Attestation { - fn into_dto_type(self) -> dtos::Attestation { +impl IntoInterfaceType for VerifiedAttestation { + fn into_dto_type(self) -> dtos::VerifiedAttestation { match self { - Attestation::Dstack(dstack_attestation) => { - dtos::Attestation::Dstack(dstack_attestation.into_dto_type()) + VerifiedAttestation::Mock(mock_attestation) => { + dtos::VerifiedAttestation::Mock(mock_attestation.into_dto_type()) } - Attestation::Mock(mock_attestation) => { - dtos::Attestation::Mock(mock_attestation.into_dto_type()) + VerifiedAttestation::Dstack(validated_dstack_attestation) => { + dtos::VerifiedAttestation::Dtack(dtos::VerifiedDstackAttestation { + mpc_image_hash: validated_dstack_attestation.mpc_image_hash.into(), + launcher_compose_hash: validated_dstack_attestation + .launcher_compose_hash + .into(), + expiry_timestamp_seconds: validated_dstack_attestation + .expiration_timestamp_seconds, + }) } } } @@ -200,116 +207,16 @@ impl IntoInterfaceType for MockAttestation { MockAttestation::WithConstraints { mpc_docker_image_hash, launcher_docker_compose_hash, - expiry_time_stamp_seconds, + expiry_timestamp_seconds, } => dtos::MockAttestation::WithConstraints { mpc_docker_image_hash: mpc_docker_image_hash.map(Into::into), launcher_docker_compose_hash: launcher_docker_compose_hash.map(Into::into), - expiry_time_stamp_seconds, + expiry_timestamp_seconds, }, } } } -impl IntoInterfaceType for DstackAttestation { - fn into_dto_type(self) -> dtos::DstackAttestation { - let DstackAttestation { - quote, - collateral, - tcb_info, - } = self; - - dtos::DstackAttestation { - quote: quote.into(), - collateral: collateral.into_dto_type(), - tcb_info: tcb_info.into_dto_type(), - } - } -} - -impl IntoInterfaceType for Collateral { - fn into_dto_type(self) -> dtos::Collateral { - // Collateral is a newtype wrapper around QuoteCollateralV3 - let QuoteCollateralV3 { - pck_crl_issuer_chain, - root_ca_crl, - pck_crl, - tcb_info_issuer_chain, - tcb_info, - tcb_info_signature, - qe_identity_issuer_chain, - qe_identity, - qe_identity_signature, - } = self.into(); - - dtos::Collateral { - pck_crl_issuer_chain, - root_ca_crl, - pck_crl, - tcb_info_issuer_chain, - tcb_info, - tcb_info_signature, - qe_identity_issuer_chain, - qe_identity, - qe_identity_signature, - } - } -} - -impl IntoInterfaceType for TcbInfo { - fn into_dto_type(self) -> dtos::TcbInfo { - let TcbInfo { - mrtd, - rtmr0, - rtmr1, - rtmr2, - rtmr3, - os_image_hash, - compose_hash, - device_id, - app_compose, - event_log, - } = self; - - let event_log = event_log - .into_iter() - .map(IntoInterfaceType::into_dto_type) - .collect(); - - dtos::TcbInfo { - mrtd, - rtmr0, - rtmr1, - rtmr2, - rtmr3, - os_image_hash, - compose_hash, - device_id, - app_compose, - event_log, - } - } -} - -impl IntoInterfaceType for EventLog { - fn into_dto_type(self) -> dtos::EventLog { - let EventLog { - imr, - event_type, - digest, - event, - event_payload, - } = self; - - dtos::EventLog { - imr, - event_type, - digest, - event, - event_payload, - } - } -} - impl IntoInterfaceType for &k256_types::PublicKey { fn into_dto_type(self) -> dtos::Secp256k1PublicKey { let mut bytes = [0u8; 64]; diff --git a/crates/contract/src/lib.rs b/crates/contract/src/lib.rs index 4d47b542b..99fc2ac51 100644 --- a/crates/contract/src/lib.rs +++ b/crates/contract/src/lib.rs @@ -19,6 +19,7 @@ pub mod update; #[cfg(feature = "dev-utils")] pub mod utils; pub mod v3_0_2_state; +pub mod v3_2_0_state; mod dto_mapping; @@ -67,7 +68,7 @@ use primitives::{ use state::{running::RunningContractState, ProtocolContractState}; use tee::{ proposal::MpcDockerImageHash, - tee_state::{NodeId, TeeValidationResult}, + tee_state::{NodeId, ParticipantInsertion, TeeValidationResult}, }; use utilities::{AccountIdExtV1, AccountIdExtV2}; @@ -579,31 +580,28 @@ impl MpcContract { let tee_upgrade_deadline_duration = Duration::from_secs(self.config.tee_upgrade_deadline_duration_seconds); - // Verify the TEE quote (including TLS and account keys) and Docker image for the proposed participant - let account_key_dto = account_key.clone().try_into_dto_type()?; - let status = self.tee_state.verify_proposed_participant_attestation( - &proposed_participant_attestation, - tls_public_key.clone(), - account_key_dto, - tee_upgrade_deadline_duration, - ); - - if let TeeQuoteStatus::Invalid(reason) = status { - return Err(InvalidParameters::InvalidTeeRemoteAttestation - .message(format!("TeeQuoteStatus is invalid: {reason}"))); - } - // Add the participant information to the contract state - let is_new_attestation = self.tee_state.add_participant( - NodeId { - account_id: account_id.clone(), - tls_public_key: tls_public_key.into_contract_type(), - account_public_key: Some(account_key), - }, - proposed_participant_attestation, - ); + let attestation_insertion_result = self + .tee_state + .add_participant( + NodeId { + account_id: account_id.clone(), + tls_public_key: tls_public_key.into_contract_type(), + account_public_key: Some(account_key), + }, + proposed_participant_attestation, + tee_upgrade_deadline_duration, + ) + .map_err(|err| { + InvalidParameters::InvalidTeeRemoteAttestation + .message(format!("TeeQuoteStatus is invalid: {err}")) + })?; let caller_is_not_participant = self.voter_account().is_err(); + let is_new_attestation = matches!( + attestation_insertion_result, + ParticipantInsertion::NewlyInsertedParticipant + ); let attestation_storage_must_be_paid_by_caller = is_new_attestation || caller_is_not_participant; @@ -638,15 +636,19 @@ impl MpcContract { pub fn get_attestation( &self, tls_public_key: dtos::Ed25519PublicKey, - ) -> Result, Error> { + ) -> Result, Error> { let tls_public_key = tls_public_key.into_contract_type(); Ok(self .tee_state .stored_attestations - .iter() - .find(|(stored_tls_pk, _)| **stored_tls_pk == tls_public_key) - .map(|(_, (_, attestation))| attestation.clone().into_dto_type())) + .get(&tls_public_key) + .map(|node_attestation| { + node_attestation + .verified_attestation + .clone() + .into_dto_type() + })) } /// Propose a new set of parameters (participants and threshold) for the MPC network. @@ -671,9 +673,10 @@ impl MpcContract { let tee_upgrade_deadline_duration = Duration::from_secs(self.config.tee_upgrade_deadline_duration_seconds); - let validation_result = self - .tee_state - .validate_tee(proposal.participants(), tee_upgrade_deadline_duration); + let validation_result = self.tee_state.reverify_and_cleanup_participants( + proposal.participants(), + tee_upgrade_deadline_duration, + ); let proposed_participants = proposal.participants(); match validation_result { @@ -1076,10 +1079,10 @@ impl MpcContract { let tee_upgrade_deadline_duration = Duration::from_secs(self.config.tee_upgrade_deadline_duration_seconds); - match self - .tee_state - .validate_tee(current_params.participants(), tee_upgrade_deadline_duration) - { + match self.tee_state.reverify_and_cleanup_participants( + current_params.participants(), + tee_upgrade_deadline_duration, + ) { TeeValidationResult::Full => { self.accept_requests = true; log!("All participants have an accepted Tee status"); @@ -1270,7 +1273,17 @@ impl MpcContract { match try_state_read::() { Ok(Some(state)) => return Ok(state.into()), Ok(None) => return Err(InvalidState::ContractStateIsMissing.into()), - Err(_) => (), // Try read as "Self" instead + Err(err) => { + log!("failed to deserialize state into 3_0_2 state: {:?}", err); + } + }; + + match try_state_read::() { + Ok(Some(state)) => return Ok(state.into()), + Ok(None) => return Err(InvalidState::ContractStateIsMissing.into()), + Err(err) => { + log!("failed to deserialize state into 3_2_0 state: {:?}", err); + } }; match try_state_read::() { @@ -1597,9 +1610,9 @@ impl MpcContract { }; if !(matches!( - self.tee_state.verify_tee_participant( + self.tee_state.reverify_participants( &node_id, - Duration::from_secs(self.config.tee_upgrade_deadline_duration_seconds) + Duration::from_secs(self.config.tee_upgrade_deadline_duration_seconds), ), TeeQuoteStatus::Valid )) { @@ -1829,7 +1842,7 @@ mod tests { .find(|(public_key, _)| active_participant_pks.contains(public_key)) .expect("No attested participants in tee_state") .1 - .0 + .node_id .clone(); // Build a new simulated environment with this node as caller @@ -2341,6 +2354,7 @@ mod tests { .predecessor_account_id(outsider_id.clone().as_v1_account_id()) .attached_deposit(NearToken::from_near(1)) .build()); + contract .submit_participant_info(Attestation::Mock(MockAttestation::Valid), dto_public_key) .unwrap(); @@ -2839,13 +2853,22 @@ mod tests { let valid_participant_attestation = mpc_attestation::attestation::Attestation::Mock( mpc_attestation::attestation::MockAttestation::Valid, ); - contract.tee_state.add_participant( + + let tee_upgrade_duration = + Duration::from_secs(contract.config.tee_upgrade_deadline_duration_seconds); + + let insertion_result = contract.tee_state.add_participant( NodeId { account_id: self.signer_account_id.clone(), tls_public_key: self.attestation_tls_key.clone().into_contract_type(), account_public_key: Some(self.signer_account_pk.clone()), }, valid_participant_attestation, + tee_upgrade_duration, + ); + assert_matches::assert_matches!( + insertion_result, + Ok(ParticipantInsertion::NewlyInsertedParticipant) ); } diff --git a/crates/contract/src/primitives/time.rs b/crates/contract/src/primitives/time.rs index a849a5a6b..b2441e9b8 100644 --- a/crates/contract/src/primitives/time.rs +++ b/crates/contract/src/primitives/time.rs @@ -1,7 +1,5 @@ -use near_sdk::near; use std::time::Duration; -#[near(serializers=[json])] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub(crate) struct Timestamp { duration_since_unix_epoch: Duration, diff --git a/crates/contract/src/storage_keys.rs b/crates/contract/src/storage_keys.rs index e8cabe6d9..17897946a 100644 --- a/crates/contract/src/storage_keys.rs +++ b/crates/contract/src/storage_keys.rs @@ -13,7 +13,7 @@ pub enum StorageKey { PendingSignatureRequestsV2, ProposedUpdatesEntriesV2, ProposedUpdatesVotesV2, - TeeParticipantAttestation, + _DeprecatedTeeParticipantAttestation, PendingCKDRequests, BackupServicesInfo, NodeMigrations, diff --git a/crates/contract/src/tee/proposal.rs b/crates/contract/src/tee/proposal.rs index 43a46b47b..d814e0cd7 100644 --- a/crates/contract/src/tee/proposal.rs +++ b/crates/contract/src/tee/proposal.rs @@ -54,7 +54,6 @@ impl CodeHashesVotes { /// An allowed Docker image configuration entry containing both the MPC image hash and its /// corresponding launcher compose hash, along with when it was added to the allowlist. -#[near(serializers=[json])] #[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] pub struct AllowedMpcDockerImage { pub(crate) image_hash: MpcDockerImageHash, @@ -63,7 +62,6 @@ pub struct AllowedMpcDockerImage { } /// Collection of whitelisted Docker code hashes that are the only ones MPC nodes are allowed to /// run. -#[near(serializers=[json])] #[derive(Clone, Default, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)] pub(crate) struct AllowedDockerImageHashes { /// Whitelisted code hashes, sorted by when they were added (oldest first). Expired entries are diff --git a/crates/contract/src/tee/tee_state.rs b/crates/contract/src/tee/tee_state.rs index 43f18129d..b8a2a4d9d 100644 --- a/crates/contract/src/tee/tee_state.rs +++ b/crates/contract/src/tee/tee_state.rs @@ -1,21 +1,22 @@ use crate::{ primitives::{key_state::AuthenticatedParticipantId, participants::Participants}, - storage_keys::StorageKey, tee::proposal::{ AllowedDockerImageHashes, AllowedMpcDockerImage, CodeHashesVotes, MpcDockerImageHash, }, TryIntoInterfaceType, }; use borsh::{BorshDeserialize, BorshSerialize}; -use contract_interface::types::Ed25519PublicKey; use mpc_attestation::{ - attestation::{Attestation, MockAttestation}, + attestation::{self, Attestation, VerifiedAttestation}, report_data::{ReportData, ReportDataV1}, }; use mpc_primitives::hash::LauncherDockerComposeHash; use near_account_id::AccountId; -use near_sdk::{env, near, store::IterableMap}; -use std::hash::{Hash, Hasher}; +use near_sdk::{env, near}; +use std::{ + collections::BTreeMap, + hash::{Hash, Hasher}, +}; use std::{collections::HashSet, time::Duration}; use utilities::AccountIdExtV1; @@ -57,6 +58,21 @@ pub enum TeeQuoteStatus { /// The participant should not be trusted for TEE-dependent operations. Invalid(String), } + +#[derive(Debug, Clone, thiserror::Error)] +pub(crate) enum AttestationSubmissionError { + #[error("the submitted attestation failed verification, reason: {:?}", .0)] + InvalidAttestation(#[from] attestation::VerificationError), + #[error("the submitted attestation's TLS key is not a valid ED25519 key")] + InvalidTlsKey, +} + +#[derive(Debug)] +pub(crate) enum ParticipantInsertion { + NewlyInsertedParticipant, + UpdatedExistingParticipant, +} + #[derive(Debug)] pub enum TeeValidationResult { /// All participants are valid @@ -68,31 +84,26 @@ pub enum TeeValidationResult { } #[derive(Debug, BorshSerialize, BorshDeserialize)] +pub(crate) struct NodeAttestation { + pub(crate) node_id: NodeId, + pub(crate) verified_attestation: VerifiedAttestation, +} + +#[derive(Default, Debug, BorshSerialize, BorshDeserialize)] pub struct TeeState { pub(crate) allowed_docker_image_hashes: AllowedDockerImageHashes, pub(crate) allowed_launcher_compose_hashes: Vec, pub(crate) votes: CodeHashesVotes, - /// Mapping of TLS public key of a participant to its [`NodeId`] and [`Attestation`]. + /// Mapping of TLS public key of a participant to its [`NodeAttestation`]. /// Attestations are stored for any valid participant that has submitted one, not /// just for the currently active participants. - pub(crate) stored_attestations: IterableMap, -} - -impl Default for TeeState { - fn default() -> Self { - Self { - allowed_docker_image_hashes: AllowedDockerImageHashes::default(), - allowed_launcher_compose_hashes: vec![], - votes: CodeHashesVotes::default(), - stored_attestations: IterableMap::new(StorageKey::TeeParticipantAttestation), - } - } + pub(crate) stored_attestations: BTreeMap, } impl TeeState { /// Creates a [`TeeState`] with an initial set of participants that will receive a valid mocked attestation. pub(crate) fn with_mocked_participant_attestations(participants: &Participants) -> Self { - let mut participants_attestations = IterableMap::new(StorageKey::TeeParticipantAttestation); + let mut participants_attestations = BTreeMap::new(); participants .participants() @@ -106,7 +117,12 @@ impl TeeState { participants_attestations.insert( participant_info.sign_pk.clone(), - (node_id, Attestation::Mock(MockAttestation::Valid)), + NodeAttestation { + node_id, + verified_attestation: VerifiedAttestation::Mock( + attestation::MockAttestation::Valid, + ), + }, ); }); @@ -115,56 +131,25 @@ impl TeeState { ..Default::default() } } + fn current_time_seconds() -> u64 { let current_time_milliseconds = env::block_timestamp_ms(); current_time_milliseconds / 1_000 } - pub(crate) fn verify_proposed_participant_attestation( + /// Adds a participant attestation for the given node iff the attestation succeeds verification. + pub(crate) fn add_participant( &mut self, - attestation: &Attestation, - tls_public_key: Ed25519PublicKey, - account_public_key: Ed25519PublicKey, + node_id: NodeId, + attestation: Attestation, tee_upgrade_deadline_duration: Duration, - ) -> TeeQuoteStatus { - let expected_report_data: ReportData = - ReportDataV1::new(*tls_public_key.as_bytes(), *account_public_key.as_bytes()).into(); - - match attestation.verify( - expected_report_data.into(), - Self::current_time_seconds(), - &self.get_allowed_mpc_docker_image_hashes(tee_upgrade_deadline_duration), - &self.allowed_launcher_compose_hashes, - ) { - Ok(()) => TeeQuoteStatus::Valid, - Err(err) => TeeQuoteStatus::Invalid(err.to_string()), - } - } - - /// Verifies the TEE quote and Docker image - pub(crate) fn verify_tee_participant( - &mut self, - node_id: &NodeId, - tee_upgrade_deadline_duration: Duration, - ) -> TeeQuoteStatus { - let allowed_mpc_docker_image_hashes = - self.get_allowed_mpc_docker_image_hashes(tee_upgrade_deadline_duration); - let allowed_launcher_compose_hashes = &self.allowed_launcher_compose_hashes; - - let participant_attestation = self.stored_attestations.get(&node_id.tls_public_key); - let Some(participant_attestation) = participant_attestation else { - return TeeQuoteStatus::Invalid("participant has no attestation".to_string()); - }; - + ) -> Result { // Convert TLS public key - let tls_public_key = match node_id.tls_public_key.clone().try_into_dto_type() { - Ok(value) => value, - Err(err) => { - return TeeQuoteStatus::Invalid(format!( - "could not convert TLS pub key to DTO type: {err}" - )) - } - }; + let tls_public_key = node_id + .tls_public_key + .clone() + .try_into_dto_type() + .map_err(|_| AttestationSubmissionError::InvalidTlsKey)?; // Convert account public key if available // @@ -187,10 +172,47 @@ impl TeeState { let expected_report_data: ReportData = ReportDataV1::new(*tls_public_key.as_bytes(), account_key_bytes).into(); + let verified_attestation = attestation.verify( + expected_report_data.into(), + Self::current_time_seconds(), + &self.get_allowed_mpc_docker_image_hashes(tee_upgrade_deadline_duration), + &self.allowed_launcher_compose_hashes, + )?; + + let tls_pk = node_id.tls_public_key.clone(); + + let insertion = self.stored_attestations.insert( + tls_pk, + NodeAttestation { + node_id, + verified_attestation, + }, + ); + + Ok(match insertion { + Some(_previous_attestation) => ParticipantInsertion::UpdatedExistingParticipant, + None => ParticipantInsertion::NewlyInsertedParticipant, + }) + } + + /// reverifies stored participant attestations. + pub(crate) fn reverify_participants( + &self, + node_id: &NodeId, + tee_upgrade_deadline_duration: Duration, + ) -> TeeQuoteStatus { + let allowed_mpc_docker_image_hashes = + self.get_allowed_mpc_docker_image_hashes(tee_upgrade_deadline_duration); + let allowed_launcher_compose_hashes = &self.allowed_launcher_compose_hashes; + + let participant_attestation = self.stored_attestations.get(&node_id.tls_public_key); + let Some(participant_attestation) = participant_attestation else { + return TeeQuoteStatus::Invalid("participant has no attestation".to_string()); + }; + // Verify the attestation quote let time_stamp_seconds = Self::current_time_seconds(); - match participant_attestation.1.verify( - expected_report_data.into(), + match participant_attestation.verified_attestation.re_verify( time_stamp_seconds, &allowed_mpc_docker_image_hashes, allowed_launcher_compose_hashes, @@ -200,7 +222,11 @@ impl TeeState { } } - pub fn validate_tee( + /// reverifies stored participant attestations and removes any participant attestation + /// from the internal state that fails reverifications. Reverification can fail for example + /// the MPC image hash the attestation was tied to is no longer allowed, or due to certificate + /// expiries. + pub fn reverify_and_cleanup_participants( &mut self, participants: &Participants, tee_upgrade_deadline_duration: Duration, @@ -227,7 +253,7 @@ impl TeeState { }; let tee_status = - self.verify_tee_participant(&node_id, tee_upgrade_deadline_duration); + self.reverify_participants(&node_id, tee_upgrade_deadline_duration); matches!(tee_status, TeeQuoteStatus::Valid) }) @@ -246,23 +272,6 @@ impl TeeState { } } - /// Adds a participant attestation for the given node. - /// - /// Returns: - /// - `true` if this is the first attestation for the node (i.e., a new participant was added). - /// - `false` if the node already had an attestation (the existing one was replaced). - pub fn add_participant(&mut self, node_id: NodeId, attestation: Attestation) -> bool { - let tls_pk = node_id.tls_public_key.clone(); - - let is_new = !self.stored_attestations.contains_key(&tls_pk); - - // Must pass owned values, not references - self.stored_attestations - .insert(tls_pk, (node_id, attestation)); - - is_new - } - pub fn vote( &mut self, code_hash: MpcDockerImageHash, @@ -331,7 +340,7 @@ impl TeeState { pub fn get_tee_accounts(&self) -> Vec { self.stored_attestations .values() - .map(|(node_id, _)| node_id.clone()) + .map(|node_attestation| node_attestation.node_id.clone()) .collect() } @@ -339,11 +348,13 @@ impl TeeState { pub fn find_node_id_by_tls_key(&self, tls_public_key: &near_sdk::PublicKey) -> Option { self.stored_attestations .get(tls_public_key) - .map(|(node_id, _)| node_id.clone()) + .map(|node_attestation| node_attestation.node_id.clone()) } /// Returns Ok(()) if the caller has at least one participant entry /// whose TLS key matches an attested node belonging to the caller account. + /// + /// Handles multiple participants per account and supports legacy mock nodes. pub(crate) fn is_caller_an_attested_participant( &self, participants: &Participants, @@ -360,11 +371,11 @@ impl TeeState { .get(&info.sign_pk) .ok_or(AttestationCheckError::AttestationNotFound)?; - if attestation.0.account_id != signer_id { + if attestation.node_id.account_id != signer_id { return Err(AttestationCheckError::AttestationOwnerMismatch); } - if let Some(node_pk) = &attestation.0.account_public_key { + if let Some(node_pk) = &attestation.node_id.account_public_key { if node_pk != &signer_pk { return Err(AttestationCheckError::AttestationKeyMismatch); } @@ -392,10 +403,22 @@ mod tests { use near_account_id::AccountId; use near_sdk::test_utils::VMContextBuilder; use near_sdk::testing_env; + use std::time::Duration; use utilities::AccountIdExtV2; + /// Helper to set up the testing environment with a specific signer + fn set_signer(account_id: &AccountId, public_key: &near_sdk::PublicKey) { + let mut builder = VMContextBuilder::new(); + builder + .signer_account_id(account_id.as_v1_account_id()) + .signer_account_pk(public_key.clone()); + testing_env!(builder.build()); + } + #[test] fn test_clean_non_participants() { + const TEE_UPGRADE_DURATION: Duration = Duration::from_secs(10000); + let mut tee_state = TeeState::default(); // Create some test participants using test utils @@ -423,9 +446,26 @@ mod tests { }; for node_id in &participant_nodes { - tee_state.add_participant(node_id.clone(), local_attestation.clone()); + let insertion_result = tee_state.add_participant( + node_id.clone(), + local_attestation.clone(), + TEE_UPGRADE_DURATION, + ); + + assert_matches!( + insertion_result, + Ok(ParticipantInsertion::NewlyInsertedParticipant) + ); } - tee_state.add_participant(non_participant_uid.clone(), local_attestation.clone()); + let insertion_result = tee_state.add_participant( + non_participant_uid.clone(), + local_attestation.clone(), + TEE_UPGRADE_DURATION, + ); + assert_matches!( + insertion_result, + Ok(ParticipantInsertion::NewlyInsertedParticipant) + ); // Verify all 4 accounts have TEE info initially assert_eq!(tee_state.stored_attestations.len(), 4); @@ -453,18 +493,292 @@ mod tests { .contains_key(&non_participant_uid.tls_public_key)); } - /// Helper to set up the testing environment with a specific signer - fn set_signer(account_id: &AccountId, public_key: &near_sdk::PublicKey) { - let mut builder = VMContextBuilder::new(); - builder - .signer_account_id(account_id.as_v1_account_id()) - .signer_account_pk(public_key.clone()); - testing_env!(builder.build()); + #[test] + fn updating_existing_participant_returns_existing_participant() { + // given + const TEE_UPGRADE_DURATION: Duration = Duration::from_secs(10000); + let mut tee_state = TeeState::default(); + + let participant: AccountId = "dave.near".parse().unwrap(); + let local_attestation = Attestation::Mock(MockAttestation::Valid); + + let participant_id = NodeId { + account_id: participant.clone(), + account_public_key: Some(bogus_ed25519_near_public_key()), + tls_public_key: bogus_ed25519_near_public_key(), + }; + + let insertion_result = tee_state.add_participant( + participant_id.clone(), + local_attestation.clone(), + TEE_UPGRADE_DURATION, + ); + assert_matches!( + insertion_result, + Ok(ParticipantInsertion::NewlyInsertedParticipant) + ); + + // when + let re_insertion_result = tee_state.add_participant( + participant_id.clone(), + local_attestation.clone(), + TEE_UPGRADE_DURATION, + ); + + // then + assert_matches!( + re_insertion_result, + Ok(ParticipantInsertion::UpdatedExistingParticipant) + ); + } + + #[test] + fn add_participant_increases_storage_size() { + // given + let mut tee_state = TeeState::default(); + let node_id = NodeId { + account_id: "alice.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + let attestation = Attestation::Mock(MockAttestation::Valid); + + // when + tee_state + .add_participant(node_id, attestation, Duration::from_secs(0)) + .unwrap(); + + // then + assert_eq!( + tee_state.stored_attestations.len(), + 1, + "Internal storage count should increase by exactly one" + ); + } + + #[test] + fn add_participant_indexes_by_tls_key() { + // given + let mut tee_state = TeeState::default(); + let node_id = NodeId { + account_id: "alice.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + let attestation = Attestation::Mock(MockAttestation::Valid); + + // when + tee_state + .add_participant(node_id.clone(), attestation, Duration::from_secs(0)) + .unwrap(); + + // then + assert!( + tee_state + .stored_attestations + .contains_key(&node_id.tls_public_key), + "Entry should be strictly retrievable using the TLS public key" + ); + } + + #[test] + fn add_participant_preserves_node_id_integrity() { + // given + let mut tee_state = TeeState::default(); + let node_id = NodeId { + account_id: "alice.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + let attestation = Attestation::Mock(MockAttestation::Valid); + + // when + tee_state + .add_participant(node_id.clone(), attestation, Duration::from_secs(0)) + .unwrap(); + + // then + let stored_entry = tee_state + .stored_attestations + .get(&node_id.tls_public_key) + .unwrap(); + + assert_eq!( + stored_entry.node_id, node_id, + "The stored NodeId struct must exactly match the inserted one" + ); + } + + #[test] + fn internal_storage_distinguishes_participants_by_tls_key() { + // given + let mut tee_state = TeeState::default(); + + let node_1 = NodeId { + account_id: "alice.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + + let node_2 = NodeId { + account_id: "bob.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + + // when + tee_state + .add_participant( + node_1.clone(), + Attestation::Mock(MockAttestation::Valid), + Duration::from_secs(0), + ) + .unwrap(); + tee_state + .add_participant( + node_2.clone(), + Attestation::Mock(MockAttestation::Valid), + Duration::from_secs(0), + ) + .unwrap(); + + // then + assert_eq!(tee_state.stored_attestations.len(), 2); + assert!(tee_state + .stored_attestations + .contains_key(&node_1.tls_public_key)); + assert!(tee_state + .stored_attestations + .contains_key(&node_2.tls_public_key)); + } + + #[test] + fn re_verify_validates_fresh_attestation() { + // given + let mut tee_state = TeeState::default(); + let node_id = NodeId { + account_id: "fresh.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + + const NOW_SECONDS: u64 = 1000; + + testing_env!(VMContextBuilder::new().block_timestamp(NOW_SECONDS).build()); + + let attestation = Attestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: None, + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: Some(NOW_SECONDS), + }); + + tee_state + .add_participant(node_id.clone(), attestation, Duration::from_secs(0)) + .unwrap(); + + // when + let status = tee_state.reverify_participants(&node_id, Duration::from_secs(0)); + + // then + assert_eq!(status, TeeQuoteStatus::Valid); + } + + #[test] + fn test_re_verify_rejects_expired_attestation() { + // given + let mut tee_state = TeeState::default(); + let node_id = NodeId { + account_id: "about_to_be_expired.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + + const EXPIRY_TIMESTAMP_SECONDS: u64 = 1000; + const ELAPSED_SECONDS: u64 = 200; + + testing_env!(VMContextBuilder::new().block_timestamp(0).build()); + + let attestation = Attestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: None, + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: Some(EXPIRY_TIMESTAMP_SECONDS), + }); + + tee_state + .add_participant(node_id.clone(), attestation, Duration::from_secs(0)) + .unwrap(); + + // when + testing_env!(VMContextBuilder::new() + .block_timestamp( + Duration::from_secs(EXPIRY_TIMESTAMP_SECONDS + ELAPSED_SECONDS).as_nanos() as u64 + ) + .build()); + + let status = tee_state.reverify_participants(&node_id, Duration::from_secs(0)); + + // then + assert_matches!(status, TeeQuoteStatus::Invalid(_)); + } + + #[test] + fn re_verify_succeeds_within_expiry_time() { + // given + let mut tee_state = TeeState::default(); + let node_id = NodeId { + account_id: "valid_check.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + + const EXPIRY_TIMESTAMP_SECONDS: u64 = 1000; + + testing_env!(VMContextBuilder::new() + .block_timestamp(Duration::from_secs(0).as_nanos() as u64) + .build()); + + let attestation = Attestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: None, + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: Some(EXPIRY_TIMESTAMP_SECONDS), + }); + + tee_state + .add_participant(node_id.clone(), attestation, Duration::from_secs(0)) + .unwrap(); + + // when + testing_env!(VMContextBuilder::new() + .block_timestamp(Duration::from_secs(EXPIRY_TIMESTAMP_SECONDS - 1).as_nanos() as u64) + .build()); + + let status = tee_state.reverify_participants(&node_id, Duration::from_secs(0)); + + // then + assert_eq!(status, TeeQuoteStatus::Valid); + } + + #[test] + fn test_re_verify_returns_invalid_for_missing_node() { + // given + let tee_state = TeeState::default(); + let node_id = NodeId { + account_id: "ghost.near".parse().unwrap(), + tls_public_key: bogus_ed25519_near_public_key(), + account_public_key: Some(bogus_ed25519_near_public_key()), + }; + + // when + let status = tee_state.reverify_participants(&node_id, Duration::from_secs(0)); + + // then + assert_matches!(status, TeeQuoteStatus::Invalid(msg) if msg.contains("participant has no attestation")); } #[test] fn test_is_caller_attested_success() { let mut tee_state = TeeState::default(); + let tee_upgrade_duration = Duration::MAX; // Generate 1 participant let participants = gen_participants(1); let (account_id, _, participant_info) = participants.participants().iter().next().unwrap(); @@ -482,7 +796,13 @@ mod tests { tls_public_key: participant_info.sign_pk.clone(), account_public_key: Some(signer_pk), }; - tee_state.add_participant(node_id, Attestation::Mock(MockAttestation::Valid)); + tee_state + .add_participant( + node_id, + Attestation::Mock(MockAttestation::Valid), + tee_upgrade_duration, + ) + .expect("Attestation is valid on insertion"); // 4. Verify check passes let result = tee_state.is_caller_an_attested_participant(&participants); @@ -492,6 +812,7 @@ mod tests { #[test] fn test_is_caller_attested_success_legacy_no_account_key() { // Tests the case where account_public_key is None (legacy/mock nodes) + let tee_upgrade_duration = Duration::MAX; let mut tee_state = TeeState::default(); let participants = gen_participants(1); let (account_id, _, participant_info) = participants.participants().iter().next().unwrap(); @@ -505,7 +826,13 @@ mod tests { tls_public_key: participant_info.sign_pk.clone(), account_public_key: None, }; - tee_state.add_participant(node_id, Attestation::Mock(MockAttestation::Valid)); + tee_state + .add_participant( + node_id, + Attestation::Mock(MockAttestation::Valid), + tee_upgrade_duration, + ) + .expect("Attestation is valid on insertion"); let result = tee_state.is_caller_an_attested_participant(&participants); assert_matches!(result, Ok(())); @@ -547,6 +874,7 @@ mod tests { let mut tee_state = TeeState::default(); let participants = gen_participants(1); let (account_id, _, participant_info) = participants.participants().iter().next().unwrap(); + let tee_upgrade_duration = Duration::MAX; let signer_pk = bogus_ed25519_near_public_key(); set_signer(account_id, &signer_pk); @@ -561,7 +889,13 @@ mod tests { tls_public_key: participant_info.sign_pk.clone(), account_public_key: Some(signer_pk), }; - tee_state.add_participant(node_id, Attestation::Mock(MockAttestation::Valid)); + tee_state + .add_participant( + node_id, + Attestation::Mock(MockAttestation::Valid), + tee_upgrade_duration, + ) + .expect("Attestation is valid on insertion"); let result = tee_state.is_caller_an_attested_participant(&participants); @@ -570,9 +904,11 @@ mod tests { #[test] fn test_err_attestation_key_mismatch() { + // given let mut tee_state = TeeState::default(); let participants = gen_participants(1); let (account_id, _, participant_info) = participants.participants().iter().next().unwrap(); + let tee_upgrade_duration = Duration::MAX; let signer_pk = bogus_ed25519_near_public_key(); set_signer(account_id, &signer_pk); @@ -589,10 +925,18 @@ mod tests { tls_public_key: participant_info.sign_pk.clone(), account_public_key: Some(old_signer_pk), // Mismatch here }; - tee_state.add_participant(node_id, Attestation::Mock(MockAttestation::Valid)); - + tee_state + .add_participant( + node_id, + Attestation::Mock(MockAttestation::Valid), + tee_upgrade_duration, + ) + .expect("Attestation is valid on insertion"); + + // when let result = tee_state.is_caller_an_attested_participant(&participants); + // then assert_matches!(result, Err(AttestationCheckError::AttestationKeyMismatch)); } } diff --git a/crates/contract/src/v3_0_2_state.rs b/crates/contract/src/v3_0_2_state.rs index 4ac0bcc32..68c84dcb5 100644 --- a/crates/contract/src/v3_0_2_state.rs +++ b/crates/contract/src/v3_0_2_state.rs @@ -8,8 +8,13 @@ //! A better approach: only copy the structures that have changed and import the rest from the existing codebase. use borsh::{BorshDeserialize, BorshSerialize}; +use mpc_attestation::attestation::Attestation; +use mpc_primitives::hash::LauncherDockerComposeHash; use near_account_id::AccountId; -use near_sdk::store::{IterableMap, LookupMap}; +use near_sdk::{ + env, + store::{IterableMap, LookupMap}, +}; use std::collections::HashSet; use crate::{ @@ -19,7 +24,10 @@ use crate::{ signature::{SignatureRequest, YieldIndex}, }, state::ProtocolContractState, - tee::tee_state::TeeState, + tee::{ + proposal::{AllowedDockerImageHashes, CodeHashesVotes}, + tee_state::NodeId, + }, update::{Update, UpdateId}, }; @@ -87,7 +95,42 @@ impl From for crate::update::ProposedUpdates { } } -#[derive(Debug, BorshSerialize, BorshDeserialize)] +#[derive(Debug, BorshDeserialize)] +struct TeeState { + _allowed_docker_image_hashes: AllowedDockerImageHashes, + _allowed_launcher_compose_hashes: Vec, + _votes: CodeHashesVotes, + participants_attestations: IterableMap, +} + +// #[derive(Debug, BorshDeserialize)] +// enum ProtocolContractState { +// NotInitialized, +// Initializing, +// Running(RunningContractState), +// Resharing, +// } + +// #[derive(Debug, BorshDeserialize)] +// pub struct RunningContractState { +// /// The domains for which we have a key ready for signature processing. +// pub domains: DomainRegistry, +// /// The keys that are currently in use; for each domain provides an unique identifier for a +// /// distributed key, so that the nodes can identify which local keyshare to use. +// pub keyset: Keyset, +// /// The current participants and threshold. +// pub parameters: ThresholdParameters, +// /// Votes for proposals for a new set of participants and threshold. +// pub parameters_votes: ThresholdParametersVotes, +// /// Votes for proposals to add new domains. +// pub add_domains_votes: AddDomainsVotes, +// /// The previous epoch id for a resharing state that was cancelled. +// /// This epoch id is tracked, as the next time the state transitions to resharing, +// /// we can't reuse a previously cancelled epoch id. +// pub previously_cancelled_resharing_epoch_id: Option, +// } + +#[derive(Debug, BorshDeserialize)] pub struct MpcContract { protocol_state: ProtocolContractState, pending_signature_requests: LookupMap, @@ -101,13 +144,40 @@ pub struct MpcContract { impl From for crate::MpcContract { fn from(value: MpcContract) -> Self { + let protocol_state = value.protocol_state; + + // let (protocol_state, running_state) = match value.protocol_state { + // ProtocolContractState::Running(running_state) => ( + // crate::ProtocolContractState::Running(running_state), + // &running_state, + // ), + // _ => env::panic_str("Contract must be in running state when migrating."), + // }; + + let crate::ProtocolContractState::Running(running_state) = &protocol_state else { + env::panic_str("Contract must be in running state when migrating."); + }; + + // For the soft release we give every participant a mocked attestation. + // Since this upgrade has a non-backwards compatible change, instead of manually mapping the attestations + // we give everyone a new mock attestation again instead. + + // clear previous attestations from the storage trie + let mut previous_tee_state = value.tee_state; + + // TODO: This clear is running out of gas + // previous_tee_state.participants_attestations.clear(); + + let threshold_parameters = &running_state.parameters.participants(); + let tee_state = crate::TeeState::with_mocked_participant_attestations(threshold_parameters); + Self { - protocol_state: value.protocol_state, + protocol_state, pending_signature_requests: value.pending_signature_requests, pending_ckd_requests: value.pending_ckd_requests, proposed_updates: value.proposed_updates.into(), config: value.config.into(), - tee_state: value.tee_state, + tee_state, accept_requests: value.accept_requests, node_migrations: value.node_migrations, } diff --git a/crates/contract/tests/inprocess/attestation_submission.rs b/crates/contract/tests/inprocess/attestation_submission.rs index 1281c8cc0..2cc20a886 100644 --- a/crates/contract/tests/inprocess/attestation_submission.rs +++ b/crates/contract/tests/inprocess/attestation_submission.rs @@ -249,7 +249,7 @@ impl TestSetup { Attestation::Mock(MockAttestation::WithConstraints { mpc_docker_image_hash: Some(hash), launcher_docker_compose_hash: None, - expiry_time_stamp_seconds: None, + expiry_timestamp_seconds: None, }) } } @@ -323,7 +323,7 @@ fn test_participant_kickout_after_expiration() { let expiring_attestation = Attestation::Mock(MockAttestation::WithConstraints { mpc_docker_image_hash: None, launcher_docker_compose_hash: None, - expiry_time_stamp_seconds: Some(EXPIRY_SECONDS), + expiry_timestamp_seconds: Some(EXPIRY_SECONDS), }); let third_node = NodeId { account_id: setup.participants_list[2].0.clone(), diff --git a/crates/contract/tests/sandbox/tee.rs b/crates/contract/tests/sandbox/tee.rs index 94d960283..8f2c3f023 100644 --- a/crates/contract/tests/sandbox/tee.rs +++ b/crates/contract/tests/sandbox/tee.rs @@ -431,7 +431,7 @@ async fn new_hash_and_previous_hashes_under_grace_period_pass_attestation_verifi let mock_attestation = MockAttestation::WithConstraints { mpc_docker_image_hash: Some(*approved_hash), launcher_docker_compose_hash: None, - expiry_time_stamp_seconds: None, + expiry_timestamp_seconds: None, }; let attestation = Attestation::Mock(mock_attestation); @@ -509,13 +509,13 @@ async fn get_attestation_returns_some_when_tls_key_associated_with_an_attestatio let participant_1_attestation = Attestation::Mock(MockAttestation::WithConstraints { mpc_docker_image_hash: None, launcher_docker_compose_hash: None, - expiry_time_stamp_seconds: Some(u64::MAX), + expiry_timestamp_seconds: Some(u64::MAX), }); let participant_2_attestation = Attestation::Mock(MockAttestation::WithConstraints { mpc_docker_image_hash: None, launcher_docker_compose_hash: None, - expiry_time_stamp_seconds: Some(u64::MAX - 1), + expiry_timestamp_seconds: Some(u64::MAX - 1), }); assert_ne!( @@ -565,13 +565,13 @@ async fn get_attestation_overwrites_when_same_tls_key_is_reused() { let first_attestation = Attestation::Mock(MockAttestation::WithConstraints { mpc_docker_image_hash: None, launcher_docker_compose_hash: None, - expiry_time_stamp_seconds: Some(u64::MAX), + expiry_timestamp_seconds: Some(u64::MAX), }); let second_attestation = Attestation::Mock(MockAttestation::WithConstraints { mpc_docker_image_hash: None, launcher_docker_compose_hash: None, - expiry_time_stamp_seconds: Some(u64::MAX - 1), + expiry_timestamp_seconds: Some(u64::MAX - 1), }); assert_ne!( diff --git a/crates/contract/tests/sandbox/utils/consts.rs b/crates/contract/tests/sandbox/utils/consts.rs index 0c0910b8d..16173eeb5 100644 --- a/crates/contract/tests/sandbox/utils/consts.rs +++ b/crates/contract/tests/sandbox/utils/consts.rs @@ -30,11 +30,11 @@ pub const GAS_FOR_VOTE_NEW_PARAMETERS: Gas = Gas::from_tgas(22); /// TODO(#1571): Gas cost for voting on contract updates. Reduced somewhat after /// optimization (#1617) by avoiding full contract code deserialization; there’s likely still /// room for further optimization. -pub const GAS_FOR_VOTE_UPDATE: Gas = Gas::from_tgas(232); +pub const GAS_FOR_VOTE_UPDATE: Gas = Gas::from_tgas(241); /// Gas required for votes cast before the threshold is reached (votes 1 through N-1). /// These votes are cheap because they only record the vote without triggering the actual /// contract update deployment and migration. -pub const GAS_FOR_VOTE_BEFORE_THRESHOLD: Gas = Gas::from_tgas(4); +pub const GAS_FOR_VOTE_BEFORE_THRESHOLD: Gas = Gas::from_tgas(5); /// Maximum gas expected for the threshold vote that triggers the contract update. /// This vote is more expensive because it deploys the new contract code and executes /// the migration function. diff --git a/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap b/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap index 23fa58e8c..208f60f25 100644 --- a/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap +++ b/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap @@ -190,7 +190,7 @@ expression: abi "type_schema": { "anyOf": [ { - "$ref": "#/definitions/Attestation" + "$ref": "#/definitions/VerifiedAttestation" }, { "type": "null" @@ -1961,8 +1961,8 @@ expression: abi "WithConstraints": { "type": "object", "properties": { - "expiry_time_stamp_seconds": { - "description": "Unix time stamp for when this attestation expires.", + "expiry_timestamp_seconds": { + "description": "Unix time stamp for when this attestation will be expired.", "type": [ "integer", "null" @@ -2798,6 +2798,72 @@ expression: abi "format": "uint64", "minimum": 0.0 }, + "VerifiedAttestation": { + "oneOf": [ + { + "type": "object", + "required": [ + "Dtack" + ], + "properties": { + "Dtack": { + "$ref": "#/definitions/VerifiedDstackAttestation" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Mock" + ], + "properties": { + "Mock": { + "$ref": "#/definitions/MockAttestation" + } + }, + "additionalProperties": false + } + ] + }, + "VerifiedDstackAttestation": { + "type": "object", + "required": [ + "expiry_timestamp_seconds", + "launcher_compose_hash", + "mpc_image_hash" + ], + "properties": { + "expiry_timestamp_seconds": { + "description": "Unix time stamp for when this attestation will be expired.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "launcher_compose_hash": { + "description": "The digest of the launcher compose file running.", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32 + }, + "mpc_image_hash": { + "description": "The digest of the MPC image running.", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32 + } + } + }, "YieldIndex": { "description": "The index into calling the YieldResume feature of NEAR. This will allow to resume a yield call after the contract has been called back via this index.", "type": "object", diff --git a/crates/mpc-attestation/Cargo.toml b/crates/mpc-attestation/Cargo.toml index d1dcccccd..9dab92cda 100644 --- a/crates/mpc-attestation/Cargo.toml +++ b/crates/mpc-attestation/Cargo.toml @@ -17,6 +17,6 @@ sha2 = { workspace = true } sha3 = { workspace = true } [dev-dependencies] +assert_matches = { workspace = true } dcap-qvl = { workspace = true } -rstest = { workspace = true } test-utils = { workspace = true } diff --git a/crates/mpc-attestation/src/attestation.rs b/crates/mpc-attestation/src/attestation.rs index da2064ca0..e11e60de8 100644 --- a/crates/mpc-attestation/src/attestation.rs +++ b/crates/mpc-attestation/src/attestation.rs @@ -1,5 +1,5 @@ +use alloc::vec::Vec; use attestation::{ - TcbInfo, app_compose::AppCompose, attestation::{GetSingleEvent as _, OrErr as _}, measurements::ExpectedMeasurements, @@ -10,11 +10,9 @@ use attestation::{ use include_measurements::include_measurements; pub use attestation::attestation::{DstackAttestation, VerificationError}; - use mpc_primitives::hash::{LauncherDockerComposeHash, MpcDockerImageHash}; use borsh::{BorshDeserialize, BorshSerialize}; -use core::ops::Deref as _; use serde::{Deserialize, Serialize}; use sha2::{Digest as _, Sha256}; @@ -23,126 +21,220 @@ use crate::alloc::string::ToString; const MPC_IMAGE_HASH_EVENT: &str = "mpc-image-digest"; +// TODO(#1639): extract timestamp from certificate itself +pub const DEFAULT_EXPIRATION_DURATION_SECONDS: u64 = 60 * 60 * 24 * 7; // 7 days + #[allow(clippy::large_enum_variant)] -#[derive(Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] +#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] pub enum Attestation { Dstack(DstackAttestation), Mock(MockAttestation), } +#[allow(clippy::large_enum_variant)] +#[derive(Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] +pub enum VerifiedAttestation { + Dstack(ValidatedDstackAttestation), + Mock(MockAttestation), +} + +#[derive(Debug, Default, Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] +pub enum MockAttestation { + #[default] + /// Always pass validation + Valid, + /// Always fails validation + Invalid, + /// Pass validation depending on the set constraints + WithConstraints { + mpc_docker_image_hash: Option, + launcher_docker_compose_hash: Option, + /// Unix time stamp for when this attestation expires. + expiry_timestamp_seconds: Option, + }, +} + +#[derive(Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] +pub struct ValidatedDstackAttestation { + pub mpc_image_hash: MpcDockerImageHash, + pub launcher_compose_hash: LauncherDockerComposeHash, + // TODO(#1639): This timestamp can not come from the contract, + // but should be extracted from the certificate itself. + pub expiration_timestamp_seconds: u64, +} + +impl VerifiedAttestation { + pub fn re_verify( + &self, + timestamp_seconds: u64, + allowed_mpc_docker_image_hashes: &[MpcDockerImageHash], + allowed_launcher_docker_compose_hashes: &[LauncherDockerComposeHash], + ) -> Result<(), VerificationError> { + match self { + Self::Dstack(ValidatedDstackAttestation { + mpc_image_hash, + launcher_compose_hash, + expiration_timestamp_seconds, + }) => { + let attestation_has_expired = *expiration_timestamp_seconds < timestamp_seconds; + + if attestation_has_expired { + return Err(VerificationError::Custom(format!( + "The attestation expired at t = {:?}, time_now = {:?}", + expiration_timestamp_seconds, timestamp_seconds + ))); + } + + let () = verify_mpc_hash(mpc_image_hash, allowed_mpc_docker_image_hashes)?; + let () = verify_launcher_compose_hash( + launcher_compose_hash, + allowed_launcher_docker_compose_hashes, + )?; + + Ok(()) + } + Self::Mock(mock_attestation) => verify_mock_attestation( + mock_attestation, + allowed_mpc_docker_image_hashes, + allowed_launcher_docker_compose_hashes, + timestamp_seconds, + ), + } + } +} + impl Attestation { pub fn verify( &self, expected_report_data: ReportData, - timestamp_seconds: u64, + current_timestamp_seconds: u64, allowed_mpc_docker_image_hashes: &[MpcDockerImageHash], allowed_launcher_docker_compose_hashes: &[LauncherDockerComposeHash], - ) -> Result<(), VerificationError> { - let attestation = match self { + ) -> Result { + match self { Self::Dstack(dstack_attestation) => { // Makes MPC related attestation verification first - if allowed_mpc_docker_image_hashes.is_empty() { - return Err(VerificationError::Custom( - "the allowed mpc image hashes list is empty".to_string(), - )); - } - if allowed_launcher_docker_compose_hashes.is_empty() { - return Err(VerificationError::Custom( - "the allowed mpc laucher compose hashes list is empty".to_string(), - )); - } - self.verify_mpc_hash( - &dstack_attestation.tcb_info, - allowed_mpc_docker_image_hashes, - )?; - self.verify_launcher_compose_hash( - &dstack_attestation.tcb_info, + let mpc_image_hash: MpcDockerImageHash = { + let mpc_image_hash_payload = &dstack_attestation + .tcb_info + .get_single_event(MPC_IMAGE_HASH_EVENT)? + .event_payload; + + let mpc_image_hash_bytes: Vec = hex::decode(mpc_image_hash_payload) + .map_err(|err| { + VerificationError::Custom(format!( + "provided mpc image is not hex encoded: {:?}", + err + )) + })?; + let mpc_image_hash_bytes: [u8; 32] = + mpc_image_hash_bytes.try_into().map_err(|_| { + VerificationError::Custom( + "The provided MPC image hash is not 32 bytes".to_string(), + ) + })?; + MpcDockerImageHash::from(mpc_image_hash_bytes) + }; + + let () = verify_mpc_hash(&mpc_image_hash, allowed_mpc_docker_image_hashes)?; + + let launcher_compose_hash: LauncherDockerComposeHash = { + let app_compose: AppCompose = + serde_json::from_str(&dstack_attestation.tcb_info.app_compose) + .map_err(|e| VerificationError::AppComposeParsing(e.to_string()))?; + + let launcher_compose_hash_bytes: [u8; 32] = + Sha256::digest(app_compose.docker_compose_file.as_bytes()).into(); + + LauncherDockerComposeHash::from(launcher_compose_hash_bytes) + }; + + let () = verify_launcher_compose_hash( + &launcher_compose_hash, allowed_launcher_docker_compose_hashes, )?; - dstack_attestation + #[cfg(any(test, debug_assertions))] + let accepted_measurements = [ + include_measurements!("assets/tcb_info.json"), + include_measurements!("assets/tcb_info_dev.json"), + ]; + + #[cfg(not(any(test, debug_assertions)))] + let accepted_measurements = [include_measurements!("assets/tcb_info.json")]; + + dstack_attestation.verify( + expected_report_data, + current_timestamp_seconds, + &accepted_measurements, + )?; + + // TODO(#1639): extract timestamp from certificate itself + let expiration_timestamp_seconds = + current_timestamp_seconds + DEFAULT_EXPIRATION_DURATION_SECONDS; + Ok(VerifiedAttestation::Dstack(ValidatedDstackAttestation { + mpc_image_hash, + launcher_compose_hash, + expiration_timestamp_seconds, + })) } Self::Mock(mock_attestation) => { // Override attestation verification for this case - return verify_mock_attestation( + let () = verify_mock_attestation( mock_attestation, allowed_mpc_docker_image_hashes, allowed_launcher_docker_compose_hashes, - timestamp_seconds, - ); + current_timestamp_seconds, + )?; + + Ok(VerifiedAttestation::Mock(mock_attestation.clone())) } - }; - - let accepted_measurements = [ - include_measurements!("assets/tcb_info.json"), - // TODO Security #1433 - remove dev measurements from production builds after testing is complete. - include_measurements!("assets/tcb_info_dev.json"), - ]; - - attestation.verify( - expected_report_data, - timestamp_seconds, - &accepted_measurements, - ) + } } +} - /// Verifies MPC node image hash is in allowed list. - fn verify_mpc_hash( - &self, - tcb_info: &TcbInfo, - allowed_hashes: &[MpcDockerImageHash], - ) -> Result<(), VerificationError> { - let event = tcb_info.get_single_event(MPC_IMAGE_HASH_EVENT)?; - - allowed_hashes - .iter() - .any(|hash| hash.as_hex() == *event.event_payload) - .or_err(|| { - VerificationError::Custom(format!( - "MPC image hash {} is not in the allowed hashes list", - event.event_payload.clone() - )) - }) +/// Verifies MPC node image hash is in allowed list. +fn verify_mpc_hash( + image_hash: &MpcDockerImageHash, + allowed_hashes: &[MpcDockerImageHash], +) -> Result<(), VerificationError> { + if allowed_hashes.is_empty() { + return Err(VerificationError::Custom( + "the allowed mpc image hashes list is empty".to_string(), + )); } - fn verify_launcher_compose_hash( - &self, - tcb_info: &TcbInfo, - allowed_hashes: &[LauncherDockerComposeHash], - ) -> Result<(), VerificationError> { - let app_compose: AppCompose = serde_json::from_str(&tcb_info.app_compose) - .map_err(|e| VerificationError::AppComposeParsing(e.to_string()))?; - - let launcher_bytes: [u8; 32] = - Sha256::digest(app_compose.docker_compose_file.as_bytes()).into(); - - allowed_hashes - .iter() - .any(|hash| hash.deref() == &launcher_bytes) - .or_err(|| { - VerificationError::Custom(format!( - "launcher compose hash {} is not in the allowed hashes list", - hex::encode(launcher_bytes.as_ref(),) - )) - }) + let image_hash_is_allowed = allowed_hashes.contains(image_hash); + if !image_hash_is_allowed { + return Err(VerificationError::Custom(format!( + "MPC image hash {:?} is not in the allowed hashes list", + image_hash + ))); } + + Ok(()) } -#[derive(Debug, Default, Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] -pub enum MockAttestation { - #[default] - /// Always pass validation - Valid, - /// Always fails validation - Invalid, - /// Pass validation depending on the set constraints - WithConstraints { - mpc_docker_image_hash: Option, - launcher_docker_compose_hash: Option, +fn verify_launcher_compose_hash( + launcher_compose_hash: &LauncherDockerComposeHash, + allowed_hashes: &[LauncherDockerComposeHash], +) -> Result<(), VerificationError> { + if allowed_hashes.is_empty() { + return Err(VerificationError::Custom( + "the allowed mpc laucher compose hashes list is empty".to_string(), + )); + } - /// Unix time stamp for when this attestation expires. - expiry_time_stamp_seconds: Option, - }, + let launcher_compose_hash_is_allowed = allowed_hashes.contains(launcher_compose_hash); + + if !launcher_compose_hash_is_allowed { + return Err(VerificationError::Custom(format!( + "MPC launcher compose hash {:?} is not in the allowed hashes list", + launcher_compose_hash + ))); + } + + Ok(()) } pub(crate) fn verify_mock_attestation( @@ -157,7 +249,7 @@ pub(crate) fn verify_mock_attestation( MockAttestation::WithConstraints { mpc_docker_image_hash, launcher_docker_compose_hash, - expiry_time_stamp_seconds: expiry_timestamp_seconds, + expiry_timestamp_seconds, } => { if let Some(hash) = mpc_docker_image_hash { if allowed_mpc_docker_image_hashes.is_empty() { @@ -201,3 +293,164 @@ pub(crate) fn verify_mock_attestation( } } } + +#[cfg(test)] +mod tests { + use alloc::vec; + + use super::*; + + #[test] + fn mock_constrained_verification_passes_if_hash_in_allowed_list() { + let allowed_hash = MpcDockerImageHash::from([42; 32]); + + let hash_constrained_attestation = + VerifiedAttestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: Some(allowed_hash.clone()), + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: None, + }); + + let other_hash = MpcDockerImageHash::from([1; 32]); + let allowed_mpc_hashes: Vec = vec![other_hash, allowed_hash]; + + hash_constrained_attestation + .re_verify(0, &allowed_mpc_hashes, &[]) + .expect("constrained mpc image hash is allowed and should therefore pass validation"); + } + + #[test] + fn mock_constrained_verification_fails_if_hash_not_in_allowed_list() { + let restricted_hash = MpcDockerImageHash::from([42; 32]); + + let hash_constrained_attestation = + VerifiedAttestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: Some(restricted_hash), + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: None, + }); + + let other_hash = MpcDockerImageHash::from([1; 32]); + let allowed_mpc_hashes: Vec = vec![other_hash]; + + let result = hash_constrained_attestation.re_verify(0, &allowed_mpc_hashes, &[]); + + match result { + Err(VerificationError::Custom(msg)) => { + assert!( + msg.contains("MPC image hash"), + "Expected error message regarding MPC image hash, got: {}", + msg + ); + } + _ => panic!("Expected Custom VerificationError, got: {:?}", result), + } + } + + #[test] + fn mock_constrained_verification_fails_if_allowed_list_is_empty() { + let restricted_hash = MpcDockerImageHash::from([42; 32]); + + let hash_constrained_attestation = + VerifiedAttestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: Some(restricted_hash), + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: None, + }); + + let allowed_mpc_hashes: Vec = vec![]; + + let result = hash_constrained_attestation.re_verify(0, &allowed_mpc_hashes, &[]); + + match result { + Err(VerificationError::Custom(msg)) => { + assert!(msg.contains("list is empty")); + } + _ => panic!("Expected empty list error, got: {:?}", result), + } + } + + #[test] + fn launcher_constraint_passes_if_hash_in_allowed_list() { + let allowed_hash = LauncherDockerComposeHash::from([99; 32]); + + let hash_constrained_attestation = + VerifiedAttestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: None, + launcher_docker_compose_hash: Some(allowed_hash.clone()), + expiry_timestamp_seconds: None, + }); + + let other_hash = LauncherDockerComposeHash::from([1; 32]); + let allowed_launcher_hashes: Vec = + vec![other_hash, allowed_hash]; + + hash_constrained_attestation + .re_verify(0, &[], &allowed_launcher_hashes) + .expect("constrained launcher hash is allowed and should therefore pass validation"); + } + + #[test] + fn launcher_constraint_fails_if_hash_not_in_allowed_list() { + let restricted_hash = LauncherDockerComposeHash::from([99; 32]); + + let hash_constrained_attestation = + VerifiedAttestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: None, + launcher_docker_compose_hash: Some(restricted_hash), + expiry_timestamp_seconds: None, + }); + + let other_hash = LauncherDockerComposeHash::from([1; 32]); + let allowed_launcher_hashes: Vec = vec![other_hash]; + + let result = hash_constrained_attestation.re_verify(0, &[], &allowed_launcher_hashes); + + match result { + Err(VerificationError::Custom(msg)) => { + assert!(msg.contains("launcher compose hash")); + } + _ => panic!("Expected Custom VerificationError, got: {:?}", result), + } + } + + #[test] + fn mock_time_constraint_passes_if_time_is_within_expiry_window() { + let expiry_timestamp_seconds = 101; + let time_now = 100; + + let time_constrained_attestation = + VerifiedAttestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: None, + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: Some(expiry_timestamp_seconds), + }); + + time_constrained_attestation + .re_verify(time_now, &[], &[]) + .expect("Attestation is within valid time window and should pass"); + } + + #[test] + fn time_constraint_fails_if_time_is_past_expiry_window() { + let expiry_timestamp_seconds = 100; + let time_now = 101; + + let time_constrained_attestation = + VerifiedAttestation::Mock(MockAttestation::WithConstraints { + mpc_docker_image_hash: None, + launcher_docker_compose_hash: None, + expiry_timestamp_seconds: Some(expiry_timestamp_seconds), + }); + + let verification_result = time_constrained_attestation.re_verify(time_now, &[], &[]); + + assert_matches::assert_matches!( + verification_result, + Err(VerificationError::ExpiredCertificate { + attestation_time, + expiry_time, + }) if attestation_time == time_now && expiry_time == expiry_timestamp_seconds + ); + } +} diff --git a/crates/mpc-attestation/tests/test_attestation_verification.rs b/crates/mpc-attestation/tests/test_attestation_verification.rs index 2cfa43b22..cfbc4302d 100644 --- a/crates/mpc-attestation/tests/test_attestation_verification.rs +++ b/crates/mpc-attestation/tests/test_attestation_verification.rs @@ -1,53 +1,156 @@ +use assert_matches::assert_matches; use attestation::attestation::VerificationError; -use mpc_primitives::hash::{LauncherDockerComposeHash, MpcDockerImageHash}; -use rstest::rstest; +use mpc_attestation::attestation::{ + Attestation, DEFAULT_EXPIRATION_DURATION_SECONDS, MockAttestation, VerifiedAttestation, +}; +use mpc_attestation::report_data::{ReportData, ReportDataV1}; use test_utils::attestation::{ account_key, image_digest, launcher_compose_digest, mock_dstack_attestation, p2p_tls_key, }; -use mpc_attestation::attestation::{Attestation, MockAttestation}; -use mpc_attestation::report_data::{ReportData, ReportDataV1}; +#[test] +fn valid_mock_attestation_succeeds_verification() { + let valid_attestation = Attestation::Mock(MockAttestation::Valid); -#[rstest] -#[case(MockAttestation::Valid, Ok(()))] -#[case( - MockAttestation::Invalid, - Err(VerificationError::InvalidMockAttestation) -)] -fn test_mock_attestation_verify( - #[case] local_attestation: MockAttestation, - #[case] expected_quote_verification_result: Result<(), VerificationError>, -) { let timestamp_s = 0u64; let tls_key = p2p_tls_key(); let account_key = account_key(); let report_data = ReportData::V1(ReportDataV1::new(tls_key, account_key)); - let attestation = Attestation::Mock(local_attestation); + assert_matches!( + valid_attestation.verify(report_data.into(), timestamp_s, &[], &[]), + Ok(VerifiedAttestation::Mock(MockAttestation::Valid)) + ); +} + +#[test] +fn invalid_mock_attestation_fails_verification() { + let valid_attestation = Attestation::Mock(MockAttestation::Invalid); + + let timestamp_s = 0u64; + let tls_key = p2p_tls_key(); + let account_key = account_key(); + let report_data = ReportData::V1(ReportDataV1::new(tls_key, account_key)); - assert_eq!( - attestation.verify(report_data.into(), timestamp_s, &[], &[]), - expected_quote_verification_result + assert_matches!( + valid_attestation.verify(report_data.into(), timestamp_s, &[], &[]), + Err(VerificationError::InvalidMockAttestation) ); } #[test] -fn test_verify_method_signature() { +fn validated_dstack_attestation_can_be_reverified() { + // given let attestation = mock_dstack_attestation(); let tls_key = p2p_tls_key(); let account_key = account_key(); + let report_data = ReportData::V1(ReportDataV1::new(tls_key, account_key)); + let timestamp_s = 1763626832_u64; + let allowed_mpc_hashes = [image_digest()]; + let allowed_launcher_hashes = [launcher_compose_digest()]; + + let validated = attestation + .verify( + report_data.into(), + timestamp_s, + &allowed_mpc_hashes, + &allowed_launcher_hashes, + ) + .expect("Initial verification failed"); + + // when + let re_verification_result = validated.re_verify( + timestamp_s + DEFAULT_EXPIRATION_DURATION_SECONDS, + &allowed_mpc_hashes, + &allowed_launcher_hashes, + ); + + // then + assert_matches!(re_verification_result, Ok(())); +} +#[test] +fn validated_dstack_attestation_fails_reverification_when_expired() { + // given + let attestation = mock_dstack_attestation(); + let tls_key = p2p_tls_key(); + let account_key = account_key(); + let report_data = ReportData::V1(ReportDataV1::new(tls_key, account_key)); + let timestamp_s = 1763626832_u64; + let allowed_mpc_hashes = [image_digest()]; + let allowed_launcher_hashes = [launcher_compose_digest()]; + + let validated = attestation + .verify( + report_data.into(), + timestamp_s, + &allowed_mpc_hashes, + &allowed_launcher_hashes, + ) + .expect("Initial verification failed"); + + // when + let re_verification_result = validated.re_verify( + timestamp_s + DEFAULT_EXPIRATION_DURATION_SECONDS + 1, + &allowed_mpc_hashes, + &allowed_launcher_hashes, + ); + + // then + assert_matches!( + re_verification_result, + Err(VerificationError::Custom(msg)) if msg.contains("The attestation expired") + ); +} + +#[test] +fn validated_mock_attestation_passes_reverification() { + let valid_attestation = Attestation::Mock(MockAttestation::Valid); + let tls_key = p2p_tls_key(); + let account_key = account_key(); let report_data: ReportData = ReportDataV1::new(tls_key, account_key).into(); - let timestamp_s = 1763626832_u64; //Thursday, 20 November 2025 08:20:32 - let allowed_mpc_image_digest: MpcDockerImageHash = image_digest(); - let allowed_launcher_compose_digest: LauncherDockerComposeHash = launcher_compose_digest(); + let validated = valid_attestation + .verify(report_data.into(), 0, &[], &[]) + .expect("Initial verification failed"); + + // Mock should generally pass re-verify + assert_matches!(validated.re_verify(100, &[], &[]), Ok(())); +} + +#[test] +fn validated_dstack_attestation_fails_reverification_with_rotated_hashes() { + let attestation = mock_dstack_attestation(); + let tls_key = p2p_tls_key(); + let account_key = account_key(); + let report_data: ReportData = ReportDataV1::new(tls_key, account_key).into(); + let creation_time = 1763626832_u64; + + let allowed_mpc_hashes = [image_digest()]; + let allowed_launcher_hashes = [launcher_compose_digest()]; + + // 1. Initial verify succeeds with the "old" allowed list + let validated = attestation + .verify( + report_data.into(), + creation_time, + &allowed_mpc_hashes, + &allowed_launcher_hashes, + ) + .expect("Initial verification should succeed"); + + let new_allowed_mpc_docker_image_hashes = [[42; 32].into()]; + + // 2. Re-verify fails if we remove the allowed hash (e.g. strict rotation) + let result = validated.re_verify( + creation_time, + &new_allowed_mpc_docker_image_hashes, + &allowed_launcher_hashes, + ); - let verification_result = attestation.verify( - report_data.into(), - timestamp_s, - &[allowed_mpc_image_digest], - &[allowed_launcher_compose_digest], + assert_matches!( + result, + Err(VerificationError::Custom(msg)) + if msg.contains("not in the allowed hashes list") ); - assert!(verification_result.is_ok()); } diff --git a/crates/node/src/indexer.rs b/crates/node/src/indexer.rs index 598400635..7bef9c5ab 100644 --- a/crates/node/src/indexer.rs +++ b/crates/node/src/indexer.rs @@ -183,7 +183,7 @@ impl IndexerViewClient { &self, mpc_contract_id: &AccountId, participant_tls_public_key: &contract_interface::types::Ed25519PublicKey, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let get_attestation_args: Vec = serde_json::to_string(&GetAttestationArgs { tls_public_key: participant_tls_public_key, }) @@ -210,7 +210,7 @@ impl IndexerViewClient { match query_response.kind { QueryResponseKind::CallResult(call_result) => serde_json::from_slice::< - Option, + Option, >(&call_result.result) .context("failed to deserialize pending request response"), _ => { diff --git a/crates/node/src/indexer/tx_sender.rs b/crates/node/src/indexer/tx_sender.rs index 709c7b6e7..51b89ea85 100644 --- a/crates/node/src/indexer/tx_sender.rs +++ b/crates/node/src/indexer/tx_sender.rs @@ -4,17 +4,20 @@ use super::IndexerState; use crate::config::RespondConfig; use crate::metrics; use anyhow::Context; +use contract_interface::types::{Attestation, VerifiedAttestation}; use ed25519_dalek::SigningKey; +use mpc_attestation::attestation::DEFAULT_EXPIRATION_DURATION_SECONDS; use near_account_id::AccountId; use near_indexer_primitives::types::Gas; use std::future::Future; use std::sync::Arc; -use std::time::Duration; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; use tokio::sync::{mpsc, oneshot}; use tokio::time; const TRANSACTION_PROCESSOR_CHANNEL_SIZE: usize = 10000; const TRANSACTION_TIMEOUT: Duration = Duration::from_secs(10); +const MAX_ATTESTATION_AGE: Duration = Duration::from_secs(60 * 2); pub trait TransactionSender: Clone + Send + Sync { fn send( @@ -207,11 +210,61 @@ async fn observe_tx_result( .get_participant_attestation(&indexer_state.mpc_contract_id, tls_public_key) .await?; + let Some(stored_attestation) = attestation_stored_on_contract else { + return Ok(TransactionStatus::NotExecuted); + }; + + let submitted_attestation = + &submit_participant_info_args.proposed_participant_attestation; + let submitted_attestation_is_on_chain = - attestation_stored_on_contract.is_some_and(|stored_attestation| { - stored_attestation - == submit_participant_info_args.proposed_participant_attestation - }); + match (stored_attestation, submitted_attestation) { + ( + VerifiedAttestation::Dtack(verified_dstack_attestation), + Attestation::Dstack(_), + ) => { + // Check for equality by checking expiry timestamp to be less than + // than `MAX_ATTESTATION_AGE` + // + // TODO(#1637): extract expiration timestamp from the certificate itself, + // instead of using heuristics. + let expiry_timestamp_seconds = + verified_dstack_attestation.expiry_timestamp_seconds; + + let Some(attestation_duration_since_unix_epoch) = expiry_timestamp_seconds + .checked_sub(DEFAULT_EXPIRATION_DURATION_SECONDS) + .map(Duration::from_secs) + else { + tracing::error!( + ?expiry_timestamp_seconds, + "could not calculate attestation storage time" + ); + + return Ok(TransactionStatus::NotExecuted); + }; + + let timestamp_seconds_now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .context("could not calculate system time")?; + + let attestation_age = + attestation_duration_since_unix_epoch.abs_diff(timestamp_seconds_now); + let attestation_is_fresh = attestation_age < MAX_ATTESTATION_AGE; + + tracing::info!( + ?attestation_age, + ?attestation_is_fresh, + "node found dstack attestation on chain" + ); + + attestation_is_fresh + } + ( + VerifiedAttestation::Mock(stored_mock_attestation), + Attestation::Mock(submitted_mock_attestation), + ) => stored_mock_attestation == *submitted_mock_attestation, + _ => false, + }; if submitted_attestation_is_on_chain { Ok(TransactionStatus::Executed) diff --git a/crates/node/src/tee/remote_attestation.rs b/crates/node/src/tee/remote_attestation.rs index 25cd8612e..0ec5ccd5e 100644 --- a/crates/node/src/tee/remote_attestation.rs +++ b/crates/node/src/tee/remote_attestation.rs @@ -104,12 +104,14 @@ fn validate_remote_attestation( .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); - attestation.verify( - expected_report_data.into(), - now, - allowed_docker_image_hashes, - allowed_launcher_compose_hashes, - ) + attestation + .verify( + expected_report_data.into(), + now, + allowed_docker_image_hashes, + allowed_launcher_compose_hashes, + ) + .map(|_| ()) } pub async fn validate_and_submit_remote_attestation( diff --git a/crates/node/src/trait_extensions/convert_to_contract_dto.rs b/crates/node/src/trait_extensions/convert_to_contract_dto.rs index e874c6a70..2567810f8 100644 --- a/crates/node/src/trait_extensions/convert_to_contract_dto.rs +++ b/crates/node/src/trait_extensions/convert_to_contract_dto.rs @@ -67,11 +67,11 @@ impl IntoContractInterfaceType for M MockAttestation::WithConstraints { mpc_docker_image_hash, launcher_docker_compose_hash, - expiry_time_stamp_seconds, + expiry_timestamp_seconds, } => contract_interface::types::MockAttestation::WithConstraints { mpc_docker_image_hash: mpc_docker_image_hash.map(Into::into), launcher_docker_compose_hash: launcher_docker_compose_hash.map(Into::into), - expiry_time_stamp_seconds, + expiry_timestamp_seconds, }, } } From 26359c0e2eba9de652434be1e69861d36c314ef5 Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 11:11:11 +0100 Subject: [PATCH 2/8] move cleanup post migrate into separate function --- crates/contract/src/lib.rs | 43 +- crates/contract/src/v3_0_2_state.rs | 17 +- crates/contract/src/v3_2_0_state.rs | 83 + crates/contract/tests/sandbox/common.rs | 13 + .../sandbox/upgrade_to_current_contract.rs | 4 + expanded.rs | 30223 ++++++++++++++++ 6 files changed, 30365 insertions(+), 18 deletions(-) create mode 100644 crates/contract/src/v3_2_0_state.rs create mode 100644 expanded.rs diff --git a/crates/contract/src/lib.rs b/crates/contract/src/lib.rs index 99fc2ac51..e4329eddb 100644 --- a/crates/contract/src/lib.rs +++ b/crates/contract/src/lib.rs @@ -48,13 +48,14 @@ use errors::{ }; use k256::elliptic_curve::PrimeField; +use mpc_attestation::attestation::Attestation; use mpc_primitives::hash::LauncherDockerComposeHash; use near_account_id::AccountId; use near_sdk::{ env::{self, ed25519_verify}, log, near_bindgen, state::ContractState, - store::LookupMap, + store::{IterableMap, LookupMap}, CryptoHash, Gas, GasWeight, NearToken, Promise, PromiseError, PromiseOrValue, }; use node_migrations::{BackupServiceInfo, DestinationNodeInfo, NodeMigrations}; @@ -100,6 +101,27 @@ pub struct MpcContract { tee_state: TeeState, accept_requests: bool, node_migrations: NodeMigrations, + stale_data: StaleData, +} + +/// A container for "orphaned" state that persists across contract migrations. +/// +/// ### Why this exists +/// On the NEAR blockchain, the `migrate` function is limited by the maximum transaction gas +/// (300 Tgas). Large data structures, specifically `IterableMap` or `LookupMap` +/// often cannot be cleared in a single block without hitting this limit. +/// +/// ### The Pattern +/// 1. During `migrate()`, expensive-to-delete fields are moved from the main state into [`StaleData`]. +/// 2. The main contract state becomes usable immediately. +/// 3. "Lazy cleanup" methods (like `migrate_clear_tee`) are then called in subsequent, +/// separate transactions to gradually deallocate this storage. +#[derive(Debug, Default, BorshSerialize, BorshDeserialize)] +struct StaleData { + /// Holds the TEE attestations from the previous contract version. + /// This is stored as an `Option` so it can be `.take()`n during the cleanup process, + /// ensuring the `IterableMap` handle is properly dropped. + participant_attestations: Option>, } impl MpcContract { @@ -1205,6 +1227,7 @@ impl MpcContract { tee_state, accept_requests: true, node_migrations: NodeMigrations::default(), + stale_data: Default::default(), }) } @@ -1255,6 +1278,7 @@ impl MpcContract { tee_state, accept_requests: true, node_migrations: NodeMigrations::default(), + stale_data: Default::default(), }) } @@ -1293,6 +1317,18 @@ impl MpcContract { } } + pub fn migrate_clear_tee(&mut self) { + let mut attestations = self + .stale_data + .participant_attestations + .take() + .expect("TEE data has not been cleared"); + + attestations.clear(); + + log!("Successfully cleared stale TEE attestations."); + } + pub fn state(&self) -> &ProtocolContractState { &self.protocol_state } @@ -2419,11 +2455,8 @@ mod tests { protocol_state, pending_signature_requests: LookupMap::new(StorageKey::PendingSignatureRequestsV2), pending_ckd_requests: LookupMap::new(StorageKey::PendingCKDRequests), - proposed_updates: ProposedUpdates::default(), - config: Config::default(), - tee_state: TeeState::default(), accept_requests: true, - node_migrations: NodeMigrations::default(), + ..Default::default() } } } diff --git a/crates/contract/src/v3_0_2_state.rs b/crates/contract/src/v3_0_2_state.rs index 68c84dcb5..0c5bbfe2f 100644 --- a/crates/contract/src/v3_0_2_state.rs +++ b/crates/contract/src/v3_0_2_state.rs @@ -146,14 +146,6 @@ impl From for crate::MpcContract { fn from(value: MpcContract) -> Self { let protocol_state = value.protocol_state; - // let (protocol_state, running_state) = match value.protocol_state { - // ProtocolContractState::Running(running_state) => ( - // crate::ProtocolContractState::Running(running_state), - // &running_state, - // ), - // _ => env::panic_str("Contract must be in running state when migrating."), - // }; - let crate::ProtocolContractState::Running(running_state) = &protocol_state else { env::panic_str("Contract must be in running state when migrating."); }; @@ -161,12 +153,8 @@ impl From for crate::MpcContract { // For the soft release we give every participant a mocked attestation. // Since this upgrade has a non-backwards compatible change, instead of manually mapping the attestations // we give everyone a new mock attestation again instead. - // clear previous attestations from the storage trie - let mut previous_tee_state = value.tee_state; - - // TODO: This clear is running out of gas - // previous_tee_state.participants_attestations.clear(); + let stale_participant_attestations = value.tee_state.participants_attestations; let threshold_parameters = &running_state.parameters.participants(); let tee_state = crate::TeeState::with_mocked_participant_attestations(threshold_parameters); @@ -180,6 +168,9 @@ impl From for crate::MpcContract { tee_state, accept_requests: value.accept_requests, node_migrations: value.node_migrations, + stale_data: crate::StaleData { + participant_attestations: Some(stale_participant_attestations), + }, } } } diff --git a/crates/contract/src/v3_2_0_state.rs b/crates/contract/src/v3_2_0_state.rs new file mode 100644 index 000000000..bc4c9e1a2 --- /dev/null +++ b/crates/contract/src/v3_2_0_state.rs @@ -0,0 +1,83 @@ +//! ## Overview +//! This module stores the previous contract state—the one you want to migrate from. +//! The goal is to describe the data layout _exactly_ as it existed before. +//! +//! ## Guideline +//! In theory, you could copy-paste every struct from the specific commit you're migrating from. +//! However, this approach (a) requires manual effort from a developer and (b) increases the binary size. +//! A better approach: only copy the structures that have changed and import the rest from the existing codebase. + +use borsh::BorshDeserialize; +use mpc_attestation::attestation::Attestation; +use mpc_primitives::hash::LauncherDockerComposeHash; +use near_sdk::{ + env, + store::{IterableMap, LookupMap}, +}; + +use crate::{ + node_migrations::NodeMigrations, + primitives::{ + ckd::CKDRequest, + signature::{SignatureRequest, YieldIndex}, + }, + state::ProtocolContractState, + tee::{ + proposal::{AllowedDockerImageHashes, CodeHashesVotes}, + tee_state::NodeId, + }, + update::ProposedUpdates, + Config, +}; + +#[derive(Debug, BorshDeserialize)] +struct TeeState { + _allowed_docker_image_hashes: AllowedDockerImageHashes, + _allowed_launcher_compose_hashes: Vec, + _votes: CodeHashesVotes, + participants_attestations: IterableMap, +} + +#[derive(Debug, BorshDeserialize)] +pub struct MpcContract { + protocol_state: ProtocolContractState, + pending_signature_requests: LookupMap, + pending_ckd_requests: LookupMap, + proposed_updates: ProposedUpdates, + config: Config, + tee_state: TeeState, + accept_requests: bool, + node_migrations: NodeMigrations, +} + +impl From for crate::MpcContract { + fn from(value: MpcContract) -> Self { + let protocol_state = value.protocol_state; + + let crate::ProtocolContractState::Running(running_state) = &protocol_state else { + env::panic_str("Contract must be in running state when migrating."); + }; + + // For the soft release we give every participant a mocked attestation. + // Since this upgrade has a non-backwards compatible change, instead of manually mapping the attestations + // we give everyone a new mock attestation again instead. + // clear previous attestations from the storage trie + let stale_participant_attestations = value.tee_state.participants_attestations; + let threshold_parameters = &running_state.parameters.participants(); + let tee_state = crate::TeeState::with_mocked_participant_attestations(threshold_parameters); + + Self { + protocol_state, + pending_signature_requests: value.pending_signature_requests, + pending_ckd_requests: value.pending_ckd_requests, + proposed_updates: value.proposed_updates.into(), + config: value.config.into(), + tee_state, + accept_requests: value.accept_requests, + node_migrations: value.node_migrations, + stale_data: crate::StaleData { + participant_attestations: Some(stale_participant_attestations), + }, + } + } +} diff --git a/crates/contract/tests/sandbox/common.rs b/crates/contract/tests/sandbox/common.rs index cd61de372..4dbf63601 100644 --- a/crates/contract/tests/sandbox/common.rs +++ b/crates/contract/tests/sandbox/common.rs @@ -478,3 +478,16 @@ pub async fn generate_participant_and_submit_attestation( .expect("Attestation submission for new account must succeed."); (new_account, account_id, new_participant) } + +pub async fn cleanup_post_migrate(contract: &Contract, account: &Account) { + let execution = account + .call(contract.id(), "migrate_clear_tee") + .max_gas() + .transact() + .await + .unwrap() + .into_result() + .expect("migration cleanup succeeded"); + + dbg!(&execution); +} diff --git a/crates/contract/tests/sandbox/upgrade_to_current_contract.rs b/crates/contract/tests/sandbox/upgrade_to_current_contract.rs index 264602794..ce354eb7c 100644 --- a/crates/contract/tests/sandbox/upgrade_to_current_contract.rs +++ b/crates/contract/tests/sandbox/upgrade_to_current_contract.rs @@ -152,6 +152,8 @@ async fn propose_upgrade_from_production_to_current_binary( ) { use rand_core::OsRng; + use crate::sandbox::common::cleanup_post_migrate; + let worker = near_workspaces::sandbox().await.unwrap(); let contract = deploy_old(&worker, network).await.unwrap(); let (accounts, participants) = init_old_contract(&worker, &contract, PARTICIPANT_LEN) @@ -178,6 +180,8 @@ async fn propose_upgrade_from_production_to_current_binary( state_pre_upgrade, state_post_upgrade, "State of the contract should remain the same post upgrade." ); + + cleanup_post_migrate(&contract, &accounts[0]).await; } //// Verifies that upgrading the contract preserves state and functionality. diff --git a/expanded.rs b/expanded.rs new file mode 100644 index 000000000..c50cb9247 --- /dev/null +++ b/expanded.rs @@ -0,0 +1,30223 @@ + Checking mpc-contract v3.2.0 (/Users/dsharifi/Dev/mpc/crates/contract) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s + +#![feature(prelude_import)] +/*!# MPC Contract + +This crate defines the **MPC Contract**, which governs the MPC network and allows any NEAR account to request signatures. + +```text + ┌───────┐ ┌─────────────┐ ┌───────────┐ + │ User │ │ Participant │ │ MPC Node │ + └───────┘ └─────────────┘ └───────────┘ + │ │ │ +Request signature. │ │ + │ Vote on changes. │ + │ │ │ + └────────┐ │ ┌──Respond to signature requests. + │ │ │ + ▼ ▼ ▼ + ┌──────────────┐ + │ MPC Contract │ + └──────────────┘ + +``` + +## Live deployments + +The MPC contract is deployed on the [NEAR blockchain](https://nearblocks.io/address/v1.signer) +and on the [NEAR testnet](https://testnet.nearblocks.io/address/v1.signer-prod.testnet). + +## Role of the contract in Chain Signatures + +This contract serves as an interface to the MPC network. +Users and contracts can submit signature requests via this contract, +and MPC Participants can vote on changes to the MPC network, such as: + +- Changing the set of MPC participants. +- Adjusting the cryptographic threshold. +- Generating new distributed keys. +- Updating the contract code. + +## Contract State + +The contract tracks the following information: + +- Pending signature requests. +- Current participant set of the MPC network. +- Node migrations. +- Current set of keys managed by the MPC network (each key is associated to a unique `domain_id`). +- Metadata related to trusted execution environments. +- Current protocol state of the MPC network (see [Protocol State and Lifecycle](#protocol-state)). + +## Contract Updates + +Participants can propose and vote on contract updates (code or configuration changes). When an update receives sufficient votes and is executed (via the `vote_update` endpoint which calls `do_update` internally), all pending update proposals and votes are cleared as they are no longer be valid after the contract migration. The update ID counter is preserved across migrations as part of the contract state to avoid race conditions where multiple participants might propose updates with colliding IDs immediately after an upgrade. + +## Usage + +### Submitting a signature Request + +Users can submit a signature request to the MPC network via the `sign` endpoint of this contract. Note that a **deposit is required to cover storage costs** (minimum 1 yoctoNEAR) to prevent abuse by malicious frontends. Any excess deposit is automatically refunded to the user. + +The sign request takes the following arguments: + +- `path` (String): the derivation path (used for key-derivation). +- `payload_v2`: either + - `{"Ecdsa": ""}` or + - `{"Eddsa": ""}` +- `domain_id` (integer): identifies the key to use for generating the signature. Note that the payload type must match the associated signature scheme. + +Submitting a signature request costs approximately 7 Tgas, but the contract requires that at least 10 Tgas are attached to the transaction. + +#### Example + +_ECDSA Signature Request_ + +```Json +{ + "request": { + "payload_v2": { + "Ecdsa": "521da91dc9bddb625bd0679d9e735def558761a34653624f5954f44bce6443a9" + }, + "path": "sepolia-1", + "domain_id": 0 + } +} +``` + +_EDDSA Signature Request_ + +```Json +{ + "request": { + "payload_v2": { + "Eddsa": "521da91dc9bddb625bd0679d9e735def558761a34653624f5954f44bce6443a9" + }, + "path": "solana-1", + "domain_id": 1 + } +} +``` + +#### Ecdsa payload restrictions + +Note that an Ecdsa payload is subsequently represented as a Scalar on curve Secp256k1. This means that the payload must be strictly less than the field size `p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F` (see also [curve parameters](https://www.secg.org/sec2-v2.pdf#subsubsection.2.4.1) and [k256 implementation details](https://docs.rs/k256/latest/k256/struct.Scalar.html#method.from_repr)). + +### Submitting a confidential key derivation (ckd) request + +Users can submit a ckd request to the MPC network via the +`request_app_private_key` endpoint of this contract. Note that a **deposit is required to cover storage costs** (minimum 1 yoctoNEAR) to prevent abuse by malicious frontends. Any excess deposit is automatically refunded to the user. + +The ckd request takes the following arguments: + +- `derivation_path` (String): the derivation path (used to derive different keys from the same account). +- `"app_public_key": "bls12381g1:"` +- `domain_id` (integer): identifies the master key to use for deriving the ckd, and must correspond to bls12381. + +Note that `app_public_key` represents a valid point on curve BLS12381 (G1). + +Submitting a ckd request costs approximately 7 Tgas, but the contract requires +that at least 10 Tgas are attached to the transaction. + +#### Example + +_ckd request_ + +```Json +{ + "request": { + "derivation_path": "mykey", + "app_public_key": "bls12381g1:6KtVVcAAGacrjNGePN8bp3KV6fYGrw1rFsyc7cVJCqR16Zc2ZFg3HX3hSZxSfv1oH6", + "domain_id": 2 + } +} +``` + +### Changing the participant set + +The set of MPC participants can be changed, subject to following restrictions: + +- There must at least be `threshold` (the current threshold) number of current participants in the prospective participant set. +- The prospective threshold must be at least 60% of the number of participants (rounded upwards). +- The set of participants must have at least two participants. + +In order for a change to be accepted by the contract, all prospective participants must vote for it using the `vote_new_parameters` endpoint. Note that any new participants vote will only be accepted after at least `threshold` (the current threshold) old participants voted for the same participant set. + +#### Example + +```Json +{ + "prospective_epoch_id":1, + "proposal":{ + "threshold":3, + "participants":{ + "next_id":2, + "participants":[ + [ + "mpc-participant0.near", + 0, + { + "sign_pk":"ed25519:2XPuwqhg71RXRiTUMKGapd8FYWgXnxVvydYBK9tS1ex2", + "url":"http://mpc-service0.com" + } + ], + [ + "mpc-participant1.near", + 1, + { + "sign_pk":"ed25519:2XPuwqhg71RXRiTUMKGapd8FYWgXnxVvydYBK9tS1ex2", + "url":"http://mpc-service1.com" + } + ] + ] + } + } +} +``` + +### Adding a Key + +To generate a new threshold signature key, all participants must vote for it to be added via `vote_new_domain`. Only votes from existing participants will be accepted. + +```Json +{ + "domains":[ + { + "id":2, + "scheme":"Secp256k1" + }, + { + "id":3, + "scheme":"Ed25519" + }, + { + "id":4, + "scheme":"Bls12381" + } + ] +} +``` + +### Deployment + +After deploying the contract, it will first be in an uninitialized state. The owner will need to initialize it via `init`, providing the set of participants and threshold parameters. + +The contract will then switch to running state, where further operations (like initializing keys, or changing the participant set), can be taken. + +### Protocol State + +The following protocol state transitions are allowed. + +```mermaid +stateDiagram-v2 + direction LR + [*] --> NotInitialized : deploy + NotInitialized --> Running : init + Running --> Initializing : vote_add_domains + Running --> Resharing : vote_new_parameters + Initializing --> Running : vote_pk + Initializing --> Running : vote_cancel_keygen + Resharing --> Running : vote_reshared + Resharing --> Resharing : vote_new_parameters +``` + +## Contract API + +### User API + +| Function | Behavior | Return Value | Gas requirement | Effective Gas Cost | +| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------- | --------------- | ------------------ | +| `sign(request: SignRequestArgs)` | Submits a signature request to the contract. Requires a deposit to cover storage costs (minimum 1 yoctoNEAR). Excess deposit is refunded. Re-submitting the same request before the original request timed out or has been responded to may cause both requests to fail. | deferred to promise | `15 Tgas` | `~7 Tgas` | +| `request_app_private_key(request: CKDRequestArgs)` | Submits a confidential key derivation (CKD) request to the contract. Requires a deposit to cover storage costs (minimum 1 yoctoNEAR). Excess deposit is refunded. Re-submitting the same request before the original request timed out or has been responded to may cause both requests to fail. | deferred to promise | `15 Tgas` | `~7 Tgas` | +| `public_key(domain: Option)` | Read-only function; returns the public key used for the given domain (defaulting to first). | `Result` | | | +| `derived_public_key(path: String, predecessor: Option, domain: Option)` | Generates a derived public key for a given path and account, for the given domain (defaulting to first). | `Result` | | | + +#### SignRequestArgs (Latest version) + +The `sign` request takes the following arguments: + +- `path` (String): the derivation path. +- `payload_v2`: either `{"Ecdsa": ""}` or `{"Eddsa": ""}` +- `domain_id` (integer): the domain ID that identifies the key and signature scheme to use for signing. + +#### CKDRequestArgs (Latest version) + +The `request_app_private_key` request takes the following arguments: + +- `derivation_path` (String): the derivation path. +- `app_public_key` (String): the ephemeral public key to encrypt the generated confidential key +- `domain_id` (integer): the domain ID that identifies the key and signature scheme to use to generate the confidential key + +#### SignRequestArgs (Legacy version for backwards compatibility with V1) + +- The legacy argument `payload` can be used in place of `payload_v2`; the format for that is an array of 32 integer bytes. This argument can only be used + to pass in an ECDSA payload. +- The legacy argument `key_version` can be used in place of `domain_id` and means the same thing. + +### Participants API + +These functions require the caller to be a participant or candidate. + +| Function | Behavior | Return Value | Gas Requirement | Effective Gas Cost | +| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | --------------- | ------------------ | +| `respond(request: SignatureRequest, response: SignatureResponse)` | Processes a response to a signature request, verifying its validity and ensuring proper state cleanup. | `Result<(), Error>` | 10Tgas | ~6Tgas | +| `respond_ckd(request: CKDRequest, response: CKDResponse)` | Processes a response to a ckd request, ensuring proper state cleanup. | `Result<(), Error>` | 10Tgas | ~6Tgas | +| `vote_add_domains(domains: Vec)` | Votes to add new domains (new keys) to the MPC network; newly proposed domain IDs must start from next_domain_id and be contiguous. | `Result<(), Error>` | TBD | TBD | +| `vote_new_parameters(prospective_epoch_id: EpochId, proposal: ThresholdParameters)` | Votes to change the set of participants as well as the new threshold for the network. (Prospective epoch ID must be 1 plus current) | `Result<(), Error>` | TBD | TBD | +| `vote_code_hash(code_hash: CodeHash)` | Votes to add new whitelisted TEE Docker image code hashes. | `Result<(), Error>` | TBD | TBD | +| `start_keygen_instance(key_event_id: KeyEventId)` | For Initializing state only. Starts a new attempt to generate a key (key_event_id must be the expected one) | `Result<(), Error>` | TBD | TBD | +| `start_resharing_instance(key_event_id: KeyEventId)` | For Resharing state only. Starts a new attempt to reshare a key (key_event_id must be the expected one) | `Result<(), Error>` | TBD | TBD | +| `vote_pk(key_event_id: KeyEventId, public_key: PublicKey)` | For Initializing state only. Votes for the public key for the given generation attempt; if enough votes are collected, transitions to the next domain to generate a key for, or if all domains are completed, transitions into Running. | `Result<(), Error>` | TBD | TBD | +| `vote_reshared(key_event_id: KeyEventId)` | For Resharing state only. Votes for the success of the given resharing attempt; if enough votes are collected, transitions to the next domain to reshare for, or if all domains are completed, transitions into Running. | `Result<(), Error>` | TBD | TBD | +| `vote_cancel_keygen(next_domain_id: u64)` | For Initializing state only. Votes to cancel the key generation (identified by the next_domain_id) and revert to the Running state. | `Result<(), Error>` | TBD | TBD | +| `propose_update(args: ProposeUpdateArgs)` | Proposes an update to the contract, requiring an attached deposit. | `Result` | TBD | TBD | +| `vote_update(id: UpdateId)` | Votes on a proposed update. If the threshold is met, the update is executed. | `Result` | TBD | TBD | +| `propose_join(proposed_tee_participant: DstackAttestation, signer_pk: PublicKey)` | Submits the tee participant info for a potential candidate. c.f. TEE section | `Result<(), Error>` | TBD | TBD | + +### Developer API + +| Function | Behavior | Return Value | Gas Requirement | Effective Gas Cost | +| -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | --------------- | ------------------ | +| `init(parameters: ThresholdParameters, init_config: Option)` | Initializes the contract with a threshold, candidate participants, and config values. Can only be called once. This sets the contract state to `Running` with zero domains. vote_add_domains can be called to initialize key generation. | `Result` | TBD | TBD | +| `state()` | Returns the current state of the contract. | `&ProtocolContractState` | TBD | TBD | +| `get_pending_request(request: &SignatureRequest)` | Retrieves pending signature requests. | `Option` | TBD | TBD | +| `get_pending_ckd_request(request: &CKDRequest)` | Retrieves pending confidential key derivation requests. | `Option` | TBD | TBD | +| `config()` | Returns the contract configuration. | `&ConfigV1` | TBD | TBD | +| `version()` | Returns the contract version. | `String` | TBD | TBD | +| `update_config(config: ConfigV1)` | Updates the contract configuration for `V1`. | `()` | TBD | TBD | +| `clean_tee_status()` | Private endpoint. Cleans up TEE information for non-participants after resharing. Only callable by the contract itself via a promise. | `Result<(), Error>` | TBD | TBD | + +## Building the contract + +During development, it's recommended to build non-deterministically using [cargo-near](https://github.com/near/cargo-near). + +```bash +cargo near build non-reproducible-wasm --features abi --manifest-path crates/contract/Cargo.toml --locked +``` + +The contract can also be built deterministically. This requires `docker` to be installed. + +```bash +cargo near build reproducible-wasm --features abi --manifest-path crates/contract/Cargo.toml +``` + +## TEE Specific information + +The MPC nodes will eventually run inside a Trusted Execution Environments (TEE). The network is currently in a transitioning period, where both operation modes (TEE and non-TEE) are supported, however, the TEE support is at least as of June 2025, highly experimental and not stable. + +Participants that run their node inside a TEE will have to submit the following TEE related data to the contract: + +```rust +pub struct DstackAttestation { + /// TEE Remote Attestation Quote that proves the participant's identity. + pub quote: Quote, + /// Supplemental data for the TEE quote, including Intel certificates to verify it came from + /// genuine Intel hardware, along with details about the Trusted Computing Base (TCB) + /// versioning, status, and other relevant info. + pub collateral: Collateral, + /// Dstack event log. + pub tcb_info: TcbInfo, + /// Expected measurements for the TEE quote. + pub expected_measurements: ExpectedMeasurements, +} +``` + +The prospective node operator can retrieve that data from the web endpoint (`:8080/get_public_data`). + +The process of doing so is as follows: + +1. The prospective participants set up their MPC inside their TEE environment (todo: [#550](https://github.com/near/mpc/issues/550), documentation to follow). +2. The prospective participants fetch their TEE related information from their logs. +3. The prospective participants add the `near_signer_public_key` from the web endpoint (`:8080/get_public_data`) as an access key to their node operator account, eligible for calling the MPC contract (`v1.signer` on mainnet or `v1.signer-prod.testnet` on testnet). Participants should provide sufficient funding to this key. +4. The prospective participants add the `near_responder_public_keys` from the web endpoint to a different account and provide sufficient funding to it. +5. The participants submit their data to the contract via `propose_join`. +*/ +#![deny(clippy::mod_module_files)] +#![allow(clippy::disallowed_types)] +#[prelude_import] +use std::prelude::rust_2021::*; +#[macro_use] +extern crate std; +pub mod config { + use near_sdk::near; + /// Default for `key_event_timeout_blocks`. + const DEFAULT_KEY_EVENT_TIMEOUT_BLOCKS: u64 = 30; + /// Maximum time after which TEE MPC nodes must be upgraded to the latest version + const DEFAULT_TEE_UPGRADE_DEADLINE_DURATION_SECONDS: u64 = 7 * 24 * 60 * 60; + /// Amount of gas to deposit when creating an internal upgrade transaction promise. + /// Note this deposit must be less than 300, as the total gas usage including the + /// initial call itself to vote for the update can not exceed 300 Tgas. + const DEFAULT_CONTRACT_UPGRADE_DEPOSIT_TERA_GAS: u64 = 50; + /// Gas required for a sign request + const DEFAULT_SIGN_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS: u64 = 15; + /// Gas required for a CKD request + const DEFAULT_CKD_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS: u64 = 15; + /// Prepaid gas for a `return_signature_and_clean_state_on_success` call + const DEFAULT_RETURN_SIGNATURE_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS: u64 = 7; + /// Prepaid gas for a `return_ck_and_clean_state_on_success` call + const DEFAULT_RETURN_CK_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS: u64 = 7; + /// Prepaid gas for a `fail_on_timeout` call + const DEFAULT_FAIL_ON_TIMEOUT_TERA_GAS: u64 = 2; + /// Prepaid gas for a `clean_tee_status` call + const DEFAULT_CLEAN_TEE_STATUS_TERA_GAS: u64 = 10; + /// Prepaid gas for a `cleanup_orphaned_node_migrations` call + /// todo: benchmark [#1164](https://github.com/near/mpc/issues/1164) + const DEFAULT_CLEANUP_ORPHANED_NODE_MIGRATIONS_TERA_GAS: u64 = 3; + /// Prepaid gas for a `remove_non_participant_update_votes` call + const DEFAULT_REMOVE_NON_PARTICIPANT_UPDATE_VOTES_TERA_GAS: u64 = 5; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Config for V2 of the contract. + pub(crate) struct Config { + /// If a key event attempt has not successfully completed within this many blocks, + /// it is considered failed. + pub(crate) key_event_timeout_blocks: u64, + /// The grace period duration for expiry of old mpc image hashes once a new one is added. + pub(crate) tee_upgrade_deadline_duration_seconds: u64, + /// Amount of gas to deposit for contract and config updates. + pub(crate) contract_upgrade_deposit_tera_gas: u64, + /// Gas required for a sign request. + pub(crate) sign_call_gas_attachment_requirement_tera_gas: u64, + /// Gas required for a CKD request. + pub(crate) ckd_call_gas_attachment_requirement_tera_gas: u64, + /// Prepaid gas for a `return_signature_and_clean_state_on_success` call. + pub(crate) return_signature_and_clean_state_on_success_call_tera_gas: u64, + /// Prepaid gas for a `return_ck_and_clean_state_on_success` call. + pub(crate) return_ck_and_clean_state_on_success_call_tera_gas: u64, + /// Prepaid gas for a `fail_on_timeout` call. + pub(crate) fail_on_timeout_tera_gas: u64, + /// Prepaid gas for a `clean_tee_status` call. + pub(crate) clean_tee_status_tera_gas: u64, + /// Prepaid gas for a `cleanup_orphaned_node_migrations` call. + pub(crate) cleanup_orphaned_node_migrations_tera_gas: u64, + /// Prepaid gas for a `remove_non_participant_update_votes` call. + pub(crate) remove_non_participant_update_votes_tera_gas: u64, + } + #[automatically_derived] + impl ::core::clone::Clone for Config { + #[inline] + fn clone(&self) -> Config { + Config { + key_event_timeout_blocks: ::core::clone::Clone::clone( + &self.key_event_timeout_blocks, + ), + tee_upgrade_deadline_duration_seconds: ::core::clone::Clone::clone( + &self.tee_upgrade_deadline_duration_seconds, + ), + contract_upgrade_deposit_tera_gas: ::core::clone::Clone::clone( + &self.contract_upgrade_deposit_tera_gas, + ), + sign_call_gas_attachment_requirement_tera_gas: ::core::clone::Clone::clone( + &self.sign_call_gas_attachment_requirement_tera_gas, + ), + ckd_call_gas_attachment_requirement_tera_gas: ::core::clone::Clone::clone( + &self.ckd_call_gas_attachment_requirement_tera_gas, + ), + return_signature_and_clean_state_on_success_call_tera_gas: ::core::clone::Clone::clone( + &self.return_signature_and_clean_state_on_success_call_tera_gas, + ), + return_ck_and_clean_state_on_success_call_tera_gas: ::core::clone::Clone::clone( + &self.return_ck_and_clean_state_on_success_call_tera_gas, + ), + fail_on_timeout_tera_gas: ::core::clone::Clone::clone( + &self.fail_on_timeout_tera_gas, + ), + clean_tee_status_tera_gas: ::core::clone::Clone::clone( + &self.clean_tee_status_tera_gas, + ), + cleanup_orphaned_node_migrations_tera_gas: ::core::clone::Clone::clone( + &self.cleanup_orphaned_node_migrations_tera_gas, + ), + remove_non_participant_update_votes_tera_gas: ::core::clone::Clone::clone( + &self.remove_non_participant_update_votes_tera_gas, + ), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Config { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "key_event_timeout_blocks", + "tee_upgrade_deadline_duration_seconds", + "contract_upgrade_deposit_tera_gas", + "sign_call_gas_attachment_requirement_tera_gas", + "ckd_call_gas_attachment_requirement_tera_gas", + "return_signature_and_clean_state_on_success_call_tera_gas", + "return_ck_and_clean_state_on_success_call_tera_gas", + "fail_on_timeout_tera_gas", + "clean_tee_status_tera_gas", + "cleanup_orphaned_node_migrations_tera_gas", + "remove_non_participant_update_votes_tera_gas", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.key_event_timeout_blocks, + &self.tee_upgrade_deadline_duration_seconds, + &self.contract_upgrade_deposit_tera_gas, + &self.sign_call_gas_attachment_requirement_tera_gas, + &self.ckd_call_gas_attachment_requirement_tera_gas, + &self.return_signature_and_clean_state_on_success_call_tera_gas, + &self.return_ck_and_clean_state_on_success_call_tera_gas, + &self.fail_on_timeout_tera_gas, + &self.clean_tee_status_tera_gas, + &self.cleanup_orphaned_node_migrations_tera_gas, + &&self.remove_non_participant_update_votes_tera_gas, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "Config", + names, + values, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Config {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Config { + #[inline] + fn eq(&self, other: &Config) -> bool { + self.key_event_timeout_blocks == other.key_event_timeout_blocks + && self.tee_upgrade_deadline_duration_seconds + == other.tee_upgrade_deadline_duration_seconds + && self.contract_upgrade_deposit_tera_gas + == other.contract_upgrade_deposit_tera_gas + && self.sign_call_gas_attachment_requirement_tera_gas + == other.sign_call_gas_attachment_requirement_tera_gas + && self.ckd_call_gas_attachment_requirement_tera_gas + == other.ckd_call_gas_attachment_requirement_tera_gas + && self.return_signature_and_clean_state_on_success_call_tera_gas + == other.return_signature_and_clean_state_on_success_call_tera_gas + && self.return_ck_and_clean_state_on_success_call_tera_gas + == other.return_ck_and_clean_state_on_success_call_tera_gas + && self.fail_on_timeout_tera_gas == other.fail_on_timeout_tera_gas + && self.clean_tee_status_tera_gas == other.clean_tee_status_tera_gas + && self.cleanup_orphaned_node_migrations_tera_gas + == other.cleanup_orphaned_node_migrations_tera_gas + && self.remove_non_participant_update_votes_tera_gas + == other.remove_non_participant_update_votes_tera_gas + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Config { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for Config { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.key_event_timeout_blocks, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.tee_upgrade_deadline_duration_seconds, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.contract_upgrade_deposit_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.sign_call_gas_attachment_requirement_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.ckd_call_gas_attachment_requirement_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.return_signature_and_clean_state_on_success_call_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.return_ck_and_clean_state_on_success_call_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.fail_on_timeout_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.clean_tee_status_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.cleanup_orphaned_node_migrations_tera_gas, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.remove_non_participant_update_votes_tera_gas, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for Config { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + key_event_timeout_blocks: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + tee_upgrade_deadline_duration_seconds: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + contract_upgrade_deposit_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + sign_call_gas_attachment_requirement_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + ckd_call_gas_attachment_requirement_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + return_signature_and_clean_state_on_success_call_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + return_ck_and_clean_state_on_success_call_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + fail_on_timeout_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + clean_tee_status_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + cleanup_orphaned_node_migrations_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + remove_non_participant_update_votes_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Config { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Config", + false as usize + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key_event_timeout_blocks", + &self.key_event_timeout_blocks, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "tee_upgrade_deadline_duration_seconds", + &self.tee_upgrade_deadline_duration_seconds, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "contract_upgrade_deposit_tera_gas", + &self.contract_upgrade_deposit_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "sign_call_gas_attachment_requirement_tera_gas", + &self.sign_call_gas_attachment_requirement_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "ckd_call_gas_attachment_requirement_tera_gas", + &self.ckd_call_gas_attachment_requirement_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "return_signature_and_clean_state_on_success_call_tera_gas", + &self.return_signature_and_clean_state_on_success_call_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "return_ck_and_clean_state_on_success_call_tera_gas", + &self.return_ck_and_clean_state_on_success_call_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "fail_on_timeout_tera_gas", + &self.fail_on_timeout_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "clean_tee_status_tera_gas", + &self.clean_tee_status_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "cleanup_orphaned_node_migrations_tera_gas", + &self.cleanup_orphaned_node_migrations_tera_gas, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "remove_non_participant_update_votes_tera_gas", + &self.remove_non_participant_update_votes_tera_gas, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Config { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __field6, + __field7, + __field8, + __field9, + __field10, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + 4u64 => _serde::__private228::Ok(__Field::__field4), + 5u64 => _serde::__private228::Ok(__Field::__field5), + 6u64 => _serde::__private228::Ok(__Field::__field6), + 7u64 => _serde::__private228::Ok(__Field::__field7), + 8u64 => _serde::__private228::Ok(__Field::__field8), + 9u64 => _serde::__private228::Ok(__Field::__field9), + 10u64 => _serde::__private228::Ok(__Field::__field10), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "key_event_timeout_blocks" => { + _serde::__private228::Ok(__Field::__field0) + } + "tee_upgrade_deadline_duration_seconds" => { + _serde::__private228::Ok(__Field::__field1) + } + "contract_upgrade_deposit_tera_gas" => { + _serde::__private228::Ok(__Field::__field2) + } + "sign_call_gas_attachment_requirement_tera_gas" => { + _serde::__private228::Ok(__Field::__field3) + } + "ckd_call_gas_attachment_requirement_tera_gas" => { + _serde::__private228::Ok(__Field::__field4) + } + "return_signature_and_clean_state_on_success_call_tera_gas" => { + _serde::__private228::Ok(__Field::__field5) + } + "return_ck_and_clean_state_on_success_call_tera_gas" => { + _serde::__private228::Ok(__Field::__field6) + } + "fail_on_timeout_tera_gas" => { + _serde::__private228::Ok(__Field::__field7) + } + "clean_tee_status_tera_gas" => { + _serde::__private228::Ok(__Field::__field8) + } + "cleanup_orphaned_node_migrations_tera_gas" => { + _serde::__private228::Ok(__Field::__field9) + } + "remove_non_participant_update_votes_tera_gas" => { + _serde::__private228::Ok(__Field::__field10) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"key_event_timeout_blocks" => { + _serde::__private228::Ok(__Field::__field0) + } + b"tee_upgrade_deadline_duration_seconds" => { + _serde::__private228::Ok(__Field::__field1) + } + b"contract_upgrade_deposit_tera_gas" => { + _serde::__private228::Ok(__Field::__field2) + } + b"sign_call_gas_attachment_requirement_tera_gas" => { + _serde::__private228::Ok(__Field::__field3) + } + b"ckd_call_gas_attachment_requirement_tera_gas" => { + _serde::__private228::Ok(__Field::__field4) + } + b"return_signature_and_clean_state_on_success_call_tera_gas" => { + _serde::__private228::Ok(__Field::__field5) + } + b"return_ck_and_clean_state_on_success_call_tera_gas" => { + _serde::__private228::Ok(__Field::__field6) + } + b"fail_on_timeout_tera_gas" => { + _serde::__private228::Ok(__Field::__field7) + } + b"clean_tee_status_tera_gas" => { + _serde::__private228::Ok(__Field::__field8) + } + b"cleanup_orphaned_node_migrations_tera_gas" => { + _serde::__private228::Ok(__Field::__field9) + } + b"remove_non_participant_update_votes_tera_gas" => { + _serde::__private228::Ok(__Field::__field10) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Config; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct Config", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field5 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 5usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field6 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 6usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field7 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 7usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field8 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 8usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field9 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 9usize, + &"struct Config with 11 elements", + ), + ); + } + }; + let __field10 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 10usize, + &"struct Config with 11 elements", + ), + ); + } + }; + _serde::__private228::Ok(Config { + key_event_timeout_blocks: __field0, + tee_upgrade_deadline_duration_seconds: __field1, + contract_upgrade_deposit_tera_gas: __field2, + sign_call_gas_attachment_requirement_tera_gas: __field3, + ckd_call_gas_attachment_requirement_tera_gas: __field4, + return_signature_and_clean_state_on_success_call_tera_gas: __field5, + return_ck_and_clean_state_on_success_call_tera_gas: __field6, + fail_on_timeout_tera_gas: __field7, + clean_tee_status_tera_gas: __field8, + cleanup_orphaned_node_migrations_tera_gas: __field9, + remove_non_participant_update_votes_tera_gas: __field10, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + let mut __field3: _serde::__private228::Option = _serde::__private228::None; + let mut __field4: _serde::__private228::Option = _serde::__private228::None; + let mut __field5: _serde::__private228::Option = _serde::__private228::None; + let mut __field6: _serde::__private228::Option = _serde::__private228::None; + let mut __field7: _serde::__private228::Option = _serde::__private228::None; + let mut __field8: _serde::__private228::Option = _serde::__private228::None; + let mut __field9: _serde::__private228::Option = _serde::__private228::None; + let mut __field10: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "key_event_timeout_blocks", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "tee_upgrade_deadline_duration_seconds", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "contract_upgrade_deposit_tera_gas", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private228::Option::is_some(&__field3) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "sign_call_gas_attachment_requirement_tera_gas", + ), + ); + } + __field3 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private228::Option::is_some(&__field4) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "ckd_call_gas_attachment_requirement_tera_gas", + ), + ); + } + __field4 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field5 => { + if _serde::__private228::Option::is_some(&__field5) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "return_signature_and_clean_state_on_success_call_tera_gas", + ), + ); + } + __field5 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field6 => { + if _serde::__private228::Option::is_some(&__field6) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "return_ck_and_clean_state_on_success_call_tera_gas", + ), + ); + } + __field6 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field7 => { + if _serde::__private228::Option::is_some(&__field7) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "fail_on_timeout_tera_gas", + ), + ); + } + __field7 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field8 => { + if _serde::__private228::Option::is_some(&__field8) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "clean_tee_status_tera_gas", + ), + ); + } + __field8 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field9 => { + if _serde::__private228::Option::is_some(&__field9) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "cleanup_orphaned_node_migrations_tera_gas", + ), + ); + } + __field9 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field10 => { + if _serde::__private228::Option::is_some(&__field10) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "remove_non_participant_update_votes_tera_gas", + ), + ); + } + __field10 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "key_event_timeout_blocks", + )? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "tee_upgrade_deadline_duration_seconds", + )? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "contract_upgrade_deposit_tera_gas", + )? + } + }; + let __field3 = match __field3 { + _serde::__private228::Some(__field3) => __field3, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "sign_call_gas_attachment_requirement_tera_gas", + )? + } + }; + let __field4 = match __field4 { + _serde::__private228::Some(__field4) => __field4, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "ckd_call_gas_attachment_requirement_tera_gas", + )? + } + }; + let __field5 = match __field5 { + _serde::__private228::Some(__field5) => __field5, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "return_signature_and_clean_state_on_success_call_tera_gas", + )? + } + }; + let __field6 = match __field6 { + _serde::__private228::Some(__field6) => __field6, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "return_ck_and_clean_state_on_success_call_tera_gas", + )? + } + }; + let __field7 = match __field7 { + _serde::__private228::Some(__field7) => __field7, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "fail_on_timeout_tera_gas", + )? + } + }; + let __field8 = match __field8 { + _serde::__private228::Some(__field8) => __field8, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "clean_tee_status_tera_gas", + )? + } + }; + let __field9 = match __field9 { + _serde::__private228::Some(__field9) => __field9, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "cleanup_orphaned_node_migrations_tera_gas", + )? + } + }; + let __field10 = match __field10 { + _serde::__private228::Some(__field10) => __field10, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "remove_non_participant_update_votes_tera_gas", + )? + } + }; + _serde::__private228::Ok(Config { + key_event_timeout_blocks: __field0, + tee_upgrade_deadline_duration_seconds: __field1, + contract_upgrade_deposit_tera_gas: __field2, + sign_call_gas_attachment_requirement_tera_gas: __field3, + ckd_call_gas_attachment_requirement_tera_gas: __field4, + return_signature_and_clean_state_on_success_call_tera_gas: __field5, + return_ck_and_clean_state_on_success_call_tera_gas: __field6, + fail_on_timeout_tera_gas: __field7, + clean_tee_status_tera_gas: __field8, + cleanup_orphaned_node_migrations_tera_gas: __field9, + remove_non_participant_update_votes_tera_gas: __field10, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "key_event_timeout_blocks", + "tee_upgrade_deadline_duration_seconds", + "contract_upgrade_deposit_tera_gas", + "sign_call_gas_attachment_requirement_tera_gas", + "ckd_call_gas_attachment_requirement_tera_gas", + "return_signature_and_clean_state_on_success_call_tera_gas", + "return_ck_and_clean_state_on_success_call_tera_gas", + "fail_on_timeout_tera_gas", + "clean_tee_status_tera_gas", + "cleanup_orphaned_node_migrations_tera_gas", + "remove_non_participant_update_votes_tera_gas", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Config", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl Default for Config { + fn default() -> Self { + Self { + key_event_timeout_blocks: DEFAULT_KEY_EVENT_TIMEOUT_BLOCKS, + tee_upgrade_deadline_duration_seconds: DEFAULT_TEE_UPGRADE_DEADLINE_DURATION_SECONDS, + contract_upgrade_deposit_tera_gas: DEFAULT_CONTRACT_UPGRADE_DEPOSIT_TERA_GAS, + sign_call_gas_attachment_requirement_tera_gas: DEFAULT_SIGN_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS, + ckd_call_gas_attachment_requirement_tera_gas: DEFAULT_CKD_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS, + return_signature_and_clean_state_on_success_call_tera_gas: DEFAULT_RETURN_SIGNATURE_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS, + return_ck_and_clean_state_on_success_call_tera_gas: DEFAULT_RETURN_CK_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS, + fail_on_timeout_tera_gas: DEFAULT_FAIL_ON_TIMEOUT_TERA_GAS, + clean_tee_status_tera_gas: DEFAULT_CLEAN_TEE_STATUS_TERA_GAS, + cleanup_orphaned_node_migrations_tera_gas: DEFAULT_CLEANUP_ORPHANED_NODE_MIGRATIONS_TERA_GAS, + remove_non_participant_update_votes_tera_gas: DEFAULT_REMOVE_NON_PARTICIPANT_UPDATE_VOTES_TERA_GAS, + } + } + } +} +pub mod crypto_shared { + pub mod kdf { + use crate::{crypto_shared::types::k256_types, primitives::signature::Tweak}; + use anyhow::Context; + use curve25519_dalek::constants::ED25519_BASEPOINT_POINT; + use k256::{ + ecdsa::{RecoveryId, Signature}, + elliptic_curve::{ + point::AffineCoordinates, sec1::ToEncodedPoint, CurveArithmetic, + PrimeField, + }, + Secp256k1, + }; + use near_account_id::AccountId; + use sha3::{Digest, Sha3_256}; + use contract_interface::types as dtos; + const TWEAK_DERIVATION_PREFIX: &str = "near-mpc-recovery v0.1.0 epsilon derivation:"; + pub fn derive_tweak(predecessor_id: &AccountId, path: &str) -> Tweak { + let hash: [u8; 32] = derive_from_path( + TWEAK_DERIVATION_PREFIX, + predecessor_id, + path, + ); + Tweak::new(hash) + } + const APP_ID_DERIVATION_PREFIX: &str = "near-mpc v0.1.0 app_id derivation:"; + pub fn derive_app_id( + predecessor_id: &AccountId, + derivation_path: &str, + ) -> dtos::CkdAppId { + let hash: [u8; 32] = derive_from_path( + APP_ID_DERIVATION_PREFIX, + predecessor_id, + derivation_path, + ); + hash.into() + } + fn derive_from_path( + derivation_prefix: &str, + predecessor_id: &AccountId, + path: &str, + ) -> [u8; 32] { + let derivation_path = ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("{2}{0},{1}", predecessor_id, path, derivation_prefix), + ); + res + }); + let mut hasher = Sha3_256::new(); + hasher.update(derivation_path); + let hash: [u8; 32] = hasher.finalize().into(); + hash + } + pub struct TweakNotOnCurve; + #[automatically_derived] + impl ::core::fmt::Debug for TweakNotOnCurve { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "TweakNotOnCurve") + } + } + #[automatically_derived] + impl ::core::clone::Clone for TweakNotOnCurve { + #[inline] + fn clone(&self) -> TweakNotOnCurve { + TweakNotOnCurve + } + } + pub fn derive_key_secp256k1( + public_key: &k256_types::PublicKey, + tweak: &Tweak, + ) -> Result { + let tweak = k256::Scalar::from_repr(tweak.as_bytes().into()) + .into_option() + .ok_or(TweakNotOnCurve)?; + Ok( + (::ProjectivePoint::GENERATOR * tweak + + public_key) + .to_affine(), + ) + } + pub fn derive_public_key_edwards_point_ed25519( + public_key_edwards_point: &curve25519_dalek::EdwardsPoint, + tweak: &Tweak, + ) -> curve25519_dalek::EdwardsPoint { + let tweak = curve25519_dalek::Scalar::from_bytes_mod_order(tweak.as_bytes()); + public_key_edwards_point + ED25519_BASEPOINT_POINT * tweak + } + /// Get the x coordinate of a point, as a scalar + pub fn x_coordinate( + point: &::AffinePoint, + ) -> ::Scalar { + <::Scalar as k256::elliptic_curve::ops::Reduce< + ::Uint, + >>::reduce_bytes(&point.x()) + } + pub fn check_ec_signature( + expected_pk: &k256::AffinePoint, + big_r: &k256::AffinePoint, + s: &k256::Scalar, + msg_hash: &[u8; 32], + recovery_id: u8, + ) -> anyhow::Result<()> { + let public_key = expected_pk.to_encoded_point(false); + let signature = k256::ecdsa::Signature::from_scalars(x_coordinate(big_r), s) + .context("cannot create signature from cait_sith signature")?; + let found_pk = recover( + msg_hash, + &signature, + RecoveryId::try_from(recovery_id).context("invalid recovery ID")?, + )? + .to_encoded_point(false); + if public_key == found_pk { + return Ok(()); + } + return ::anyhow::__private::Err({ + let error = ::anyhow::__private::format_err( + format_args!( + "cannot use either recovery id={0} to recover pubic key", + recovery_id, + ), + ); + error + }); + } + #[cfg(not(target_arch = "wasm32"))] + pub fn recover( + prehash: &[u8], + signature: &Signature, + recovery_id: RecoveryId, + ) -> anyhow::Result { + k256::ecdsa::VerifyingKey::recover_from_prehash( + prehash, + signature, + recovery_id, + ) + .context("Unable to recover public key") + } + } + pub mod types { + pub mod serializable { + //! Module that adds implementation of [`BorshSerialize`] and [`BorshDeserialize`] for + //! [`PublicKeyExtended`]. + use borsh::{BorshDeserialize, BorshSerialize}; + use curve25519_dalek::EdwardsPoint; + use k256::elliptic_curve::{group::GroupEncoding, subtle::CtOption}; + use serde::{Deserialize, Serialize}; + pub struct SerializableEdwardsPoint(EdwardsPoint); + #[automatically_derived] + impl ::core::fmt::Debug for SerializableEdwardsPoint { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "SerializableEdwardsPoint", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SerializableEdwardsPoint {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SerializableEdwardsPoint { + #[inline] + fn eq(&self, other: &SerializableEdwardsPoint) -> bool { + self.0 == other.0 + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SerializableEdwardsPoint { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "SerializableEdwardsPoint", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SerializableEdwardsPoint { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + SerializableEdwardsPoint, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SerializableEdwardsPoint; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct SerializableEdwardsPoint", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: EdwardsPoint = ::deserialize( + __e, + )?; + _serde::__private228::Ok(SerializableEdwardsPoint(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + EdwardsPoint, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct SerializableEdwardsPoint with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(SerializableEdwardsPoint(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "SerializableEdwardsPoint", + __Visitor { + marker: _serde::__private228::PhantomData::< + SerializableEdwardsPoint, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::cmp::Eq for SerializableEdwardsPoint { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for SerializableEdwardsPoint { + #[inline] + fn clone(&self) -> SerializableEdwardsPoint { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for SerializableEdwardsPoint {} + #[allow(unreachable_code)] + #[automatically_derived] + impl derive_more::core::convert::From<(EdwardsPoint)> + for SerializableEdwardsPoint { + #[inline] + fn from(value: (EdwardsPoint)) -> Self { + SerializableEdwardsPoint(value) + } + } + #[allow(unreachable_code)] + #[automatically_derived] + impl derive_more::core::convert::AsRef + for SerializableEdwardsPoint { + #[inline] + fn as_ref(&self) -> &EdwardsPoint { + &self.0 + } + } + #[allow(unreachable_code)] + #[automatically_derived] + impl derive_more::with_trait::Deref for SerializableEdwardsPoint { + type Target = EdwardsPoint; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl GroupEncoding for SerializableEdwardsPoint { + type Repr = [u8; 32]; + fn from_bytes(bytes: &Self::Repr) -> CtOption { + EdwardsPoint::from_bytes(bytes).map(Into::into) + } + fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption { + Self::from_bytes(bytes) + } + fn to_bytes(&self) -> Self::Repr { + self.compress().to_bytes() + } + } + impl BorshSerialize for SerializableEdwardsPoint { + fn serialize( + &self, + writer: &mut W, + ) -> std::io::Result<()> { + let bytes = self.0.to_bytes(); + BorshSerialize::serialize(&bytes, writer) + } + } + impl BorshDeserialize for SerializableEdwardsPoint { + fn deserialize_reader( + reader: &mut R, + ) -> std::io::Result { + let bytes: [u8; 32] = BorshDeserialize::deserialize_reader(reader)?; + SerializableEdwardsPoint::from_bytes(&bytes) + .into_option() + .ok_or( + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "The provided bytes is not a valid edwards point.", + ), + ) + } + } + } + use std::fmt::Display; + use borsh::{BorshDeserialize, BorshSerialize}; + use k256::{ + elliptic_curve::{group::GroupEncoding, CurveArithmetic, PrimeField}, + AffinePoint, Secp256k1, + }; + use serde::{Deserialize, Serialize}; + use serde_with::serde_as; + use serializable::SerializableEdwardsPoint; + use crate::{errors, IntoContractType, IntoInterfaceType}; + use contract_interface::types as dtos; + #[serde(tag = "scheme")] + pub enum SignatureResponse { + Secp256k1(k256_types::Signature), + Ed25519 { signature: ed25519_types::Signature }, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SignatureResponse { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + SignatureResponse::Secp256k1(ref __field0) => { + _serde::__private228::ser::serialize_tagged_newtype( + __serializer, + "SignatureResponse", + "Secp256k1", + "scheme", + "Secp256k1", + __field0, + ) + } + SignatureResponse::Ed25519 { ref signature } => { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SignatureResponse", + 0 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "scheme", + "Ed25519", + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "signature", + signature, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SignatureResponse { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => { + _serde::__private228::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "Secp256k1" => _serde::__private228::Ok(__Field::__field0), + "Ed25519" => _serde::__private228::Ok(__Field::__field1), + _ => { + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"Secp256k1" => _serde::__private228::Ok(__Field::__field0), + b"Ed25519" => _serde::__private228::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private228::from_utf8_lossy( + __value, + ); + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &["Secp256k1", "Ed25519"]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private228::de::TaggedContentVisitor::< + __Field, + >::new("scheme", "internally tagged enum SignatureResponse"), + )?; + let __deserializer = _serde::__private228::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::__private228::Result::map( + ::deserialize( + __deserializer, + ), + SignatureResponse::Secp256k1, + ) + } + __Field::__field1 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "signature" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"signature" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + SignatureResponse, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SignatureResponse; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct variant SignatureResponse::Ed25519", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + ed25519_types::Signature, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant SignatureResponse::Ed25519 with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(SignatureResponse::Ed25519 { + signature: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + ed25519_types::Signature, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "signature", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + ed25519_types::Signature, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("signature")? + } + }; + _serde::__private228::Ok(SignatureResponse::Ed25519 { + signature: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["signature"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private228::PhantomData::< + SignatureResponse, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for SignatureResponse { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + SignatureResponse::Secp256k1(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Secp256k1", + &__self_0, + ) + } + SignatureResponse::Ed25519 { signature: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Ed25519", + "signature", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for SignatureResponse { + #[inline] + fn clone(&self) -> SignatureResponse { + match self { + SignatureResponse::Secp256k1(__self_0) => { + SignatureResponse::Secp256k1( + ::core::clone::Clone::clone(__self_0), + ) + } + SignatureResponse::Ed25519 { signature: __self_0 } => { + SignatureResponse::Ed25519 { + signature: ::core::clone::Clone::clone(__self_0), + } + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SignatureResponse {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SignatureResponse { + #[inline] + fn eq(&self, other: &SignatureResponse) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + ( + SignatureResponse::Secp256k1(__self_0), + SignatureResponse::Secp256k1(__arg1_0), + ) => __self_0 == __arg1_0, + ( + SignatureResponse::Ed25519 { signature: __self_0 }, + SignatureResponse::Ed25519 { signature: __arg1_0 }, + ) => __self_0 == __arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for SignatureResponse { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + pub struct CKDResponse { + pub big_y: dtos::Bls12381G1PublicKey, + pub big_c: dtos::Bls12381G1PublicKey, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for CKDResponse { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "CKDResponse", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "big_y", + &self.big_y, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "big_c", + &self.big_c, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for CKDResponse { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "big_y" => _serde::__private228::Ok(__Field::__field0), + "big_c" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"big_y" => _serde::__private228::Ok(__Field::__field0), + b"big_c" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = CKDResponse; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct CKDResponse", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + dtos::Bls12381G1PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct CKDResponse with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + dtos::Bls12381G1PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct CKDResponse with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(CKDResponse { + big_y: __field0, + big_c: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + dtos::Bls12381G1PublicKey, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + dtos::Bls12381G1PublicKey, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("big_y"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + dtos::Bls12381G1PublicKey, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("big_c"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + dtos::Bls12381G1PublicKey, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("big_y")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("big_c")? + } + }; + _serde::__private228::Ok(CKDResponse { + big_y: __field0, + big_c: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["big_y", "big_c"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "CKDResponse", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for CKDResponse { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "CKDResponse", + "big_y", + &self.big_y, + "big_c", + &&self.big_c, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for CKDResponse { + #[inline] + fn clone(&self) -> CKDResponse { + CKDResponse { + big_y: ::core::clone::Clone::clone(&self.big_y), + big_c: ::core::clone::Clone::clone(&self.big_c), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for CKDResponse {} + #[automatically_derived] + impl ::core::cmp::PartialEq for CKDResponse { + #[inline] + fn eq(&self, other: &CKDResponse) -> bool { + self.big_y == other.big_y && self.big_c == other.big_c + } + } + #[automatically_derived] + impl ::core::cmp::Eq for CKDResponse { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + pub enum PublicKeyExtended { + Secp256k1 { near_public_key: near_sdk::PublicKey }, + Ed25519 { + /// Serialized compressed Edwards-y point. + near_public_key_compressed: near_sdk::PublicKey, + /// Decompressed Edwards point used for curve arithmetic operations. + edwards_point: SerializableEdwardsPoint, + }, + Bls12381 { public_key: dtos::PublicKey }, + } + #[automatically_derived] + impl ::core::fmt::Debug for PublicKeyExtended { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + PublicKeyExtended::Secp256k1 { near_public_key: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Secp256k1", + "near_public_key", + &__self_0, + ) + } + PublicKeyExtended::Ed25519 { + near_public_key_compressed: __self_0, + edwards_point: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Ed25519", + "near_public_key_compressed", + __self_0, + "edwards_point", + &__self_1, + ) + } + PublicKeyExtended::Bls12381 { public_key: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Bls12381", + "public_key", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for PublicKeyExtended {} + #[automatically_derived] + impl ::core::cmp::PartialEq for PublicKeyExtended { + #[inline] + fn eq(&self, other: &PublicKeyExtended) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + ( + PublicKeyExtended::Secp256k1 { near_public_key: __self_0 }, + PublicKeyExtended::Secp256k1 { near_public_key: __arg1_0 }, + ) => __self_0 == __arg1_0, + ( + PublicKeyExtended::Ed25519 { + near_public_key_compressed: __self_0, + edwards_point: __self_1, + }, + PublicKeyExtended::Ed25519 { + near_public_key_compressed: __arg1_0, + edwards_point: __arg1_1, + }, + ) => __self_0 == __arg1_0 && __self_1 == __arg1_1, + ( + PublicKeyExtended::Bls12381 { public_key: __self_0 }, + PublicKeyExtended::Bls12381 { public_key: __arg1_0 }, + ) => __self_0 == __arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for PublicKeyExtended { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for PublicKeyExtended { + #[inline] + fn clone(&self) -> PublicKeyExtended { + match self { + PublicKeyExtended::Secp256k1 { near_public_key: __self_0 } => { + PublicKeyExtended::Secp256k1 { + near_public_key: ::core::clone::Clone::clone(__self_0), + } + } + PublicKeyExtended::Ed25519 { + near_public_key_compressed: __self_0, + edwards_point: __self_1, + } => { + PublicKeyExtended::Ed25519 { + near_public_key_compressed: ::core::clone::Clone::clone( + __self_0, + ), + edwards_point: ::core::clone::Clone::clone(__self_1), + } + } + PublicKeyExtended::Bls12381 { public_key: __self_0 } => { + PublicKeyExtended::Bls12381 { + public_key: ::core::clone::Clone::clone(__self_0), + } + } + } + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for PublicKeyExtended { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + PublicKeyExtended::Secp256k1 { ref near_public_key } => { + let mut __serde_state = _serde::Serializer::serialize_struct_variant( + __serializer, + "PublicKeyExtended", + 0u32, + "Secp256k1", + 0 + 1, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "near_public_key", + near_public_key, + )?; + _serde::ser::SerializeStructVariant::end(__serde_state) + } + PublicKeyExtended::Ed25519 { + ref near_public_key_compressed, + ref edwards_point, + } => { + let mut __serde_state = _serde::Serializer::serialize_struct_variant( + __serializer, + "PublicKeyExtended", + 1u32, + "Ed25519", + 0 + 1 + 1, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "near_public_key_compressed", + near_public_key_compressed, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "edwards_point", + edwards_point, + )?; + _serde::ser::SerializeStructVariant::end(__serde_state) + } + PublicKeyExtended::Bls12381 { ref public_key } => { + let mut __serde_state = _serde::Serializer::serialize_struct_variant( + __serializer, + "PublicKeyExtended", + 2u32, + "Bls12381", + 0 + 1, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "public_key", + public_key, + )?; + _serde::ser::SerializeStructVariant::end(__serde_state) + } + } + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for PublicKeyExtended { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => { + _serde::__private228::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 3", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "Secp256k1" => _serde::__private228::Ok(__Field::__field0), + "Ed25519" => _serde::__private228::Ok(__Field::__field1), + "Bls12381" => _serde::__private228::Ok(__Field::__field2), + _ => { + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"Secp256k1" => _serde::__private228::Ok(__Field::__field0), + b"Ed25519" => _serde::__private228::Ok(__Field::__field1), + b"Bls12381" => _serde::__private228::Ok(__Field::__field2), + _ => { + let __value = &_serde::__private228::from_utf8_lossy( + __value, + ); + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = PublicKeyExtended; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "enum PublicKeyExtended", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "near_public_key" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"near_public_key" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + PublicKeyExtended, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = PublicKeyExtended; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct variant PublicKeyExtended::Secp256k1", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + near_sdk::PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant PublicKeyExtended::Secp256k1 with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(PublicKeyExtended::Secp256k1 { + near_public_key: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + near_sdk::PublicKey, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "near_public_key", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + near_sdk::PublicKey, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("near_public_key")? + } + }; + _serde::__private228::Ok(PublicKeyExtended::Secp256k1 { + near_public_key: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "near_public_key", + ]; + _serde::de::VariantAccess::struct_variant( + __variant, + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + PublicKeyExtended, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + (__Field::__field1, __variant) => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "near_public_key_compressed" => { + _serde::__private228::Ok(__Field::__field0) + } + "edwards_point" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"near_public_key_compressed" => { + _serde::__private228::Ok(__Field::__field0) + } + b"edwards_point" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + PublicKeyExtended, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = PublicKeyExtended; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct variant PublicKeyExtended::Ed25519", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + near_sdk::PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant PublicKeyExtended::Ed25519 with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + SerializableEdwardsPoint, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct variant PublicKeyExtended::Ed25519 with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(PublicKeyExtended::Ed25519 { + near_public_key_compressed: __field0, + edwards_point: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + near_sdk::PublicKey, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + SerializableEdwardsPoint, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "near_public_key_compressed", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + near_sdk::PublicKey, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "edwards_point", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + SerializableEdwardsPoint, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "near_public_key_compressed", + )? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("edwards_point")? + } + }; + _serde::__private228::Ok(PublicKeyExtended::Ed25519 { + near_public_key_compressed: __field0, + edwards_point: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "near_public_key_compressed", + "edwards_point", + ]; + _serde::de::VariantAccess::struct_variant( + __variant, + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + PublicKeyExtended, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + (__Field::__field2, __variant) => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "public_key" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"public_key" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + PublicKeyExtended, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = PublicKeyExtended; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct variant PublicKeyExtended::Bls12381", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + dtos::PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant PublicKeyExtended::Bls12381 with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(PublicKeyExtended::Bls12381 { + public_key: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + dtos::PublicKey, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "public_key", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + dtos::PublicKey, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("public_key")? + } + }; + _serde::__private228::Ok(PublicKeyExtended::Bls12381 { + public_key: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["public_key"]; + _serde::de::VariantAccess::struct_variant( + __variant, + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + PublicKeyExtended, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "Secp256k1", + "Ed25519", + "Bls12381", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "PublicKeyExtended", + VARIANTS, + __Visitor { + marker: _serde::__private228::PhantomData::< + PublicKeyExtended, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl borsh::ser::BorshSerialize for PublicKeyExtended { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + let variant_idx: u8 = match self { + PublicKeyExtended::Secp256k1 { .. } => 0u8, + PublicKeyExtended::Ed25519 { .. } => 1u8, + PublicKeyExtended::Bls12381 { .. } => 2u8, + }; + writer.write_all(&variant_idx.to_le_bytes())?; + match self { + PublicKeyExtended::Secp256k1 { near_public_key, .. } => { + borsh::BorshSerialize::serialize(near_public_key, writer)?; + } + PublicKeyExtended::Ed25519 { + near_public_key_compressed, + edwards_point, + .. + } => { + borsh::BorshSerialize::serialize( + near_public_key_compressed, + writer, + )?; + borsh::BorshSerialize::serialize(edwards_point, writer)?; + } + PublicKeyExtended::Bls12381 { public_key, .. } => { + borsh::BorshSerialize::serialize(public_key, writer)?; + } + } + Ok(()) + } + } + impl borsh::de::BorshDeserialize for PublicKeyExtended { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + let tag = ::deserialize_reader( + reader, + )?; + ::deserialize_variant(reader, tag) + } + } + impl borsh::de::EnumExt for PublicKeyExtended { + fn deserialize_variant<__R: borsh::io::Read>( + reader: &mut __R, + variant_tag: u8, + ) -> ::core::result::Result { + let mut return_value = if variant_tag == 0u8 { + PublicKeyExtended::Secp256k1 { + near_public_key: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + } + } else if variant_tag == 1u8 { + PublicKeyExtended::Ed25519 { + near_public_key_compressed: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + edwards_point: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + } + } else if variant_tag == 2u8 { + PublicKeyExtended::Bls12381 { + public_key: borsh::BorshDeserialize::deserialize_reader(reader)?, + } + } else { + return Err( + borsh::io::Error::new( + borsh::io::ErrorKind::InvalidData, + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Unexpected variant tag: {0:?}", variant_tag), + ); + res + }), + ), + ) + }; + Ok(return_value) + } + } + pub enum PublicKeyExtendedConversionError { + PublicKeyLengthMalformed, + FailedDecompressingToEdwardsPoint, + } + #[automatically_derived] + impl ::core::clone::Clone for PublicKeyExtendedConversionError { + #[inline] + fn clone(&self) -> PublicKeyExtendedConversionError { + match self { + PublicKeyExtendedConversionError::PublicKeyLengthMalformed => { + PublicKeyExtendedConversionError::PublicKeyLengthMalformed + } + PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint => { + PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for PublicKeyExtendedConversionError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + PublicKeyExtendedConversionError::PublicKeyLengthMalformed => { + "PublicKeyLengthMalformed" + } + PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint => { + "FailedDecompressingToEdwardsPoint" + } + }, + ) + } + } + impl Display for PublicKeyExtendedConversionError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let message = match self { + Self::PublicKeyLengthMalformed => { + "Provided public key has malformed length." + } + Self::FailedDecompressingToEdwardsPoint => { + "The provided compressed key can not be decompressed to an edwards point." + } + }; + f.write_str(message) + } + } + impl TryFrom for near_sdk::PublicKey { + type Error = errors::Error; + fn try_from( + public_key_extended: PublicKeyExtended, + ) -> Result { + match public_key_extended { + PublicKeyExtended::Secp256k1 { near_public_key } => { + Ok(near_public_key) + } + PublicKeyExtended::Ed25519 { near_public_key_compressed, .. } => { + Ok(near_public_key_compressed) + } + PublicKeyExtended::Bls12381 { public_key: _ } => { + Err( + errors::ConversionError::DataConversion + .message( + "Cannot convert Bls12381 key to near_sdk::PublicKey", + ), + )? + } + } + } + } + impl From for dtos::PublicKey { + fn from(public_key_extended: PublicKeyExtended) -> Self { + match public_key_extended { + PublicKeyExtended::Secp256k1 { near_public_key } => { + near_public_key.into_dto_type() + } + PublicKeyExtended::Ed25519 { near_public_key_compressed, .. } => { + near_public_key_compressed.into_dto_type() + } + PublicKeyExtended::Bls12381 { public_key } => public_key, + } + } + } + impl TryFrom for PublicKeyExtended { + type Error = PublicKeyExtendedConversionError; + fn try_from( + near_public_key: near_sdk::PublicKey, + ) -> Result { + let extended_key = match near_public_key.curve_type() { + near_sdk::CurveType::ED25519 => { + let public_key_bytes: &[u8; 32] = near_public_key + .as_bytes() + .get(1..) + .map(TryInto::try_into) + .ok_or( + PublicKeyExtendedConversionError::PublicKeyLengthMalformed, + )? + .map_err(|_| { + PublicKeyExtendedConversionError::PublicKeyLengthMalformed + })?; + let edwards_point = SerializableEdwardsPoint::from_bytes( + public_key_bytes, + ) + .into_option() + .ok_or( + PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint, + )?; + Self::Ed25519 { + near_public_key_compressed: near_public_key, + edwards_point, + } + } + near_sdk::CurveType::SECP256K1 => Self::Secp256k1 { near_public_key }, + }; + Ok(extended_key) + } + } + impl TryFrom for PublicKeyExtended { + type Error = PublicKeyExtendedConversionError; + fn try_from(public_key: dtos::PublicKey) -> Result { + let extended_key = match public_key { + dtos::PublicKey::Ed25519(inner_public_key) => { + let near_public_key = inner_public_key.into_contract_type(); + let public_key_bytes: &[u8; 32] = near_public_key + .as_bytes() + .get(1..) + .map(TryInto::try_into) + .ok_or( + PublicKeyExtendedConversionError::PublicKeyLengthMalformed, + )? + .map_err(|_| { + PublicKeyExtendedConversionError::PublicKeyLengthMalformed + })?; + let edwards_point = SerializableEdwardsPoint::from_bytes( + public_key_bytes, + ) + .into_option() + .ok_or( + PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint, + )?; + Self::Ed25519 { + near_public_key_compressed: near_public_key, + edwards_point, + } + } + dtos::PublicKey::Secp256k1(inner_public_key) => { + let near_public_key = inner_public_key.into_contract_type(); + Self::Secp256k1 { near_public_key } + } + dtos::PublicKey::Bls12381(inner_public_key) => { + Self::Bls12381 { + public_key: dtos::PublicKey::from(inner_public_key), + } + } + }; + Ok(extended_key) + } + } + pub mod k256_types { + use super::*; + use k256::Scalar; + pub type PublicKey = ::AffinePoint; + pub struct SerializableScalar { + pub scalar: Scalar, + } + #[automatically_derived] + impl ::core::fmt::Debug for SerializableScalar { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "SerializableScalar", + "scalar", + &&self.scalar, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SerializableScalar {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SerializableScalar { + #[inline] + fn eq(&self, other: &SerializableScalar) -> bool { + self.scalar == other.scalar + } + } + #[automatically_derived] + impl ::core::cmp::Eq for SerializableScalar { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SerializableScalar { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SerializableScalar", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "scalar", + &self.scalar, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SerializableScalar { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "scalar" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"scalar" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + SerializableScalar, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SerializableScalar; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct SerializableScalar", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Scalar, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SerializableScalar with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(SerializableScalar { + scalar: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("scalar"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("scalar")? + } + }; + _serde::__private228::Ok(SerializableScalar { + scalar: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["scalar"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SerializableScalar", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + SerializableScalar, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for SerializableScalar { + #[inline] + fn clone(&self) -> SerializableScalar { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for SerializableScalar {} + #[automatically_derived] + impl ::core::cmp::Ord for SerializableScalar { + #[inline] + fn cmp(&self, other: &SerializableScalar) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.scalar, &other.scalar) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for SerializableScalar { + #[inline] + fn partial_cmp( + &self, + other: &SerializableScalar, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.scalar, &other.scalar) + } + } + impl SerializableScalar { + pub fn new(scalar: Scalar) -> Self { + Self { scalar } + } + } + impl From for SerializableScalar { + fn from(scalar: Scalar) -> Self { + Self { scalar } + } + } + impl BorshSerialize for SerializableScalar { + fn serialize( + &self, + writer: &mut W, + ) -> std::io::Result<()> { + let to_ser: [u8; 32] = self.scalar.to_bytes().into(); + BorshSerialize::serialize(&to_ser, writer) + } + } + impl BorshDeserialize for SerializableScalar { + fn deserialize_reader( + reader: &mut R, + ) -> std::io::Result { + let from_ser: [u8; 32] = BorshDeserialize::deserialize_reader( + reader, + )?; + let scalar = Scalar::from_repr(from_ser.into()) + .into_option() + .ok_or( + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "The given scalar is not in the field of Secp256k1", + ), + )?; + Ok(SerializableScalar { scalar }) + } + } + pub struct SerializableAffinePoint { + pub affine_point: AffinePoint, + } + #[automatically_derived] + impl ::core::fmt::Debug for SerializableAffinePoint { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "SerializableAffinePoint", + "affine_point", + &&self.affine_point, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SerializableAffinePoint {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SerializableAffinePoint { + #[inline] + fn eq(&self, other: &SerializableAffinePoint) -> bool { + self.affine_point == other.affine_point + } + } + #[automatically_derived] + impl ::core::cmp::Eq for SerializableAffinePoint { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SerializableAffinePoint { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SerializableAffinePoint", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "affine_point", + &self.affine_point, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SerializableAffinePoint { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "affine_point" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"affine_point" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + SerializableAffinePoint, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SerializableAffinePoint; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct SerializableAffinePoint", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + AffinePoint, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SerializableAffinePoint with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(SerializableAffinePoint { + affine_point: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + AffinePoint, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "affine_point", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + AffinePoint, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("affine_point")? + } + }; + _serde::__private228::Ok(SerializableAffinePoint { + affine_point: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["affine_point"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SerializableAffinePoint", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + SerializableAffinePoint, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for SerializableAffinePoint { + #[inline] + fn clone(&self) -> SerializableAffinePoint { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for SerializableAffinePoint {} + pub struct Signature { + pub big_r: SerializableAffinePoint, + pub s: SerializableScalar, + pub recovery_id: u8, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Signature { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Signature", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "big_r", + &self.big_r, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "s", + &self.s, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "recovery_id", + &self.recovery_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Signature { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "big_r" => _serde::__private228::Ok(__Field::__field0), + "s" => _serde::__private228::Ok(__Field::__field1), + "recovery_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"big_r" => _serde::__private228::Ok(__Field::__field0), + b"s" => _serde::__private228::Ok(__Field::__field1), + b"recovery_id" => { + _serde::__private228::Ok(__Field::__field2) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Signature; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct Signature", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + SerializableAffinePoint, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Signature with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + SerializableScalar, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Signature with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + u8, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct Signature with 3 elements", + ), + ); + } + }; + _serde::__private228::Ok(Signature { + big_r: __field0, + s: __field1, + recovery_id: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + SerializableAffinePoint, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + SerializableScalar, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("big_r"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + SerializableAffinePoint, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("s"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + SerializableScalar, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "recovery_id", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("big_r")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("s")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("recovery_id")? + } + }; + _serde::__private228::Ok(Signature { + big_r: __field0, + s: __field1, + recovery_id: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "big_r", + "s", + "recovery_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Signature", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for Signature { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "Signature", + "big_r", + &self.big_r, + "s", + &self.s, + "recovery_id", + &&self.recovery_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Signature { + #[inline] + fn clone(&self) -> Signature { + Signature { + big_r: ::core::clone::Clone::clone(&self.big_r), + s: ::core::clone::Clone::clone(&self.s), + recovery_id: ::core::clone::Clone::clone(&self.recovery_id), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Signature {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Signature { + #[inline] + fn eq(&self, other: &Signature) -> bool { + self.big_r == other.big_r && self.s == other.s + && self.recovery_id == other.recovery_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Signature { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + impl Signature { + pub fn new( + big_r: AffinePoint, + s: k256::Scalar, + recovery_id: u8, + ) -> Self { + Signature { + big_r: SerializableAffinePoint { + affine_point: big_r, + }, + s: s.into(), + recovery_id, + } + } + } + } + pub mod ed25519_types { + use super::*; + use curve25519_dalek::Scalar; + pub struct SerializableScalar { + scalar: Scalar, + } + #[automatically_derived] + impl ::core::fmt::Debug for SerializableScalar { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "SerializableScalar", + "scalar", + &&self.scalar, + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SerializableScalar { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SerializableScalar", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "scalar", + &self.scalar, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SerializableScalar { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "scalar" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"scalar" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + SerializableScalar, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SerializableScalar; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct SerializableScalar", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Scalar, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SerializableScalar with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(SerializableScalar { + scalar: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("scalar"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("scalar")? + } + }; + _serde::__private228::Ok(SerializableScalar { + scalar: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["scalar"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SerializableScalar", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + SerializableScalar, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SerializableScalar {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SerializableScalar { + #[inline] + fn eq(&self, other: &SerializableScalar) -> bool { + self.scalar == other.scalar + } + } + #[automatically_derived] + impl ::core::cmp::Eq for SerializableScalar { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for SerializableScalar { + #[inline] + fn clone(&self) -> SerializableScalar { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for SerializableScalar {} + impl SerializableScalar { + pub fn new(scalar: Scalar) -> Self { + Self { scalar } + } + } + impl From for SerializableScalar { + fn from(scalar: Scalar) -> Self { + Self { scalar } + } + } + impl BorshSerialize for SerializableScalar { + fn serialize( + &self, + writer: &mut W, + ) -> std::io::Result<()> { + let to_ser: [u8; 32] = self.scalar.to_bytes(); + BorshSerialize::serialize(&to_ser, writer) + } + } + impl BorshDeserialize for SerializableScalar { + fn deserialize_reader( + reader: &mut R, + ) -> std::io::Result { + let from_ser: [u8; 32] = BorshDeserialize::deserialize_reader( + reader, + )?; + let scalar = Scalar::from_repr(from_ser) + .into_option() + .ok_or( + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "The given scalar is not in the field of ed25519", + ), + )?; + Ok(SerializableScalar { scalar }) + } + } + impl Ord for SerializableScalar { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.scalar.as_bytes().cmp(other.scalar.as_bytes()) + } + } + impl PartialOrd for SerializableScalar { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + pub struct Signature( + #[serde_as(r#as = "[_; 64]")] + #[serde(with = ":: serde_with :: As :: < [:: serde_with :: Same; 64] >")] + [u8; 64], + ); + impl borsh::de::BorshDeserialize for Signature { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self(borsh::BorshDeserialize::deserialize_reader(reader)?)) + } + } + impl borsh::ser::BorshSerialize for Signature { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Signature { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "Signature", + &{ + #[doc(hidden)] + struct __SerializeWith<'__a> { + values: (&'__a [u8; 64],), + phantom: _serde::__private228::PhantomData, + } + #[automatically_derived] + impl<'__a> _serde::Serialize for __SerializeWith<'__a> { + fn serialize<__S>( + &self, + __s: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + ::serde_with::As::< + [::serde_with::Same; 64], + >::serialize(self.values.0, __s) + } + } + __SerializeWith { + values: (&self.0,), + phantom: _serde::__private228::PhantomData::, + } + }, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Signature { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Signature; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct Signature", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: [u8; 64] = ::serde_with::As::< + [::serde_with::Same; 64], + >::deserialize(__e)?; + _serde::__private228::Ok(Signature(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match { + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: [u8; 64], + phantom: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private228::Ok(__DeserializeWith { + value: ::serde_with::As::< + [::serde_with::Same; 64], + >::deserialize(__deserializer)?, + phantom: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData, + }) + } + } + _serde::__private228::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct Signature with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(Signature(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "Signature", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for Signature { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Signature", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Signature { + #[inline] + fn clone(&self) -> Signature { + Signature(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Signature {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Signature { + #[inline] + fn eq(&self, other: &Signature) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Signature { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; + } + } + impl Signature { + pub fn as_bytes(&self) -> &[u8; 64] { + &self.0 + } + pub fn new(bytes: [u8; 64]) -> Self { + Self(bytes) + } + } + } + } + use k256::{elliptic_curve::sec1::FromEncodedPoint, EncodedPoint}; + pub use kdf::{derive_key_secp256k1, derive_tweak, x_coordinate}; + pub use types::{ + ed25519_types, k256_types::{self, SerializableScalar}, + CKDResponse, SignatureResponse, + }; + pub fn near_public_key_to_affine_point( + pk: near_sdk::PublicKey, + ) -> k256_types::PublicKey { + match (&pk.curve_type(), &near_sdk::CurveType::SECP256K1) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + let kind = ::core::panicking::AssertKind::Eq; + ::core::panicking::assert_failed( + kind, + &*left_val, + &*right_val, + ::core::option::Option::Some( + format_args!("Expected a key on the SECP256K1 curve"), + ), + ); + } + } + }; + let mut bytes = pk.into_bytes(); + bytes[0] = 0x04; + let point = EncodedPoint::from_bytes(bytes).unwrap(); + k256_types::PublicKey::from_encoded_point(&point).unwrap() + } +} +pub mod errors { + use std::borrow::Cow; + use crate::primitives::{domain::DomainId, key_state::EpochId}; + mod impls { + use std::borrow::Cow; + use std::fmt; + use crate::crypto_shared::kdf::TweakNotOnCurve; + use super::{ + ConversionError, DomainError, Error, ErrorKind, ErrorRepr, + InvalidCandidateSet, InvalidParameters, InvalidState, InvalidThreshold, + KeyEventError, NodeMigrationError, PublicKeyError, RespondError, SignError, + TeeError, VoteError, + }; + impl Error { + /// Construct a contract [`Error`] with the details of an error which includes + /// the custom error message with further context and the [`ErrorKind`] that + /// represents the category of error. + pub fn message(kind: ErrorKind, msg: T) -> Self + where + T: Into>, + { + Self { + repr: ErrorRepr::Message { + kind, + message: msg.into(), + }, + } + } + /// Construct a contract [`Error`] with the details of an error which only + /// includes the [`ErrorKind`] that represents the category of error. + pub fn simple(kind: ErrorKind) -> Self { + Self { + repr: ErrorRepr::Simple(kind), + } + } + /// Returns the corresponding [`ErrorKind`] for this error. + pub fn kind(&self) -> &ErrorKind { + match &self.repr { + ErrorRepr::Simple(kind) => kind, + ErrorRepr::Message { kind, .. } => kind, + } + } + } + impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self.repr { + ErrorRepr::Simple(kind) => f.write_fmt(format_args!("{0}", kind)), + ErrorRepr::Message { kind, message } => { + f.write_fmt(format_args!("{0}: {1}", kind, message)) + } + } + } + } + impl From for Error { + fn from(code: SignError) -> Self { + Self::simple(ErrorKind::Sign(code)) + } + } + impl From for Error { + fn from(code: RespondError) -> Self { + Self::simple(ErrorKind::Respond(code)) + } + } + impl From for Error { + fn from(code: PublicKeyError) -> Self { + Self::simple(ErrorKind::PublicKey(code)) + } + } + impl From for Error { + fn from(code: VoteError) -> Self { + Self::simple(ErrorKind::Vote(code)) + } + } + impl From for Error { + fn from(code: InvalidParameters) -> Self { + Self::simple(ErrorKind::InvalidParameters(code)) + } + } + impl From for Error { + fn from(code: NodeMigrationError) -> Self { + Self::simple(ErrorKind::NodeMigrationError(code)) + } + } + impl NodeMigrationError { + pub(crate) fn message(self, msg: T) -> Error + where + T: Into>, + { + Error::message(ErrorKind::NodeMigrationError(self), msg) + } + } + impl InvalidParameters { + pub(crate) fn message(self, msg: T) -> Error + where + T: Into>, + { + Error::message(ErrorKind::InvalidParameters(self), msg) + } + } + impl RespondError { + pub(crate) fn message(self, msg: T) -> Error + where + T: Into>, + { + Error::message(ErrorKind::Respond(self), msg) + } + } + impl From for Error { + fn from(code: InvalidState) -> Self { + Self::simple(ErrorKind::InvalidState(code)) + } + } + impl InvalidState { + pub(crate) fn message(self, msg: T) -> Error + where + T: Into>, + { + Error::message(ErrorKind::InvalidState(self), msg) + } + } + impl From for Error { + fn from(code: ConversionError) -> Self { + Self::simple(ErrorKind::ConversionError(code)) + } + } + impl ConversionError { + pub(crate) fn message(self, msg: T) -> Error + where + T: Into>, + { + Error::message(ErrorKind::ConversionError(self), msg) + } + } + impl From for Error { + fn from(code: KeyEventError) -> Self { + Self::simple(ErrorKind::KeyEventError(code)) + } + } + impl From for Error { + fn from(code: TeeError) -> Self { + Self::simple(ErrorKind::TeeError(code)) + } + } + impl InvalidThreshold { + pub(crate) fn message(self, msg: T) -> Error + where + T: Into>, + { + Error::message(ErrorKind::InvalidThreshold(self), msg) + } + } + impl From for Error { + fn from(code: InvalidThreshold) -> Self { + Self::simple(ErrorKind::InvalidThreshold(code)) + } + } + impl From for Error { + fn from(code: InvalidCandidateSet) -> Self { + Self::simple(ErrorKind::InvalidCandidateSet(code)) + } + } + impl From for Error { + fn from(code: DomainError) -> Self { + Self::simple(ErrorKind::DomainError(code)) + } + } + impl From for PublicKeyError { + fn from(_: TweakNotOnCurve) -> Self { + Self::TweakNotOnCurve + } + } + impl From for RespondError { + fn from(_: TweakNotOnCurve) -> Self { + Self::TweakNotOnCurve + } + } + } + pub enum NodeMigrationError { + #[error("Node dose not have an ongoing recovery")] + MigrationNotFound, + #[error( + "The transaction was submitted by a different public key than expected." + )] + AccountPublicKeyMismatch, + #[error("The submitted keyset differs from the expected keyset.")] + KeysetMismatch, + } + #[automatically_derived] + impl ::core::fmt::Debug for NodeMigrationError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + NodeMigrationError::MigrationNotFound => "MigrationNotFound", + NodeMigrationError::AccountPublicKeyMismatch => { + "AccountPublicKeyMismatch" + } + NodeMigrationError::KeysetMismatch => "KeysetMismatch", + }, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for NodeMigrationError { + #[inline] + fn clone(&self) -> NodeMigrationError { + match self { + NodeMigrationError::MigrationNotFound => { + NodeMigrationError::MigrationNotFound + } + NodeMigrationError::AccountPublicKeyMismatch => { + NodeMigrationError::AccountPublicKeyMismatch + } + NodeMigrationError::KeysetMismatch => NodeMigrationError::KeysetMismatch, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for NodeMigrationError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for NodeMigrationError { + #[inline] + fn eq(&self, other: &NodeMigrationError) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for NodeMigrationError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for NodeMigrationError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for NodeMigrationError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + NodeMigrationError::MigrationNotFound {} => { + __formatter.write_str("Node dose not have an ongoing recovery") + } + NodeMigrationError::AccountPublicKeyMismatch {} => { + __formatter + .write_str( + "The transaction was submitted by a different public key than expected.", + ) + } + NodeMigrationError::KeysetMismatch {} => { + __formatter + .write_str( + "The submitted keyset differs from the expected keyset.", + ) + } + } + } + } + pub enum TeeError { + #[error( + "Due to previously failed TEE validation, the network is not accepting new requests at this point in time. Try again later." + )] + TeeValidationFailed, + } + #[automatically_derived] + impl ::core::fmt::Debug for TeeError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "TeeValidationFailed") + } + } + #[automatically_derived] + impl ::core::clone::Clone for TeeError { + #[inline] + fn clone(&self) -> TeeError { + TeeError::TeeValidationFailed + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TeeError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TeeError { + #[inline] + fn eq(&self, other: &TeeError) -> bool { + true + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TeeError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for TeeError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for TeeError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + TeeError::TeeValidationFailed {} => { + __formatter + .write_str( + "Due to previously failed TEE validation, the network is not accepting new requests at this point in time. Try again later.", + ) + } + } + } + } + pub enum RequestError { + #[error("Request has timed out.")] + Timeout, + } + #[automatically_derived] + impl ::core::fmt::Debug for RequestError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "Timeout") + } + } + #[automatically_derived] + impl ::core::clone::Clone for RequestError { + #[inline] + fn clone(&self) -> RequestError { + RequestError::Timeout + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RequestError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RequestError { + #[inline] + fn eq(&self, other: &RequestError) -> bool { + true + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RequestError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for RequestError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for RequestError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + RequestError::Timeout {} => { + __formatter.write_str("Request has timed out.") + } + } + } + } + pub enum SignError { + #[error("Signature request has already been submitted. Please try again later.")] + PayloadCollision, + #[error( + "This key version is not supported. Call latest_key_version() to get the latest supported version." + )] + UnsupportedKeyVersion, + } + #[automatically_derived] + impl ::core::fmt::Debug for SignError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + SignError::PayloadCollision => "PayloadCollision", + SignError::UnsupportedKeyVersion => "UnsupportedKeyVersion", + }, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for SignError { + #[inline] + fn clone(&self) -> SignError { + match self { + SignError::PayloadCollision => SignError::PayloadCollision, + SignError::UnsupportedKeyVersion => SignError::UnsupportedKeyVersion, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SignError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SignError { + #[inline] + fn eq(&self, other: &SignError) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for SignError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for SignError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for SignError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + SignError::PayloadCollision {} => { + __formatter + .write_str( + "Signature request has already been submitted. Please try again later.", + ) + } + SignError::UnsupportedKeyVersion {} => { + __formatter + .write_str( + "This key version is not supported. Call latest_key_version() to get the latest supported version.", + ) + } + } + } + } + pub enum RespondError { + #[error("The provided signature is invalid.")] + InvalidSignature, + #[error( + "The provided signature scheme does not match the requestued key's scheme" + )] + SignatureSchemeMismatch, + #[error("The provided domain was not found.")] + DomainNotFound, + #[error("The provided tweak is not on the curve of the public key.")] + TweakNotOnCurve, + } + #[automatically_derived] + impl ::core::fmt::Debug for RespondError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + RespondError::InvalidSignature => "InvalidSignature", + RespondError::SignatureSchemeMismatch => "SignatureSchemeMismatch", + RespondError::DomainNotFound => "DomainNotFound", + RespondError::TweakNotOnCurve => "TweakNotOnCurve", + }, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RespondError { + #[inline] + fn clone(&self) -> RespondError { + match self { + RespondError::InvalidSignature => RespondError::InvalidSignature, + RespondError::SignatureSchemeMismatch => { + RespondError::SignatureSchemeMismatch + } + RespondError::DomainNotFound => RespondError::DomainNotFound, + RespondError::TweakNotOnCurve => RespondError::TweakNotOnCurve, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RespondError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RespondError { + #[inline] + fn eq(&self, other: &RespondError) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RespondError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for RespondError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for RespondError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + RespondError::InvalidSignature {} => { + __formatter.write_str("The provided signature is invalid.") + } + RespondError::SignatureSchemeMismatch {} => { + __formatter + .write_str( + "The provided signature scheme does not match the requestued key's scheme", + ) + } + RespondError::DomainNotFound {} => { + __formatter.write_str("The provided domain was not found.") + } + RespondError::TweakNotOnCurve {} => { + __formatter + .write_str( + "The provided tweak is not on the curve of the public key.", + ) + } + } + } + } + pub enum PublicKeyError { + #[error("Derived key conversion failed.")] + DerivedKeyConversionFailed, + #[error("The provided domain was not found.")] + DomainNotFound, + #[error("The provided tweak is not on the curve of the public key.")] + TweakNotOnCurve, + } + #[automatically_derived] + impl ::core::fmt::Debug for PublicKeyError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + PublicKeyError::DerivedKeyConversionFailed => { + "DerivedKeyConversionFailed" + } + PublicKeyError::DomainNotFound => "DomainNotFound", + PublicKeyError::TweakNotOnCurve => "TweakNotOnCurve", + }, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for PublicKeyError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for PublicKeyError { + #[inline] + fn eq(&self, other: &PublicKeyError) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for PublicKeyError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + impl ::core::clone::Clone for PublicKeyError { + #[inline] + fn clone(&self) -> PublicKeyError { + match self { + PublicKeyError::DerivedKeyConversionFailed => { + PublicKeyError::DerivedKeyConversionFailed + } + PublicKeyError::DomainNotFound => PublicKeyError::DomainNotFound, + PublicKeyError::TweakNotOnCurve => PublicKeyError::TweakNotOnCurve, + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for PublicKeyError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for PublicKeyError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + PublicKeyError::DerivedKeyConversionFailed {} => { + __formatter.write_str("Derived key conversion failed.") + } + PublicKeyError::DomainNotFound {} => { + __formatter.write_str("The provided domain was not found.") + } + PublicKeyError::TweakNotOnCurve {} => { + __formatter + .write_str( + "The provided tweak is not on the curve of the public key.", + ) + } + } + } + } + pub enum KeyEventError { + #[error("Key event Id mismatch")] + KeyEventIdMismatch, + #[error( + "Can not start a new reshare or keygen instance while the current instance is still active." + )] + ActiveKeyEvent, + #[error("Expected ongoing reshare")] + NoActiveKeyEvent, + } + #[automatically_derived] + impl ::core::fmt::Debug for KeyEventError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + KeyEventError::KeyEventIdMismatch => "KeyEventIdMismatch", + KeyEventError::ActiveKeyEvent => "ActiveKeyEvent", + KeyEventError::NoActiveKeyEvent => "NoActiveKeyEvent", + }, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for KeyEventError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for KeyEventError { + #[inline] + fn eq(&self, other: &KeyEventError) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for KeyEventError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + impl ::core::clone::Clone for KeyEventError { + #[inline] + fn clone(&self) -> KeyEventError { + match self { + KeyEventError::KeyEventIdMismatch => KeyEventError::KeyEventIdMismatch, + KeyEventError::ActiveKeyEvent => KeyEventError::ActiveKeyEvent, + KeyEventError::NoActiveKeyEvent => KeyEventError::NoActiveKeyEvent, + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for KeyEventError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for KeyEventError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + KeyEventError::KeyEventIdMismatch {} => { + __formatter.write_str("Key event Id mismatch") + } + KeyEventError::ActiveKeyEvent {} => { + __formatter + .write_str( + "Can not start a new reshare or keygen instance while the current instance is still active.", + ) + } + KeyEventError::NoActiveKeyEvent {} => { + __formatter.write_str("Expected ongoing reshare") + } + } + } + } + pub enum VoteError { + #[error("Voting account is not a participant.")] + VoterNotParticipant, + #[error("Voting account is neither a participant, nor a proposed participant.")] + VoterNotParticipantNorProposedParticipant, + #[error("This participant already registered a vote.")] + ParticipantVoteAlreadyRegistered, + #[error( + "Voting account is not the leader of the current reshare or keygen instance." + )] + VoterNotLeader, + #[error("Inconsistent voting state")] + InconsistentVotingState, + #[error("Voter already aborted the current key event.")] + VoterAlreadyAborted, + #[error("Vote already casted.")] + VoteAlreadySubmitted, + #[error( + "Candidates can only cast a vote after `threshold` participants casted one to admit them" + )] + VoterPending, + } + #[automatically_derived] + impl ::core::fmt::Debug for VoteError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + VoteError::VoterNotParticipant => "VoterNotParticipant", + VoteError::VoterNotParticipantNorProposedParticipant => { + "VoterNotParticipantNorProposedParticipant" + } + VoteError::ParticipantVoteAlreadyRegistered => { + "ParticipantVoteAlreadyRegistered" + } + VoteError::VoterNotLeader => "VoterNotLeader", + VoteError::InconsistentVotingState => "InconsistentVotingState", + VoteError::VoterAlreadyAborted => "VoterAlreadyAborted", + VoteError::VoteAlreadySubmitted => "VoteAlreadySubmitted", + VoteError::VoterPending => "VoterPending", + }, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for VoteError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for VoteError { + #[inline] + fn eq(&self, other: &VoteError) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for VoteError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + impl ::core::clone::Clone for VoteError { + #[inline] + fn clone(&self) -> VoteError { + match self { + VoteError::VoterNotParticipant => VoteError::VoterNotParticipant, + VoteError::VoterNotParticipantNorProposedParticipant => { + VoteError::VoterNotParticipantNorProposedParticipant + } + VoteError::ParticipantVoteAlreadyRegistered => { + VoteError::ParticipantVoteAlreadyRegistered + } + VoteError::VoterNotLeader => VoteError::VoterNotLeader, + VoteError::InconsistentVotingState => VoteError::InconsistentVotingState, + VoteError::VoterAlreadyAborted => VoteError::VoterAlreadyAborted, + VoteError::VoteAlreadySubmitted => VoteError::VoteAlreadySubmitted, + VoteError::VoterPending => VoteError::VoterPending, + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for VoteError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for VoteError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + VoteError::VoterNotParticipant {} => { + __formatter.write_str("Voting account is not a participant.") + } + VoteError::VoterNotParticipantNorProposedParticipant {} => { + __formatter + .write_str( + "Voting account is neither a participant, nor a proposed participant.", + ) + } + VoteError::ParticipantVoteAlreadyRegistered {} => { + __formatter.write_str("This participant already registered a vote.") + } + VoteError::VoterNotLeader {} => { + __formatter + .write_str( + "Voting account is not the leader of the current reshare or keygen instance.", + ) + } + VoteError::InconsistentVotingState {} => { + __formatter.write_str("Inconsistent voting state") + } + VoteError::VoterAlreadyAborted {} => { + __formatter.write_str("Voter already aborted the current key event.") + } + VoteError::VoteAlreadySubmitted {} => { + __formatter.write_str("Vote already casted.") + } + VoteError::VoterPending {} => { + __formatter + .write_str( + "Candidates can only cast a vote after `threshold` participants casted one to admit them", + ) + } + } + } + } + pub enum InvalidParameters { + #[error("Malformed payload.")] + MalformedPayload, + #[error("Attached deposit is lower than required.")] + InsufficientDeposit, + #[error("Provided gas is lower than required.")] + InsufficientGas, + #[error("This sign request has timed out, was completed, or never existed.")] + RequestNotFound, + #[error("Update not found.")] + UpdateNotFound, + #[error("Participant already in set.")] + ParticipantAlreadyInSet, + #[error("Participant id already used.")] + ParticipantAlreadyUsed, + #[error("The provided domain ID, {provided}, was not found.")] + DomainNotFound { provided: DomainId }, + #[error("Provided Epoch Id, {provided}, does not match expected, {expected}.")] + EpochMismatch { provided: EpochId, expected: EpochId }, + #[error("Next domain ID mismatch")] + NextDomainIdMismatch, + #[error("Invalid domain ID.")] + InvalidDomainId, + #[error("Invalid TEE Remote Attestation.")] + InvalidTeeRemoteAttestation, + #[error("Invalid app public key.")] + InvalidAppPublicKey, + #[error("The provided TLS key is not valid.")] + InvalidTlsPublicKey, + #[error("Caller is not the signer account.")] + CallerNotSigner, + } + #[automatically_derived] + impl ::core::fmt::Debug for InvalidParameters { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + InvalidParameters::MalformedPayload => { + ::core::fmt::Formatter::write_str(f, "MalformedPayload") + } + InvalidParameters::InsufficientDeposit => { + ::core::fmt::Formatter::write_str(f, "InsufficientDeposit") + } + InvalidParameters::InsufficientGas => { + ::core::fmt::Formatter::write_str(f, "InsufficientGas") + } + InvalidParameters::RequestNotFound => { + ::core::fmt::Formatter::write_str(f, "RequestNotFound") + } + InvalidParameters::UpdateNotFound => { + ::core::fmt::Formatter::write_str(f, "UpdateNotFound") + } + InvalidParameters::ParticipantAlreadyInSet => { + ::core::fmt::Formatter::write_str(f, "ParticipantAlreadyInSet") + } + InvalidParameters::ParticipantAlreadyUsed => { + ::core::fmt::Formatter::write_str(f, "ParticipantAlreadyUsed") + } + InvalidParameters::DomainNotFound { provided: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "DomainNotFound", + "provided", + &__self_0, + ) + } + InvalidParameters::EpochMismatch { + provided: __self_0, + expected: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "EpochMismatch", + "provided", + __self_0, + "expected", + &__self_1, + ) + } + InvalidParameters::NextDomainIdMismatch => { + ::core::fmt::Formatter::write_str(f, "NextDomainIdMismatch") + } + InvalidParameters::InvalidDomainId => { + ::core::fmt::Formatter::write_str(f, "InvalidDomainId") + } + InvalidParameters::InvalidTeeRemoteAttestation => { + ::core::fmt::Formatter::write_str(f, "InvalidTeeRemoteAttestation") + } + InvalidParameters::InvalidAppPublicKey => { + ::core::fmt::Formatter::write_str(f, "InvalidAppPublicKey") + } + InvalidParameters::InvalidTlsPublicKey => { + ::core::fmt::Formatter::write_str(f, "InvalidTlsPublicKey") + } + InvalidParameters::CallerNotSigner => { + ::core::fmt::Formatter::write_str(f, "CallerNotSigner") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for InvalidParameters {} + #[automatically_derived] + impl ::core::cmp::PartialEq for InvalidParameters { + #[inline] + fn eq(&self, other: &InvalidParameters) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + ( + InvalidParameters::DomainNotFound { provided: __self_0 }, + InvalidParameters::DomainNotFound { provided: __arg1_0 }, + ) => __self_0 == __arg1_0, + ( + InvalidParameters::EpochMismatch { + provided: __self_0, + expected: __self_1, + }, + InvalidParameters::EpochMismatch { + provided: __arg1_0, + expected: __arg1_1, + }, + ) => __self_0 == __arg1_0 && __self_1 == __arg1_1, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for InvalidParameters { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for InvalidParameters { + #[inline] + fn clone(&self) -> InvalidParameters { + match self { + InvalidParameters::MalformedPayload => { + InvalidParameters::MalformedPayload + } + InvalidParameters::InsufficientDeposit => { + InvalidParameters::InsufficientDeposit + } + InvalidParameters::InsufficientGas => InvalidParameters::InsufficientGas, + InvalidParameters::RequestNotFound => InvalidParameters::RequestNotFound, + InvalidParameters::UpdateNotFound => InvalidParameters::UpdateNotFound, + InvalidParameters::ParticipantAlreadyInSet => { + InvalidParameters::ParticipantAlreadyInSet + } + InvalidParameters::ParticipantAlreadyUsed => { + InvalidParameters::ParticipantAlreadyUsed + } + InvalidParameters::DomainNotFound { provided: __self_0 } => { + InvalidParameters::DomainNotFound { + provided: ::core::clone::Clone::clone(__self_0), + } + } + InvalidParameters::EpochMismatch { + provided: __self_0, + expected: __self_1, + } => { + InvalidParameters::EpochMismatch { + provided: ::core::clone::Clone::clone(__self_0), + expected: ::core::clone::Clone::clone(__self_1), + } + } + InvalidParameters::NextDomainIdMismatch => { + InvalidParameters::NextDomainIdMismatch + } + InvalidParameters::InvalidDomainId => InvalidParameters::InvalidDomainId, + InvalidParameters::InvalidTeeRemoteAttestation => { + InvalidParameters::InvalidTeeRemoteAttestation + } + InvalidParameters::InvalidAppPublicKey => { + InvalidParameters::InvalidAppPublicKey + } + InvalidParameters::InvalidTlsPublicKey => { + InvalidParameters::InvalidTlsPublicKey + } + InvalidParameters::CallerNotSigner => InvalidParameters::CallerNotSigner, + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for InvalidParameters {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for InvalidParameters { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use ::thiserror::__private17::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + InvalidParameters::MalformedPayload {} => { + __formatter.write_str("Malformed payload.") + } + InvalidParameters::InsufficientDeposit {} => { + __formatter.write_str("Attached deposit is lower than required.") + } + InvalidParameters::InsufficientGas {} => { + __formatter.write_str("Provided gas is lower than required.") + } + InvalidParameters::RequestNotFound {} => { + __formatter + .write_str( + "This sign request has timed out, was completed, or never existed.", + ) + } + InvalidParameters::UpdateNotFound {} => { + __formatter.write_str("Update not found.") + } + InvalidParameters::ParticipantAlreadyInSet {} => { + __formatter.write_str("Participant already in set.") + } + InvalidParameters::ParticipantAlreadyUsed {} => { + __formatter.write_str("Participant id already used.") + } + InvalidParameters::DomainNotFound { provided } => { + match (provided.as_display(),) { + (__display_provided,) => { + __formatter + .write_fmt( + format_args!( + "The provided domain ID, {0}, was not found.", + __display_provided, + ), + ) + } + } + } + InvalidParameters::EpochMismatch { provided, expected } => { + match (provided.as_display(), expected.as_display()) { + (__display_provided, __display_expected) => { + __formatter + .write_fmt( + format_args!( + "Provided Epoch Id, {0}, does not match expected, {1}.", + __display_provided, + __display_expected, + ), + ) + } + } + } + InvalidParameters::NextDomainIdMismatch {} => { + __formatter.write_str("Next domain ID mismatch") + } + InvalidParameters::InvalidDomainId {} => { + __formatter.write_str("Invalid domain ID.") + } + InvalidParameters::InvalidTeeRemoteAttestation {} => { + __formatter.write_str("Invalid TEE Remote Attestation.") + } + InvalidParameters::InvalidAppPublicKey {} => { + __formatter.write_str("Invalid app public key.") + } + InvalidParameters::InvalidTlsPublicKey {} => { + __formatter.write_str("The provided TLS key is not valid.") + } + InvalidParameters::CallerNotSigner {} => { + __formatter.write_str("Caller is not the signer account.") + } + } + } + } + pub enum InvalidState { + #[error("The protocol is not Running.")] + ProtocolStateNotRunning, + #[error("Protocol state is not resharing.")] + ProtocolStateNotResharing, + #[error("Protocol state is not initializing.")] + ProtocolStateNotInitializing, + #[error("Protocol state is not running, nor resharing.")] + ProtocolStateNotRunningNorResharing, + #[error("Unexpected protocol state.")] + UnexpectedProtocolState, + #[error("Cannot load in contract due to missing state")] + ContractStateIsMissing, + #[error("Participant index out of range")] + ParticipantIndexOutOfRange, + #[error("Not a participant")] + NotParticipant, + } + #[automatically_derived] + impl ::core::fmt::Debug for InvalidState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + InvalidState::ProtocolStateNotRunning => "ProtocolStateNotRunning", + InvalidState::ProtocolStateNotResharing => { + "ProtocolStateNotResharing" + } + InvalidState::ProtocolStateNotInitializing => { + "ProtocolStateNotInitializing" + } + InvalidState::ProtocolStateNotRunningNorResharing => { + "ProtocolStateNotRunningNorResharing" + } + InvalidState::UnexpectedProtocolState => "UnexpectedProtocolState", + InvalidState::ContractStateIsMissing => "ContractStateIsMissing", + InvalidState::ParticipantIndexOutOfRange => { + "ParticipantIndexOutOfRange" + } + InvalidState::NotParticipant => "NotParticipant", + }, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for InvalidState {} + #[automatically_derived] + impl ::core::cmp::PartialEq for InvalidState { + #[inline] + fn eq(&self, other: &InvalidState) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for InvalidState { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + impl ::core::clone::Clone for InvalidState { + #[inline] + fn clone(&self) -> InvalidState { + match self { + InvalidState::ProtocolStateNotRunning => { + InvalidState::ProtocolStateNotRunning + } + InvalidState::ProtocolStateNotResharing => { + InvalidState::ProtocolStateNotResharing + } + InvalidState::ProtocolStateNotInitializing => { + InvalidState::ProtocolStateNotInitializing + } + InvalidState::ProtocolStateNotRunningNorResharing => { + InvalidState::ProtocolStateNotRunningNorResharing + } + InvalidState::UnexpectedProtocolState => { + InvalidState::UnexpectedProtocolState + } + InvalidState::ContractStateIsMissing => { + InvalidState::ContractStateIsMissing + } + InvalidState::ParticipantIndexOutOfRange => { + InvalidState::ParticipantIndexOutOfRange + } + InvalidState::NotParticipant => InvalidState::NotParticipant, + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for InvalidState {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for InvalidState { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + InvalidState::ProtocolStateNotRunning {} => { + __formatter.write_str("The protocol is not Running.") + } + InvalidState::ProtocolStateNotResharing {} => { + __formatter.write_str("Protocol state is not resharing.") + } + InvalidState::ProtocolStateNotInitializing {} => { + __formatter.write_str("Protocol state is not initializing.") + } + InvalidState::ProtocolStateNotRunningNorResharing {} => { + __formatter + .write_str("Protocol state is not running, nor resharing.") + } + InvalidState::UnexpectedProtocolState {} => { + __formatter.write_str("Unexpected protocol state.") + } + InvalidState::ContractStateIsMissing {} => { + __formatter.write_str("Cannot load in contract due to missing state") + } + InvalidState::ParticipantIndexOutOfRange {} => { + __formatter.write_str("Participant index out of range") + } + InvalidState::NotParticipant {} => { + __formatter.write_str("Not a participant") + } + } + } + } + pub enum InvalidThreshold { + #[error("Threshold does not meet the minimum absolute requirement")] + MinAbsRequirementFailed, + #[error("Threshold does not meet the minimum relative requirement")] + MinRelRequirementFailed, + #[error("Threshold must not exceed number of participants")] + MaxRequirementFailed, + #[error("Key event threshold must match the number of participants")] + DKGThresholdFailed, + } + #[automatically_derived] + impl ::core::fmt::Debug for InvalidThreshold { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + InvalidThreshold::MinAbsRequirementFailed => { + "MinAbsRequirementFailed" + } + InvalidThreshold::MinRelRequirementFailed => { + "MinRelRequirementFailed" + } + InvalidThreshold::MaxRequirementFailed => "MaxRequirementFailed", + InvalidThreshold::DKGThresholdFailed => "DKGThresholdFailed", + }, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for InvalidThreshold {} + #[automatically_derived] + impl ::core::cmp::PartialEq for InvalidThreshold { + #[inline] + fn eq(&self, other: &InvalidThreshold) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for InvalidThreshold { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + impl ::core::clone::Clone for InvalidThreshold { + #[inline] + fn clone(&self) -> InvalidThreshold { + match self { + InvalidThreshold::MinAbsRequirementFailed => { + InvalidThreshold::MinAbsRequirementFailed + } + InvalidThreshold::MinRelRequirementFailed => { + InvalidThreshold::MinRelRequirementFailed + } + InvalidThreshold::MaxRequirementFailed => { + InvalidThreshold::MaxRequirementFailed + } + InvalidThreshold::DKGThresholdFailed => { + InvalidThreshold::DKGThresholdFailed + } + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for InvalidThreshold {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for InvalidThreshold { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + InvalidThreshold::MinAbsRequirementFailed {} => { + __formatter + .write_str( + "Threshold does not meet the minimum absolute requirement", + ) + } + InvalidThreshold::MinRelRequirementFailed {} => { + __formatter + .write_str( + "Threshold does not meet the minimum relative requirement", + ) + } + InvalidThreshold::MaxRequirementFailed {} => { + __formatter + .write_str("Threshold must not exceed number of participants") + } + InvalidThreshold::DKGThresholdFailed {} => { + __formatter + .write_str( + "Key event threshold must match the number of participants", + ) + } + } + } + } + pub enum InvalidCandidateSet { + #[error( + "Set of proposed participants must contain at least `threshold` old participants." + )] + InsufficientOldParticipants, + #[error("Participant ids are not coherent.")] + IncoherentParticipantIds, + #[error("New Participant ids need to be unique and contiguous.")] + NewParticipantIdsNotContiguous, + #[error("New Participant ids need to not skip any unused participant ids.")] + NewParticipantIdsTooHigh, + #[error("Invalid participants TEE Remote Attestation Quote.")] + InvalidParticipantsTeeQuote, + } + #[automatically_derived] + impl ::core::fmt::Debug for InvalidCandidateSet { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + InvalidCandidateSet::InsufficientOldParticipants => { + "InsufficientOldParticipants" + } + InvalidCandidateSet::IncoherentParticipantIds => { + "IncoherentParticipantIds" + } + InvalidCandidateSet::NewParticipantIdsNotContiguous => { + "NewParticipantIdsNotContiguous" + } + InvalidCandidateSet::NewParticipantIdsTooHigh => { + "NewParticipantIdsTooHigh" + } + InvalidCandidateSet::InvalidParticipantsTeeQuote => { + "InvalidParticipantsTeeQuote" + } + }, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for InvalidCandidateSet {} + #[automatically_derived] + impl ::core::cmp::PartialEq for InvalidCandidateSet { + #[inline] + fn eq(&self, other: &InvalidCandidateSet) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for InvalidCandidateSet { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + impl ::core::clone::Clone for InvalidCandidateSet { + #[inline] + fn clone(&self) -> InvalidCandidateSet { + match self { + InvalidCandidateSet::InsufficientOldParticipants => { + InvalidCandidateSet::InsufficientOldParticipants + } + InvalidCandidateSet::IncoherentParticipantIds => { + InvalidCandidateSet::IncoherentParticipantIds + } + InvalidCandidateSet::NewParticipantIdsNotContiguous => { + InvalidCandidateSet::NewParticipantIdsNotContiguous + } + InvalidCandidateSet::NewParticipantIdsTooHigh => { + InvalidCandidateSet::NewParticipantIdsTooHigh + } + InvalidCandidateSet::InvalidParticipantsTeeQuote => { + InvalidCandidateSet::InvalidParticipantsTeeQuote + } + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for InvalidCandidateSet {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for InvalidCandidateSet { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + InvalidCandidateSet::InsufficientOldParticipants {} => { + __formatter + .write_str( + "Set of proposed participants must contain at least `threshold` old participants.", + ) + } + InvalidCandidateSet::IncoherentParticipantIds {} => { + __formatter.write_str("Participant ids are not coherent.") + } + InvalidCandidateSet::NewParticipantIdsNotContiguous {} => { + __formatter + .write_str( + "New Participant ids need to be unique and contiguous.", + ) + } + InvalidCandidateSet::NewParticipantIdsTooHigh {} => { + __formatter + .write_str( + "New Participant ids need to not skip any unused participant ids.", + ) + } + InvalidCandidateSet::InvalidParticipantsTeeQuote {} => { + __formatter + .write_str("Invalid participants TEE Remote Attestation Quote.") + } + } + } + } + pub enum ConversionError { + #[error("Data conversion error.")] + DataConversion, + } + #[automatically_derived] + impl ::core::fmt::Debug for ConversionError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "DataConversion") + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ConversionError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ConversionError { + #[inline] + fn eq(&self, other: &ConversionError) -> bool { + true + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ConversionError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + impl ::core::clone::Clone for ConversionError { + #[inline] + fn clone(&self) -> ConversionError { + ConversionError::DataConversion + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for ConversionError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for ConversionError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + ConversionError::DataConversion {} => { + __formatter.write_str("Data conversion error.") + } + } + } + } + pub enum DomainError { + #[error("No such domain.")] + NoSuchDomain, + #[error( + "Newly proposed domain IDs are not contiguous. Expected id: {expected_id}" + )] + NewDomainIdsNotContiguous { expected_id: DomainId }, + #[error("vote_add_domains must add at least one domain")] + AddDomainsMustAddAtLeastOneDomain, + #[error("Invalid list of domains provided")] + InvalidDomains, + #[error("Domains from keyset do not match the provided domains")] + DomainsMismatch, + } + #[automatically_derived] + impl ::core::fmt::Debug for DomainError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + DomainError::NoSuchDomain => { + ::core::fmt::Formatter::write_str(f, "NoSuchDomain") + } + DomainError::NewDomainIdsNotContiguous { expected_id: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "NewDomainIdsNotContiguous", + "expected_id", + &__self_0, + ) + } + DomainError::AddDomainsMustAddAtLeastOneDomain => { + ::core::fmt::Formatter::write_str( + f, + "AddDomainsMustAddAtLeastOneDomain", + ) + } + DomainError::InvalidDomains => { + ::core::fmt::Formatter::write_str(f, "InvalidDomains") + } + DomainError::DomainsMismatch => { + ::core::fmt::Formatter::write_str(f, "DomainsMismatch") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DomainError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DomainError { + #[inline] + fn eq(&self, other: &DomainError) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + ( + DomainError::NewDomainIdsNotContiguous { expected_id: __self_0 }, + DomainError::NewDomainIdsNotContiguous { expected_id: __arg1_0 }, + ) => __self_0 == __arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DomainError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for DomainError { + #[inline] + fn clone(&self) -> DomainError { + match self { + DomainError::NoSuchDomain => DomainError::NoSuchDomain, + DomainError::NewDomainIdsNotContiguous { expected_id: __self_0 } => { + DomainError::NewDomainIdsNotContiguous { + expected_id: ::core::clone::Clone::clone(__self_0), + } + } + DomainError::AddDomainsMustAddAtLeastOneDomain => { + DomainError::AddDomainsMustAddAtLeastOneDomain + } + DomainError::InvalidDomains => DomainError::InvalidDomains, + DomainError::DomainsMismatch => DomainError::DomainsMismatch, + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for DomainError {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for DomainError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use ::thiserror::__private17::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + DomainError::NoSuchDomain {} => __formatter.write_str("No such domain."), + DomainError::NewDomainIdsNotContiguous { expected_id } => { + match (expected_id.as_display(),) { + (__display_expected_id,) => { + __formatter + .write_fmt( + format_args!( + "Newly proposed domain IDs are not contiguous. Expected id: {0}", + __display_expected_id, + ), + ) + } + } + } + DomainError::AddDomainsMustAddAtLeastOneDomain {} => { + __formatter + .write_str("vote_add_domains must add at least one domain") + } + DomainError::InvalidDomains {} => { + __formatter.write_str("Invalid list of domains provided") + } + DomainError::DomainsMismatch {} => { + __formatter + .write_str( + "Domains from keyset do not match the provided domains", + ) + } + } + } + } + /// A list specifying general categories of MPC Contract errors. + #[non_exhaustive] + pub enum ErrorKind { + /// An error occurred while user is performing sign request. + #[error("{0}")] + Sign(#[from] SignError), + /// An error occurred while node is performing respond call. + #[error("{0}")] + Respond(#[from] RespondError), + /// An error occurred while user is performing public_key_* call. + #[error("{0}")] + PublicKey(#[from] PublicKeyError), + /// An error occurred while node is performing vote_* call. + #[error("{0}")] + Vote(#[from] VoteError), + #[error("{0}")] + InvalidParameters(#[from] InvalidParameters), + #[error("{0}")] + InvalidState(#[from] InvalidState), + #[error("{0}")] + ConversionError(#[from] ConversionError), + #[error("{0}")] + InvalidThreshold(#[from] InvalidThreshold), + #[error("{0}")] + InvalidCandidateSet(#[from] InvalidCandidateSet), + #[error("{0}")] + KeyEventError(#[from] KeyEventError), + #[error("{0}")] + DomainError(#[from] DomainError), + #[error("{0}")] + TeeError(#[from] TeeError), + #[error("{0}")] + NodeMigrationError(#[from] NodeMigrationError), + } + #[automatically_derived] + impl ::core::clone::Clone for ErrorKind { + #[inline] + fn clone(&self) -> ErrorKind { + match self { + ErrorKind::Sign(__self_0) => { + ErrorKind::Sign(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::Respond(__self_0) => { + ErrorKind::Respond(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::PublicKey(__self_0) => { + ErrorKind::PublicKey(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::Vote(__self_0) => { + ErrorKind::Vote(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::InvalidParameters(__self_0) => { + ErrorKind::InvalidParameters(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::InvalidState(__self_0) => { + ErrorKind::InvalidState(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::ConversionError(__self_0) => { + ErrorKind::ConversionError(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::InvalidThreshold(__self_0) => { + ErrorKind::InvalidThreshold(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::InvalidCandidateSet(__self_0) => { + ErrorKind::InvalidCandidateSet(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::KeyEventError(__self_0) => { + ErrorKind::KeyEventError(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::DomainError(__self_0) => { + ErrorKind::DomainError(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::TeeError(__self_0) => { + ErrorKind::TeeError(::core::clone::Clone::clone(__self_0)) + } + ErrorKind::NodeMigrationError(__self_0) => { + ErrorKind::NodeMigrationError(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ErrorKind { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ErrorKind::Sign(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Sign", + &__self_0, + ) + } + ErrorKind::Respond(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Respond", + &__self_0, + ) + } + ErrorKind::PublicKey(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "PublicKey", + &__self_0, + ) + } + ErrorKind::Vote(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Vote", + &__self_0, + ) + } + ErrorKind::InvalidParameters(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InvalidParameters", + &__self_0, + ) + } + ErrorKind::InvalidState(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InvalidState", + &__self_0, + ) + } + ErrorKind::ConversionError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ConversionError", + &__self_0, + ) + } + ErrorKind::InvalidThreshold(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InvalidThreshold", + &__self_0, + ) + } + ErrorKind::InvalidCandidateSet(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InvalidCandidateSet", + &__self_0, + ) + } + ErrorKind::KeyEventError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "KeyEventError", + &__self_0, + ) + } + ErrorKind::DomainError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DomainError", + &__self_0, + ) + } + ErrorKind::TeeError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "TeeError", + &__self_0, + ) + } + ErrorKind::NodeMigrationError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "NodeMigrationError", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ErrorKind { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ErrorKind {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ErrorKind { + #[inline] + fn eq(&self, other: &ErrorKind) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + (ErrorKind::Sign(__self_0), ErrorKind::Sign(__arg1_0)) => { + __self_0 == __arg1_0 + } + (ErrorKind::Respond(__self_0), ErrorKind::Respond(__arg1_0)) => { + __self_0 == __arg1_0 + } + (ErrorKind::PublicKey(__self_0), ErrorKind::PublicKey(__arg1_0)) => { + __self_0 == __arg1_0 + } + (ErrorKind::Vote(__self_0), ErrorKind::Vote(__arg1_0)) => { + __self_0 == __arg1_0 + } + ( + ErrorKind::InvalidParameters(__self_0), + ErrorKind::InvalidParameters(__arg1_0), + ) => __self_0 == __arg1_0, + ( + ErrorKind::InvalidState(__self_0), + ErrorKind::InvalidState(__arg1_0), + ) => __self_0 == __arg1_0, + ( + ErrorKind::ConversionError(__self_0), + ErrorKind::ConversionError(__arg1_0), + ) => __self_0 == __arg1_0, + ( + ErrorKind::InvalidThreshold(__self_0), + ErrorKind::InvalidThreshold(__arg1_0), + ) => __self_0 == __arg1_0, + ( + ErrorKind::InvalidCandidateSet(__self_0), + ErrorKind::InvalidCandidateSet(__arg1_0), + ) => __self_0 == __arg1_0, + ( + ErrorKind::KeyEventError(__self_0), + ErrorKind::KeyEventError(__arg1_0), + ) => __self_0 == __arg1_0, + ( + ErrorKind::DomainError(__self_0), + ErrorKind::DomainError(__arg1_0), + ) => __self_0 == __arg1_0, + (ErrorKind::TeeError(__self_0), ErrorKind::TeeError(__arg1_0)) => { + __self_0 == __arg1_0 + } + ( + ErrorKind::NodeMigrationError(__self_0), + ErrorKind::NodeMigrationError(__arg1_0), + ) => __self_0 == __arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for ErrorKind { + fn source( + &self, + ) -> ::core::option::Option<&(dyn ::thiserror::__private17::Error + 'static)> { + use ::thiserror::__private17::AsDynError as _; + #[allow(deprecated)] + match self { + ErrorKind::Sign { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::Respond { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::PublicKey { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::Vote { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::InvalidParameters { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::InvalidState { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::ConversionError { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::InvalidThreshold { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::InvalidCandidateSet { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::KeyEventError { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::DomainError { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::TeeError { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + ErrorKind::NodeMigrationError { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for ErrorKind { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use ::thiserror::__private17::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + ErrorKind::Sign(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::Respond(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::PublicKey(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::Vote(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::InvalidParameters(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::InvalidState(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::ConversionError(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::InvalidThreshold(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::InvalidCandidateSet(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::KeyEventError(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::DomainError(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::TeeError(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorKind::NodeMigrationError(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: SignError) -> Self { + ErrorKind::Sign { 0: source } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: RespondError) -> Self { + ErrorKind::Respond { 0: source } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: PublicKeyError) -> Self { + ErrorKind::PublicKey { 0: source } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: VoteError) -> Self { + ErrorKind::Vote { 0: source } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: InvalidParameters) -> Self { + ErrorKind::InvalidParameters { + 0: source, + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: InvalidState) -> Self { + ErrorKind::InvalidState { + 0: source, + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: ConversionError) -> Self { + ErrorKind::ConversionError { + 0: source, + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: InvalidThreshold) -> Self { + ErrorKind::InvalidThreshold { + 0: source, + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: InvalidCandidateSet) -> Self { + ErrorKind::InvalidCandidateSet { + 0: source, + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: KeyEventError) -> Self { + ErrorKind::KeyEventError { + 0: source, + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: DomainError) -> Self { + ErrorKind::DomainError { + 0: source, + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: TeeError) -> Self { + ErrorKind::TeeError { 0: source } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From for ErrorKind { + fn from(source: NodeMigrationError) -> Self { + ErrorKind::NodeMigrationError { + 0: source, + } + } + } + enum ErrorRepr { + #[error("{0}")] + Simple(ErrorKind), + #[error("{message}")] + Message { kind: ErrorKind, message: Cow<'static, str> }, + } + #[automatically_derived] + impl ::core::fmt::Debug for ErrorRepr { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ErrorRepr::Simple(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Simple", + &__self_0, + ) + } + ErrorRepr::Message { kind: __self_0, message: __self_1 } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Message", + "kind", + __self_0, + "message", + &__self_1, + ) + } + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for ErrorRepr {} + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for ErrorRepr { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use ::thiserror::__private17::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + ErrorRepr::Simple(_0) => { + match (_0.as_display(),) { + (__display0,) => { + __formatter.write_fmt(format_args!("{0}", __display0)) + } + } + } + ErrorRepr::Message { kind, message } => { + match (message.as_display(),) { + (__display_message,) => { + __formatter.write_fmt(format_args!("{0}", __display_message)) + } + } + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ErrorRepr {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ErrorRepr { + #[inline] + fn eq(&self, other: &ErrorRepr) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + (ErrorRepr::Simple(__self_0), ErrorRepr::Simple(__arg1_0)) => { + __self_0 == __arg1_0 + } + ( + ErrorRepr::Message { kind: __self_0, message: __self_1 }, + ErrorRepr::Message { kind: __arg1_0, message: __arg1_1 }, + ) => __self_0 == __arg1_0 && __self_1 == __arg1_1, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ErrorRepr { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + /// Error type that this contract will make use of for all the errors + /// returned from this library + pub struct Error { + repr: ErrorRepr, + } + #[automatically_derived] + impl ::core::fmt::Debug for Error { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Error", + "repr", + &&self.repr, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Error {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Error { + #[inline] + fn eq(&self, other: &Error) -> bool { + self.repr == other.repr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Error { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + impl near_sdk::FunctionError for Error { + fn panic(&self) -> ! { + crate::env::panic_str(&self.to_string()) + } + } +} +pub mod node_migrations { + use std::collections::BTreeMap; + use contract_interface::types::Ed25519PublicKey; + use near_account_id::AccountId; + use near_sdk::{near, store::IterableMap}; + use crate::{primitives::participants::ParticipantInfo, storage_keys::StorageKey}; + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct NodeMigrations { + backup_services_info: IterableMap, + ongoing_migrations: IterableMap, + } + #[automatically_derived] + impl ::core::fmt::Debug for NodeMigrations { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "NodeMigrations", + "backup_services_info", + &self.backup_services_info, + "ongoing_migrations", + &&self.ongoing_migrations, + ) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for NodeMigrations { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.backup_services_info, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.ongoing_migrations, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for NodeMigrations { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + backup_services_info: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + ongoing_migrations: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + impl Default for NodeMigrations { + fn default() -> Self { + Self { + backup_services_info: IterableMap::new(StorageKey::BackupServicesInfo), + ongoing_migrations: IterableMap::new(StorageKey::NodeMigrations), + } + } + } + impl NodeMigrations { + pub(crate) fn backup_services_info( + &self, + ) -> &IterableMap { + &self.backup_services_info + } + pub fn set_backup_service_info( + &mut self, + account_id: AccountId, + info: BackupServiceInfo, + ) { + self.backup_services_info.insert(account_id, info); + } + pub fn set_destination_node_info( + &mut self, + account_id: AccountId, + destination_node_info: DestinationNodeInfo, + ) { + self.ongoing_migrations.insert(account_id, destination_node_info); + } + pub fn remove_account_data(&mut self, account_id: &AccountId) { + self.backup_services_info.remove(account_id); + self.ongoing_migrations.remove(account_id); + } + pub fn remove_migration( + &mut self, + account_id: &AccountId, + ) -> Option { + self.ongoing_migrations.remove(account_id) + } + pub fn get_for_account( + &self, + account_id: &AccountId, + ) -> (AccountId, Option, Option) { + ( + account_id.clone(), + self.backup_services_info.get(account_id).cloned(), + self.ongoing_migrations.get(account_id).cloned(), + ) + } + pub fn get_all( + &self, + ) -> BTreeMap< + AccountId, + (Option, Option), + > { + let mut combined: BTreeMap< + AccountId, + (Option, Option), + > = BTreeMap::new(); + for (id, backup_serivce_info) in self.backup_services_info.iter() { + combined.insert(id.clone(), (Some(backup_serivce_info.clone()), None)); + } + for (id, destination_node_info) in self.ongoing_migrations.iter() { + combined + .entry(id.clone()) + .and_modify(|entry| entry.1 = Some(destination_node_info.clone())) + .or_insert((None, Some(destination_node_info.clone()))); + } + combined + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct BackupServiceInfo { + pub public_key: Ed25519PublicKey, + } + impl ::near_sdk::borsh::ser::BorshSerialize for BackupServiceInfo { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.public_key, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for BackupServiceInfo { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for BackupServiceInfo { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "BackupServiceInfo", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "public_key", + &self.public_key, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for BackupServiceInfo { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "public_key" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"public_key" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = BackupServiceInfo; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct BackupServiceInfo", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Ed25519PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct BackupServiceInfo with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(BackupServiceInfo { + public_key: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + Ed25519PublicKey, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "public_key", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Ed25519PublicKey, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("public_key")? + } + }; + _serde::__private228::Ok(BackupServiceInfo { + public_key: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["public_key"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "BackupServiceInfo", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for BackupServiceInfo { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "BackupServiceInfo", + "public_key", + &&self.public_key, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BackupServiceInfo {} + #[automatically_derived] + impl ::core::cmp::PartialEq for BackupServiceInfo { + #[inline] + fn eq(&self, other: &BackupServiceInfo) -> bool { + self.public_key == other.public_key + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for BackupServiceInfo { + #[inline] + fn partial_cmp( + &self, + other: &BackupServiceInfo, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.public_key, &other.public_key) + } + } + #[automatically_derived] + impl ::core::clone::Clone for BackupServiceInfo { + #[inline] + fn clone(&self) -> BackupServiceInfo { + BackupServiceInfo { + public_key: ::core::clone::Clone::clone(&self.public_key), + } + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct DestinationNodeInfo { + /// the public key used by the node to sign transactions to the contract + /// this key is different from the TLS key called `sign_pk` and stored in `ParticipantInfo`. + pub signer_account_pk: near_sdk::PublicKey, + pub destination_node_info: ParticipantInfo, + } + impl ::near_sdk::borsh::ser::BorshSerialize for DestinationNodeInfo { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.signer_account_pk, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.destination_node_info, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for DestinationNodeInfo { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + signer_account_pk: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + destination_node_info: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for DestinationNodeInfo { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "DestinationNodeInfo", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "signer_account_pk", + &self.signer_account_pk, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "destination_node_info", + &self.destination_node_info, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for DestinationNodeInfo { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "signer_account_pk" => { + _serde::__private228::Ok(__Field::__field0) + } + "destination_node_info" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"signer_account_pk" => { + _serde::__private228::Ok(__Field::__field0) + } + b"destination_node_info" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = DestinationNodeInfo; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct DestinationNodeInfo", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + near_sdk::PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct DestinationNodeInfo with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + ParticipantInfo, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct DestinationNodeInfo with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(DestinationNodeInfo { + signer_account_pk: __field0, + destination_node_info: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + near_sdk::PublicKey, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + ParticipantInfo, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "signer_account_pk", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + near_sdk::PublicKey, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "destination_node_info", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + ParticipantInfo, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "signer_account_pk", + )? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "destination_node_info", + )? + } + }; + _serde::__private228::Ok(DestinationNodeInfo { + signer_account_pk: __field0, + destination_node_info: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "signer_account_pk", + "destination_node_info", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "DestinationNodeInfo", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for DestinationNodeInfo { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "DestinationNodeInfo", + "signer_account_pk", + &self.signer_account_pk, + "destination_node_info", + &&self.destination_node_info, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for DestinationNodeInfo { + #[inline] + fn clone(&self) -> DestinationNodeInfo { + DestinationNodeInfo { + signer_account_pk: ::core::clone::Clone::clone(&self.signer_account_pk), + destination_node_info: ::core::clone::Clone::clone( + &self.destination_node_info, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DestinationNodeInfo {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DestinationNodeInfo { + #[inline] + fn eq(&self, other: &DestinationNodeInfo) -> bool { + self.signer_account_pk == other.signer_account_pk + && self.destination_node_info == other.destination_node_info + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for DestinationNodeInfo { + #[inline] + fn partial_cmp( + &self, + other: &DestinationNodeInfo, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.signer_account_pk, + &other.signer_account_pk, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.destination_node_info, + &other.destination_node_info, + ) + } + cmp => cmp, + } + } + } +} +pub mod primitives { + pub mod ckd { + use crate::{crypto_shared::kdf::derive_app_id, primitives::domain::DomainId}; + use contract_interface::types as dtos; + use near_account_id::AccountId; + use near_sdk::near; + #[serde(crate = ":: near_sdk :: serde")] + pub struct CKDRequestArgs { + pub derivation_path: String, + pub app_public_key: dtos::Bls12381G1PublicKey, + pub domain_id: DomainId, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for CKDRequestArgs { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "CKDRequestArgs", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "derivation_path", + &self.derivation_path, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "app_public_key", + &self.app_public_key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for CKDRequestArgs { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "derivation_path" => { + _serde::__private228::Ok(__Field::__field0) + } + "app_public_key" => { + _serde::__private228::Ok(__Field::__field1) + } + "domain_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"derivation_path" => { + _serde::__private228::Ok(__Field::__field0) + } + b"app_public_key" => { + _serde::__private228::Ok(__Field::__field1) + } + b"domain_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = CKDRequestArgs; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct CKDRequestArgs", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct CKDRequestArgs with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + dtos::Bls12381G1PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct CKDRequestArgs with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + DomainId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct CKDRequestArgs with 3 elements", + ), + ); + } + }; + _serde::__private228::Ok(CKDRequestArgs { + derivation_path: __field0, + app_public_key: __field1, + domain_id: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + dtos::Bls12381G1PublicKey, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "derivation_path", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "app_public_key", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + dtos::Bls12381G1PublicKey, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domain_id", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("derivation_path")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("app_public_key")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domain_id")? + } + }; + _serde::__private228::Ok(CKDRequestArgs { + derivation_path: __field0, + app_public_key: __field1, + domain_id: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "derivation_path", + "app_public_key", + "domain_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "CKDRequestArgs", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for CKDRequestArgs { + #[inline] + fn clone(&self) -> CKDRequestArgs { + CKDRequestArgs { + derivation_path: ::core::clone::Clone::clone(&self.derivation_path), + app_public_key: ::core::clone::Clone::clone(&self.app_public_key), + domain_id: ::core::clone::Clone::clone(&self.domain_id), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for CKDRequestArgs { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "CKDRequestArgs", + "derivation_path", + &self.derivation_path, + "app_public_key", + &self.app_public_key, + "domain_id", + &&self.domain_id, + ) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct CKDRequest { + /// The app ephemeral public key + pub app_public_key: dtos::Bls12381G1PublicKey, + pub app_id: dtos::CkdAppId, + pub domain_id: DomainId, + } + impl ::near_sdk::borsh::ser::BorshSerialize for CKDRequest { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.app_public_key, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.app_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for CKDRequest { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + app_public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + app_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for CKDRequest { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "CKDRequest", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "app_public_key", + &self.app_public_key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "app_id", + &self.app_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for CKDRequest { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "app_public_key" => { + _serde::__private228::Ok(__Field::__field0) + } + "app_id" => _serde::__private228::Ok(__Field::__field1), + "domain_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"app_public_key" => { + _serde::__private228::Ok(__Field::__field0) + } + b"app_id" => _serde::__private228::Ok(__Field::__field1), + b"domain_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = CKDRequest; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct CKDRequest", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + dtos::Bls12381G1PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct CKDRequest with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + dtos::CkdAppId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct CKDRequest with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + DomainId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct CKDRequest with 3 elements", + ), + ); + } + }; + _serde::__private228::Ok(CKDRequest { + app_public_key: __field0, + app_id: __field1, + domain_id: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + dtos::Bls12381G1PublicKey, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + dtos::CkdAppId, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "app_public_key", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + dtos::Bls12381G1PublicKey, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("app_id"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + dtos::CkdAppId, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domain_id", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("app_public_key")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("app_id")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domain_id")? + } + }; + _serde::__private228::Ok(CKDRequest { + app_public_key: __field0, + app_id: __field1, + domain_id: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "app_public_key", + "app_id", + "domain_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "CKDRequest", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for CKDRequest { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "CKDRequest", + "app_public_key", + &self.app_public_key, + "app_id", + &self.app_id, + "domain_id", + &&self.domain_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for CKDRequest { + #[inline] + fn clone(&self) -> CKDRequest { + CKDRequest { + app_public_key: ::core::clone::Clone::clone(&self.app_public_key), + app_id: ::core::clone::Clone::clone(&self.app_id), + domain_id: ::core::clone::Clone::clone(&self.domain_id), + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for CKDRequest { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::Ord for CKDRequest { + #[inline] + fn cmp(&self, other: &CKDRequest) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp( + &self.app_public_key, + &other.app_public_key, + ) { + ::core::cmp::Ordering::Equal => { + match ::core::cmp::Ord::cmp(&self.app_id, &other.app_id) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.domain_id, &other.domain_id) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for CKDRequest {} + #[automatically_derived] + impl ::core::cmp::PartialEq for CKDRequest { + #[inline] + fn eq(&self, other: &CKDRequest) -> bool { + self.app_public_key == other.app_public_key + && self.app_id == other.app_id && self.domain_id == other.domain_id + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for CKDRequest { + #[inline] + fn partial_cmp( + &self, + other: &CKDRequest, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.app_public_key, + &other.app_public_key, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + match ::core::cmp::PartialOrd::partial_cmp( + &self.app_id, + &other.app_id, + ) { + ::core::option::Option::Some( + ::core::cmp::Ordering::Equal, + ) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.domain_id, + &other.domain_id, + ) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + impl CKDRequest { + pub fn new( + app_public_key: dtos::Bls12381G1PublicKey, + domain_id: DomainId, + predecessor_id: &AccountId, + derivation_path: &str, + ) -> Self { + let app_id = derive_app_id(predecessor_id, derivation_path); + Self { + app_public_key, + app_id, + domain_id, + } + } + } + } + pub mod domain { + use super::key_state::AuthenticatedParticipantId; + use crate::errors::{DomainError, Error}; + use derive_more::{Deref, From}; + use near_sdk::{log, near}; + use std::collections::BTreeMap; + use std::fmt::Display; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Each domain corresponds to a specific root key in a specific signature scheme. There may be + /// multiple domains per signature scheme. The domain ID uniquely identifies a domain. + pub struct DomainId(pub u64); + #[automatically_derived] + impl ::core::fmt::Debug for DomainId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DomainId", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for DomainId { + #[inline] + fn clone(&self) -> DomainId { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for DomainId {} + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DomainId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DomainId { + #[inline] + fn eq(&self, other: &DomainId) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DomainId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::hash::Hash for DomainId { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for DomainId { + #[inline] + fn partial_cmp( + &self, + other: &DomainId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for DomainId { + #[inline] + fn cmp(&self, other: &DomainId) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[allow(unreachable_code)] + #[automatically_derived] + impl derive_more::core::convert::From<(u64)> for DomainId { + #[inline] + fn from(value: (u64)) -> Self { + DomainId(value) + } + } + #[allow(unreachable_code)] + #[automatically_derived] + impl derive_more::with_trait::Deref for DomainId { + type Target = u64; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for DomainId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for DomainId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for DomainId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "DomainId", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for DomainId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = DomainId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct DomainId", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: u64 = ::deserialize( + __e, + )?; + _serde::__private228::Ok(DomainId(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct DomainId with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(DomainId(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "DomainId", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl Default for DomainId { + fn default() -> Self { + Self::legacy_ecdsa_id() + } + } + impl DomainId { + /// Returns the DomainId of the single ECDSA key present in the contract before V2. + pub fn legacy_ecdsa_id() -> Self { + Self(0) + } + } + impl Display for DomainId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Uniquely identifies a specific request algorithm. + /// More protocols may be added in the future. When adding new protocols, both Borsh + /// *and* JSON serialization must be kept compatible. + pub enum SignatureScheme { + Secp256k1, + Ed25519, + Bls12381, + V2Secp256k1, + } + #[automatically_derived] + impl ::core::fmt::Debug for SignatureScheme { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + SignatureScheme::Secp256k1 => "Secp256k1", + SignatureScheme::Ed25519 => "Ed25519", + SignatureScheme::Bls12381 => "Bls12381", + SignatureScheme::V2Secp256k1 => "V2Secp256k1", + }, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for SignatureScheme { + #[inline] + fn clone(&self) -> SignatureScheme { + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for SignatureScheme {} + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SignatureScheme {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SignatureScheme { + #[inline] + fn eq(&self, other: &SignatureScheme) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for SignatureScheme { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + impl ::near_sdk::borsh::ser::BorshSerialize for SignatureScheme { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + let variant_idx: u8 = match self { + SignatureScheme::Secp256k1 => 0u8, + SignatureScheme::Ed25519 => 1u8, + SignatureScheme::Bls12381 => 2u8, + SignatureScheme::V2Secp256k1 => 3u8, + }; + writer.write_all(&variant_idx.to_le_bytes())?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for SignatureScheme { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + let tag = ::deserialize_reader( + reader, + )?; + ::deserialize_variant( + reader, + tag, + ) + } + } + impl ::near_sdk::borsh::de::EnumExt for SignatureScheme { + fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + variant_tag: u8, + ) -> ::core::result::Result { + let mut return_value = if variant_tag == 0u8 { + SignatureScheme::Secp256k1 + } else if variant_tag == 1u8 { + SignatureScheme::Ed25519 + } else if variant_tag == 2u8 { + SignatureScheme::Bls12381 + } else if variant_tag == 3u8 { + SignatureScheme::V2Secp256k1 + } else { + return Err( + ::near_sdk::borsh::io::Error::new( + ::near_sdk::borsh::io::ErrorKind::InvalidData, + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Unexpected variant tag: {0:?}", variant_tag), + ); + res + }), + ), + ) + }; + Ok(return_value) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SignatureScheme { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + SignatureScheme::Secp256k1 => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "SignatureScheme", + 0u32, + "Secp256k1", + ) + } + SignatureScheme::Ed25519 => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "SignatureScheme", + 1u32, + "Ed25519", + ) + } + SignatureScheme::Bls12381 => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "SignatureScheme", + 2u32, + "Bls12381", + ) + } + SignatureScheme::V2Secp256k1 => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "SignatureScheme", + 3u32, + "V2Secp256k1", + ) + } + } + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SignatureScheme { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + _ => { + _serde::__private228::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 4", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "Secp256k1" => _serde::__private228::Ok(__Field::__field0), + "Ed25519" => _serde::__private228::Ok(__Field::__field1), + "Bls12381" => _serde::__private228::Ok(__Field::__field2), + "V2Secp256k1" => _serde::__private228::Ok(__Field::__field3), + _ => { + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"Secp256k1" => _serde::__private228::Ok(__Field::__field0), + b"Ed25519" => _serde::__private228::Ok(__Field::__field1), + b"Bls12381" => _serde::__private228::Ok(__Field::__field2), + b"V2Secp256k1" => { + _serde::__private228::Ok(__Field::__field3) + } + _ => { + let __value = &_serde::__private228::from_utf8_lossy( + __value, + ); + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SignatureScheme; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "enum SignatureScheme", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private228::Ok(SignatureScheme::Secp256k1) + } + (__Field::__field1, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private228::Ok(SignatureScheme::Ed25519) + } + (__Field::__field2, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private228::Ok(SignatureScheme::Bls12381) + } + (__Field::__field3, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private228::Ok(SignatureScheme::V2Secp256k1) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "Secp256k1", + "Ed25519", + "Bls12381", + "V2Secp256k1", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "SignatureScheme", + VARIANTS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl Default for SignatureScheme { + fn default() -> Self { + Self::Secp256k1 + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Describes the configuration of a domain: the domain ID and the protocol it uses. + pub struct DomainConfig { + pub id: DomainId, + pub scheme: SignatureScheme, + } + #[automatically_derived] + impl ::core::fmt::Debug for DomainConfig { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "DomainConfig", + "id", + &self.id, + "scheme", + &&self.scheme, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for DomainConfig { + #[inline] + fn clone(&self) -> DomainConfig { + DomainConfig { + id: ::core::clone::Clone::clone(&self.id), + scheme: ::core::clone::Clone::clone(&self.scheme), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DomainConfig {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DomainConfig { + #[inline] + fn eq(&self, other: &DomainConfig) -> bool { + self.id == other.id && self.scheme == other.scheme + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DomainConfig { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for DomainConfig { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.scheme, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for DomainConfig { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + scheme: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for DomainConfig { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "DomainConfig", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "id", + &self.id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "scheme", + &self.scheme, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for DomainConfig { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "id" => _serde::__private228::Ok(__Field::__field0), + "scheme" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"id" => _serde::__private228::Ok(__Field::__field0), + b"scheme" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = DomainConfig; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct DomainConfig", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + DomainId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct DomainConfig with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + SignatureScheme, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct DomainConfig with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(DomainConfig { + id: __field0, + scheme: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + SignatureScheme, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("id"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("scheme"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + SignatureScheme, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("scheme")? + } + }; + _serde::__private228::Ok(DomainConfig { + id: __field0, + scheme: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["id", "scheme"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "DomainConfig", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// All the domains present in the contract, as well as the next domain ID which is kept to ensure + /// that we never reuse domain IDs. (Domains may be deleted in only one case: when we decided to + /// add domains but ultimately canceled that process.) + pub struct DomainRegistry { + domains: Vec, + next_domain_id: u64, + } + #[automatically_derived] + impl ::core::fmt::Debug for DomainRegistry { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "DomainRegistry", + "domains", + &self.domains, + "next_domain_id", + &&self.next_domain_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for DomainRegistry { + #[inline] + fn clone(&self) -> DomainRegistry { + DomainRegistry { + domains: ::core::clone::Clone::clone(&self.domains), + next_domain_id: ::core::clone::Clone::clone(&self.next_domain_id), + } + } + } + #[automatically_derived] + impl ::core::default::Default for DomainRegistry { + #[inline] + fn default() -> DomainRegistry { + DomainRegistry { + domains: ::core::default::Default::default(), + next_domain_id: ::core::default::Default::default(), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DomainRegistry {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DomainRegistry { + #[inline] + fn eq(&self, other: &DomainRegistry) -> bool { + self.domains == other.domains + && self.next_domain_id == other.next_domain_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DomainRegistry { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for DomainRegistry { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.next_domain_id, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for DomainRegistry { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + next_domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for DomainRegistry { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "DomainRegistry", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domains", + &self.domains, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "next_domain_id", + &self.next_domain_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for DomainRegistry { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "domains" => _serde::__private228::Ok(__Field::__field0), + "next_domain_id" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"domains" => _serde::__private228::Ok(__Field::__field0), + b"next_domain_id" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = DomainRegistry; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct DomainRegistry", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct DomainRegistry with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct DomainRegistry with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(DomainRegistry { + domains: __field0, + next_domain_id: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + Vec, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domains", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Vec, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "next_domain_id", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domains")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("next_domain_id")? + } + }; + _serde::__private228::Ok(DomainRegistry { + domains: __field0, + next_domain_id: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "domains", + "next_domain_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "DomainRegistry", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl DomainRegistry { + pub fn domains(&self) -> &[DomainConfig] { + &self.domains + } + /// Migration from legacy: creates a DomainRegistry with a single ecdsa key. + pub fn new_single_ecdsa_key_from_legacy() -> Self { + let mut registry = Self::default(); + registry.add_domain(SignatureScheme::Secp256k1); + registry + } + /// Add a single domain with the given protocol, returning the DomainId of the added + /// domain. + fn add_domain(&mut self, scheme: SignatureScheme) -> DomainId { + let domain = DomainConfig { + id: DomainId(self.next_domain_id), + scheme, + }; + self.next_domain_id += 1; + self.domains.push(domain.clone()); + domain.id + } + /// Processes the addition of the given domains, returning a new DomainRegistry. + /// This stringently requires that the domains specified have sorted and contiguous IDs starting + /// from next_domain_id, returning an error otherwise. + pub fn add_domains( + &self, + domains: Vec, + ) -> Result { + let mut new_registry = self.clone(); + for domain in domains { + let new_domain_id = new_registry.add_domain(domain.scheme); + if new_domain_id != domain.id { + return Err( + DomainError::NewDomainIdsNotContiguous { + expected_id: new_domain_id, + } + .into(), + ); + } + } + Ok(new_registry) + } + /// Retain a prefix of the given number of domains. This is used for cancelling key generation, + /// where we would delete whatever domains we failed to generate a key for. + pub fn retain_domains(&mut self, num_domains: usize) { + self.domains.truncate(num_domains); + } + /// Returns the given domain by the index, not the DomainId. + pub fn get_domain_by_index(&self, index: usize) -> Option<&DomainConfig> { + self.domains.get(index) + } + /// Returns the given domain by the DomainId. + pub fn get_domain_by_domain_id( + &self, + id: DomainId, + ) -> Option<&DomainConfig> { + self.domains.iter().find(|domain| domain.id == id) + } + /// Returns the most recently added domain for the given protocol, + /// or None if no such domain exists. + pub fn most_recent_domain_for_protocol( + &self, + scheme: SignatureScheme, + ) -> Option { + self.domains + .iter() + .rev() + .find(|domain| domain.scheme == scheme) + .map(|domain| domain.id) + } + /// Constructs a DomainRegistry from its raw fields, but performing basic + /// validation that the fields could've been produced by a valid + /// sequence of add_domains and retain_domains calls. This is used for + /// init_running and testing only. + pub fn from_raw_validated( + domains: Vec, + next_domain_id: u64, + ) -> Result { + let registry = Self { domains, next_domain_id }; + for (left, right) in registry + .domains + .iter() + .zip(registry.domains.iter().skip(1)) + { + if left.id.0 >= right.id.0 { + return Err(DomainError::InvalidDomains.into()); + } + } + if let Some(largest_domain_id) = registry + .domains + .last() + .map(|domain| domain.id.0) + { + if largest_domain_id >= registry.next_domain_id { + return Err(DomainError::InvalidDomains.into()); + } + } + Ok(registry) + } + pub fn next_domain_id(&self) -> u64 { + self.next_domain_id + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Tracks votes to add domains. Each participant can at any given time vote for a list of domains + /// to add. + pub struct AddDomainsVotes { + proposal_by_account: BTreeMap>, + } + #[automatically_derived] + impl ::core::fmt::Debug for AddDomainsVotes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "AddDomainsVotes", + "proposal_by_account", + &&self.proposal_by_account, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for AddDomainsVotes { + #[inline] + fn clone(&self) -> AddDomainsVotes { + AddDomainsVotes { + proposal_by_account: ::core::clone::Clone::clone( + &self.proposal_by_account, + ), + } + } + } + #[automatically_derived] + impl ::core::default::Default for AddDomainsVotes { + #[inline] + fn default() -> AddDomainsVotes { + AddDomainsVotes { + proposal_by_account: ::core::default::Default::default(), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AddDomainsVotes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AddDomainsVotes { + #[inline] + fn eq(&self, other: &AddDomainsVotes) -> bool { + self.proposal_by_account == other.proposal_by_account + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AddDomainsVotes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq< + BTreeMap>, + >; + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for AddDomainsVotes { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.proposal_by_account, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for AddDomainsVotes { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + proposal_by_account: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for AddDomainsVotes { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "AddDomainsVotes", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "proposal_by_account", + &self.proposal_by_account, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for AddDomainsVotes { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "proposal_by_account" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"proposal_by_account" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = AddDomainsVotes; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct AddDomainsVotes", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + BTreeMap>, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct AddDomainsVotes with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(AddDomainsVotes { + proposal_by_account: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + BTreeMap>, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "proposal_by_account", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + BTreeMap>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "proposal_by_account", + )? + } + }; + _serde::__private228::Ok(AddDomainsVotes { + proposal_by_account: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["proposal_by_account"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "AddDomainsVotes", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl AddDomainsVotes { + /// Votes for the proposal, returning the total number of voters so far who + /// have proposed the exact same domains to add. + /// If the participant had voted already, this replaces the existing vote. + pub fn vote( + &mut self, + proposal: Vec, + participant: &AuthenticatedParticipantId, + ) -> u64 { + if self + .proposal_by_account + .insert(participant.clone(), proposal.clone()) + .is_some() + { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("removed old vote for signer"), + ); + res + }) + .as_str(), + ); + } + let total = self + .proposal_by_account + .values() + .filter(|&prop| prop == &proposal) + .count() as u64; + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("total votes for proposal: {0}", total), + ); + res + }) + .as_str(), + ); + total + } + } + } + pub mod key_state { + use super::domain::DomainId; + use super::participants::{ParticipantId, Participants}; + use crate::crypto_shared::types::PublicKeyExtended; + use crate::errors::{DomainError, Error, InvalidState}; + use near_account_id::AccountId; + use near_sdk::{env, near}; + use std::fmt::Display; + use utilities::AccountIdExtV1; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// An EpochId uniquely identifies a ThresholdParameters (but not vice-versa). + /// Every time we change the ThresholdParameters (participants and threshold), + /// we increment EpochId. + /// Locally on each node, each keyshare is uniquely identified by the tuple + /// (EpochId, DomainId, AttemptId). + pub struct EpochId(u64); + #[automatically_derived] + impl ::core::fmt::Debug for EpochId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "EpochId", &&self.0) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for EpochId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for EpochId { + #[inline] + fn eq(&self, other: &EpochId) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for EpochId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for EpochId { + #[inline] + fn clone(&self) -> EpochId { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for EpochId {} + #[automatically_derived] + impl ::core::hash::Hash for EpochId { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for EpochId { + #[inline] + fn partial_cmp( + &self, + other: &EpochId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for EpochId { + #[inline] + fn cmp(&self, other: &EpochId) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for EpochId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for EpochId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for EpochId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "EpochId", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for EpochId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = EpochId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct EpochId", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: u64 = ::deserialize( + __e, + )?; + _serde::__private228::Ok(EpochId(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct EpochId with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(EpochId(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "EpochId", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl EpochId { + pub const fn next(&self) -> Self { + EpochId(self.0 + 1) + } + pub const fn new(epoch_id: u64) -> Self { + EpochId(epoch_id) + } + pub fn get(&self) -> u64 { + self.0 + } + } + impl Display for EpochId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct AttemptId(u64); + #[automatically_derived] + impl ::core::fmt::Debug for AttemptId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "AttemptId", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AttemptId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AttemptId { + #[inline] + fn eq(&self, other: &AttemptId) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AttemptId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for AttemptId { + #[inline] + fn clone(&self) -> AttemptId { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for AttemptId {} + #[automatically_derived] + impl ::core::hash::Hash for AttemptId { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for AttemptId { + #[inline] + fn partial_cmp( + &self, + other: &AttemptId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for AttemptId { + #[inline] + fn cmp(&self, other: &AttemptId) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for AttemptId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for AttemptId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for AttemptId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "AttemptId", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for AttemptId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = AttemptId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct AttemptId", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: u64 = ::deserialize( + __e, + )?; + _serde::__private228::Ok(AttemptId(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct AttemptId with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(AttemptId(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "AttemptId", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl AttemptId { + pub fn new() -> Self { + AttemptId(0) + } + pub fn next(&self) -> Self { + AttemptId(&self.0 + 1) + } + pub fn get(&self) -> u64 { + self.0 + } + pub fn legacy_attempt_id() -> Self { + AttemptId(0) + } + } + impl Default for AttemptId { + fn default() -> Self { + Self::new() + } + } + impl Display for AttemptId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// A unique identifier for a key event (generation or resharing): + /// `epoch_id`: identifies the ThresholdParameters that this key is intended to function in. + /// `domain_id`: the domain this key is intended for. + /// `attempt_id`: identifies a particular attempt for this key event, in case multiple attempts + /// yielded partially valid results. This is incremented for each attempt within the + /// same epoch and domain. + pub struct KeyEventId { + pub epoch_id: EpochId, + pub domain_id: DomainId, + pub attempt_id: AttemptId, + } + #[automatically_derived] + impl ::core::fmt::Debug for KeyEventId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "KeyEventId", + "epoch_id", + &self.epoch_id, + "domain_id", + &self.domain_id, + "attempt_id", + &&self.attempt_id, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for KeyEventId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for KeyEventId { + #[inline] + fn eq(&self, other: &KeyEventId) -> bool { + self.epoch_id == other.epoch_id && self.domain_id == other.domain_id + && self.attempt_id == other.attempt_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for KeyEventId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::marker::Copy for KeyEventId {} + #[automatically_derived] + impl ::core::clone::Clone for KeyEventId { + #[inline] + fn clone(&self) -> KeyEventId { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::hash::Hash for KeyEventId { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.epoch_id, state); + ::core::hash::Hash::hash(&self.domain_id, state); + ::core::hash::Hash::hash(&self.attempt_id, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for KeyEventId { + #[inline] + fn partial_cmp( + &self, + other: &KeyEventId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.epoch_id, + &other.epoch_id, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + match ::core::cmp::PartialOrd::partial_cmp( + &self.domain_id, + &other.domain_id, + ) { + ::core::option::Option::Some( + ::core::cmp::Ordering::Equal, + ) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.attempt_id, + &other.attempt_id, + ) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::Ord for KeyEventId { + #[inline] + fn cmp(&self, other: &KeyEventId) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.epoch_id, &other.epoch_id) { + ::core::cmp::Ordering::Equal => { + match ::core::cmp::Ord::cmp(&self.domain_id, &other.domain_id) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.attempt_id, &other.attempt_id) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for KeyEventId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.attempt_id, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for KeyEventId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + attempt_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for KeyEventId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "KeyEventId", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "epoch_id", + &self.epoch_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "attempt_id", + &self.attempt_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for KeyEventId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "epoch_id" => _serde::__private228::Ok(__Field::__field0), + "domain_id" => _serde::__private228::Ok(__Field::__field1), + "attempt_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"epoch_id" => _serde::__private228::Ok(__Field::__field0), + b"domain_id" => _serde::__private228::Ok(__Field::__field1), + b"attempt_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = KeyEventId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct KeyEventId", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + EpochId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct KeyEventId with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + DomainId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct KeyEventId with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + AttemptId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct KeyEventId with 3 elements", + ), + ); + } + }; + _serde::__private228::Ok(KeyEventId { + epoch_id: __field0, + domain_id: __field1, + attempt_id: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "epoch_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domain_id", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "attempt_id", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("epoch_id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domain_id")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("attempt_id")? + } + }; + _serde::__private228::Ok(KeyEventId { + epoch_id: __field0, + domain_id: __field1, + attempt_id: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "epoch_id", + "domain_id", + "attempt_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "KeyEventId", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl KeyEventId { + pub fn new( + epoch_id: EpochId, + domain_id: DomainId, + attempt_id: AttemptId, + ) -> Self { + KeyEventId { + epoch_id, + domain_id, + attempt_id, + } + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// The identification of a specific distributed key, based on which a node would know exactly what + /// keyshare it has corresponds to this distributed key. (A distributed key refers to a specific set + /// of keyshares that nodes have which can be pieced together to form the secret key.) + pub struct KeyForDomain { + /// Identifies the domain this key is intended for. + pub domain_id: DomainId, + /// Identifies the public key. Although technically redundant given that we have the AttemptId, + /// we keep it here in the contract so that it can be verified against and queried. + pub key: PublicKeyExtended, + /// The attempt ID that generated (initially or as a result of resharing) this distributed key. + /// Nodes may have made multiple attempts to generate the distributed key, and this uniquely + /// identifies which one should ultimately be used. + pub attempt: AttemptId, + } + #[automatically_derived] + impl ::core::fmt::Debug for KeyForDomain { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "KeyForDomain", + "domain_id", + &self.domain_id, + "key", + &self.key, + "attempt", + &&self.attempt, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for KeyForDomain {} + #[automatically_derived] + impl ::core::cmp::PartialEq for KeyForDomain { + #[inline] + fn eq(&self, other: &KeyForDomain) -> bool { + self.domain_id == other.domain_id && self.key == other.key + && self.attempt == other.attempt + } + } + #[automatically_derived] + impl ::core::cmp::Eq for KeyForDomain { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for KeyForDomain { + #[inline] + fn clone(&self) -> KeyForDomain { + KeyForDomain { + domain_id: ::core::clone::Clone::clone(&self.domain_id), + key: ::core::clone::Clone::clone(&self.key), + attempt: ::core::clone::Clone::clone(&self.attempt), + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for KeyForDomain { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.key, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.attempt, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for KeyForDomain { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + attempt: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for KeyForDomain { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "KeyForDomain", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key", + &self.key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "attempt", + &self.attempt, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for KeyForDomain { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "domain_id" => _serde::__private228::Ok(__Field::__field0), + "key" => _serde::__private228::Ok(__Field::__field1), + "attempt" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"domain_id" => _serde::__private228::Ok(__Field::__field0), + b"key" => _serde::__private228::Ok(__Field::__field1), + b"attempt" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = KeyForDomain; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct KeyForDomain", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + DomainId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct KeyForDomain with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + PublicKeyExtended, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct KeyForDomain with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + AttemptId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct KeyForDomain with 3 elements", + ), + ); + } + }; + _serde::__private228::Ok(KeyForDomain { + domain_id: __field0, + key: __field1, + attempt: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + PublicKeyExtended, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domain_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("key"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + PublicKeyExtended, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "attempt", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domain_id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("key")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("attempt")? + } + }; + _serde::__private228::Ok(KeyForDomain { + domain_id: __field0, + key: __field1, + attempt: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "domain_id", + "key", + "attempt", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "KeyForDomain", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Represents a key for every domain in a specific epoch. + pub struct Keyset { + pub epoch_id: EpochId, + pub domains: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for Keyset { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Keyset", + "epoch_id", + &self.epoch_id, + "domains", + &&self.domains, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Keyset {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Keyset { + #[inline] + fn eq(&self, other: &Keyset) -> bool { + self.epoch_id == other.epoch_id && self.domains == other.domains + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Keyset { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Keyset { + #[inline] + fn clone(&self) -> Keyset { + Keyset { + epoch_id: ::core::clone::Clone::clone(&self.epoch_id), + domains: ::core::clone::Clone::clone(&self.domains), + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for Keyset { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for Keyset { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Keyset { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Keyset", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "epoch_id", + &self.epoch_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domains", + &self.domains, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Keyset { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "epoch_id" => _serde::__private228::Ok(__Field::__field0), + "domains" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"epoch_id" => _serde::__private228::Ok(__Field::__field0), + b"domains" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Keyset; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct Keyset", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + EpochId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Keyset with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Keyset with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(Keyset { + epoch_id: __field0, + domains: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + Vec, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "epoch_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domains", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Vec, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("epoch_id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domains")? + } + }; + _serde::__private228::Ok(Keyset { + epoch_id: __field0, + domains: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["epoch_id", "domains"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Keyset", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl Keyset { + pub fn new(epoch_id: EpochId, domains: Vec) -> Self { + Keyset { epoch_id, domains } + } + pub fn public_key( + &self, + domain_id: DomainId, + ) -> Result { + Ok( + self + .domains + .iter() + .find(|k| k.domain_id == domain_id) + .ok_or(DomainError::NoSuchDomain)? + .key + .clone(), + ) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// This struct is supposed to contain the participant id associated to the account `env::signer_account_id()`, + /// but is only constructible given a set of participants that includes the signer, thus acting as + /// a type system-based enforcement mechanism (albeit a best-effort one) for authenticating the + /// signer. + pub struct AuthenticatedParticipantId(ParticipantId); + #[automatically_derived] + impl ::core::fmt::Debug for AuthenticatedParticipantId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "AuthenticatedParticipantId", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for AuthenticatedParticipantId { + #[inline] + fn clone(&self) -> AuthenticatedParticipantId { + AuthenticatedParticipantId(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AuthenticatedParticipantId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AuthenticatedParticipantId { + #[inline] + fn eq(&self, other: &AuthenticatedParticipantId) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AuthenticatedParticipantId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for AuthenticatedParticipantId { + #[inline] + fn partial_cmp( + &self, + other: &AuthenticatedParticipantId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for AuthenticatedParticipantId { + #[inline] + fn cmp(&self, other: &AuthenticatedParticipantId) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for AuthenticatedParticipantId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for AuthenticatedParticipantId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for AuthenticatedParticipantId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "AuthenticatedParticipantId", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for AuthenticatedParticipantId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + AuthenticatedParticipantId, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = AuthenticatedParticipantId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct AuthenticatedParticipantId", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: ParticipantId = ::deserialize( + __e, + )?; + _serde::__private228::Ok( + AuthenticatedParticipantId(__field0), + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + ParticipantId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct AuthenticatedParticipantId with 1 element", + ), + ); + } + }; + _serde::__private228::Ok( + AuthenticatedParticipantId(__field0), + ) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "AuthenticatedParticipantId", + __Visitor { + marker: _serde::__private228::PhantomData::< + AuthenticatedParticipantId, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl AuthenticatedParticipantId { + pub fn get(&self) -> ParticipantId { + self.0.clone() + } + pub fn new(participants: &Participants) -> Result { + let signer = env::signer_account_id().as_v2_account_id(); + participants + .participants() + .iter() + .find(|(a_id, _, _)| *a_id == signer) + .map(|(_, p_id, _)| AuthenticatedParticipantId(p_id.clone())) + .ok_or_else(|| InvalidState::NotParticipant.into()) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// This struct contains the account `env::signer_account_id()`, but is only constructible given a + /// set of participants that include the signer, thus acting as a typesystem-based enforcement + /// mechanism (albeit a best-effort one) for authenticating the signer. + pub struct AuthenticatedAccountId(AccountId); + #[automatically_derived] + impl ::core::fmt::Debug for AuthenticatedAccountId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "AuthenticatedAccountId", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for AuthenticatedAccountId { + #[inline] + fn clone(&self) -> AuthenticatedAccountId { + AuthenticatedAccountId(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AuthenticatedAccountId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AuthenticatedAccountId { + #[inline] + fn eq(&self, other: &AuthenticatedAccountId) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AuthenticatedAccountId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for AuthenticatedAccountId { + #[inline] + fn partial_cmp( + &self, + other: &AuthenticatedAccountId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for AuthenticatedAccountId { + #[inline] + fn cmp(&self, other: &AuthenticatedAccountId) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::hash::Hash for AuthenticatedAccountId { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for AuthenticatedAccountId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for AuthenticatedAccountId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for AuthenticatedAccountId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "AuthenticatedAccountId", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for AuthenticatedAccountId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + AuthenticatedAccountId, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = AuthenticatedAccountId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct AuthenticatedAccountId", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: AccountId = ::deserialize( + __e, + )?; + _serde::__private228::Ok(AuthenticatedAccountId(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + AccountId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct AuthenticatedAccountId with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(AuthenticatedAccountId(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "AuthenticatedAccountId", + __Visitor { + marker: _serde::__private228::PhantomData::< + AuthenticatedAccountId, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl AuthenticatedAccountId { + pub fn get(&self) -> &AccountId { + &self.0 + } + pub fn new(participants: &Participants) -> Result { + let signer = env::signer_account_id().as_v2_account_id(); + if participants.participants().iter().any(|(a_id, _, _)| *a_id == signer) + { + Ok(AuthenticatedAccountId(signer)) + } else { + Err(InvalidState::NotParticipant.into()) + } + } + } + } + pub mod participants { + use crate::errors::{Error, InvalidCandidateSet, InvalidParameters}; + use near_account_id::AccountId; + use near_sdk::{near, PublicKey}; + use std::{collections::BTreeSet, fmt::Display}; + pub mod hpke { + pub type PublicKey = [u8; 32]; + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct ParticipantInfo { + pub url: String, + /// The public key used for verifying messages. + pub sign_pk: PublicKey, + } + #[automatically_derived] + impl ::core::fmt::Debug for ParticipantInfo { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "ParticipantInfo", + "url", + &self.url, + "sign_pk", + &&self.sign_pk, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ParticipantInfo {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ParticipantInfo { + #[inline] + fn eq(&self, other: &ParticipantInfo) -> bool { + self.url == other.url && self.sign_pk == other.sign_pk + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ParticipantInfo { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for ParticipantInfo { + #[inline] + fn partial_cmp( + &self, + other: &ParticipantInfo, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp(&self.url, &other.url) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.sign_pk, + &other.sign_pk, + ) + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::Ord for ParticipantInfo { + #[inline] + fn cmp(&self, other: &ParticipantInfo) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.url, &other.url) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.sign_pk, &other.sign_pk) + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for ParticipantInfo { + #[inline] + fn clone(&self) -> ParticipantInfo { + ParticipantInfo { + url: ::core::clone::Clone::clone(&self.url), + sign_pk: ::core::clone::Clone::clone(&self.sign_pk), + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for ParticipantInfo { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.url, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.sign_pk, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for ParticipantInfo { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + url: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + sign_pk: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ParticipantInfo { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "ParticipantInfo", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "url", + &self.url, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "sign_pk", + &self.sign_pk, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ParticipantInfo { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "url" => _serde::__private228::Ok(__Field::__field0), + "sign_pk" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"url" => _serde::__private228::Ok(__Field::__field0), + b"sign_pk" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ParticipantInfo; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct ParticipantInfo", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ParticipantInfo with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct ParticipantInfo with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(ParticipantInfo { + url: __field0, + sign_pk: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("url"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "sign_pk", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("url")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("sign_pk")? + } + }; + _serde::__private228::Ok(ParticipantInfo { + url: __field0, + sign_pk: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["url", "sign_pk"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ParticipantInfo", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct ParticipantId(pub u32); + #[automatically_derived] + impl ::core::fmt::Debug for ParticipantId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ParticipantId", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ParticipantId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ParticipantId { + #[inline] + fn eq(&self, other: &ParticipantId) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ParticipantId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for ParticipantId { + #[inline] + fn partial_cmp( + &self, + other: &ParticipantId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for ParticipantId { + #[inline] + fn cmp(&self, other: &ParticipantId) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::clone::Clone for ParticipantId { + #[inline] + fn clone(&self) -> ParticipantId { + ParticipantId(::core::clone::Clone::clone(&self.0)) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for ParticipantId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for ParticipantId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ParticipantId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "ParticipantId", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ParticipantId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ParticipantId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct ParticipantId", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: u32 = ::deserialize( + __e, + )?; + _serde::__private228::Ok(ParticipantId(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct ParticipantId with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(ParticipantId(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "ParticipantId", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl ParticipantId { + pub fn get(&self) -> u32 { + self.0 + } + pub fn next(&self) -> Self { + ParticipantId(self.0 + 1) + } + } + impl Display for ParticipantId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct Participants { + next_id: ParticipantId, + participants: Vec<(AccountId, ParticipantId, ParticipantInfo)>, + } + #[automatically_derived] + impl ::core::fmt::Debug for Participants { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Participants", + "next_id", + &self.next_id, + "participants", + &&self.participants, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Participants {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Participants { + #[inline] + fn eq(&self, other: &Participants) -> bool { + self.next_id == other.next_id && self.participants == other.participants + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Participants { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq< + Vec<(AccountId, ParticipantId, ParticipantInfo)>, + >; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Participants { + #[inline] + fn partial_cmp( + &self, + other: &Participants, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.next_id, + &other.next_id, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.participants, + &other.participants, + ) + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Participants { + #[inline] + fn cmp(&self, other: &Participants) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.next_id, &other.next_id) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.participants, &other.participants) + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for Participants { + #[inline] + fn clone(&self) -> Participants { + Participants { + next_id: ::core::clone::Clone::clone(&self.next_id), + participants: ::core::clone::Clone::clone(&self.participants), + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for Participants { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.next_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.participants, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for Participants { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + next_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + participants: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Participants { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Participants", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "next_id", + &self.next_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "participants", + &self.participants, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Participants { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "next_id" => _serde::__private228::Ok(__Field::__field0), + "participants" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"next_id" => _serde::__private228::Ok(__Field::__field0), + b"participants" => { + _serde::__private228::Ok(__Field::__field1) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Participants; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct Participants", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + ParticipantId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Participants with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec<(AccountId, ParticipantId, ParticipantInfo)>, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Participants with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(Participants { + next_id: __field0, + participants: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + ParticipantId, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + Vec<(AccountId, ParticipantId, ParticipantInfo)>, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "next_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + ParticipantId, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "participants", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Vec<(AccountId, ParticipantId, ParticipantInfo)>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("next_id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("participants")? + } + }; + _serde::__private228::Ok(Participants { + next_id: __field0, + participants: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["next_id", "participants"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Participants", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl Default for Participants { + fn default() -> Self { + Self::new() + } + } + impl Participants { + pub fn new() -> Self { + Participants { + next_id: ParticipantId(0), + participants: Vec::new(), + } + } + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> usize { + self.participants.len() + } + pub fn insert_with_id( + &mut self, + account_id: AccountId, + info: ParticipantInfo, + id: ParticipantId, + ) -> Result<(), Error> { + if self + .participants + .iter() + .any(|(a_id, p_id, _)| *a_id == account_id || *p_id == id) + { + return Err(InvalidParameters::ParticipantAlreadyInSet.into()); + } + if id < self.next_id() { + return Err(InvalidParameters::ParticipantAlreadyUsed.into()); + } + self.participants.push((account_id.clone(), id.clone(), info)); + self.next_id.0 = id.0 + 1; + Ok(()) + } + pub fn insert( + &mut self, + account_id: AccountId, + info: ParticipantInfo, + ) -> Result<(), Error> { + self.insert_with_id(account_id, info, self.next_id.clone()) + } + pub fn participants( + &self, + ) -> &Vec<(AccountId, ParticipantId, ParticipantInfo)> { + &self.participants + } + pub fn next_id(&self) -> ParticipantId { + self.next_id.clone() + } + /// Validates that the fields are coherent: + /// - All participant IDs are unique. + /// - All account IDs are unique. + /// - The next_id is greater than all participant IDs. + pub fn validate(&self) -> Result<(), Error> { + let mut ids: BTreeSet = BTreeSet::new(); + let mut accounts: BTreeSet = BTreeSet::new(); + for (acc_id, pid, _) in &self.participants { + accounts.insert(acc_id.clone()); + ids.insert(pid.clone()); + if self.next_id.get() <= pid.get() { + return Err(InvalidCandidateSet::IncoherentParticipantIds.into()); + } + } + if ids.len() != self.len() { + return Err(InvalidCandidateSet::IncoherentParticipantIds.into()); + } + if accounts.len() != self.len() { + return Err(InvalidCandidateSet::IncoherentParticipantIds.into()); + } + Ok(()) + } + pub fn is_participant(&self, account_id: &AccountId) -> bool { + self.participants.iter().any(|(a_id, _, _)| a_id == account_id) + } + pub fn init( + next_id: ParticipantId, + participants: Vec<(AccountId, ParticipantId, ParticipantInfo)>, + ) -> Self { + Self { next_id, participants } + } + pub fn info(&self, account_id: &AccountId) -> Option<&ParticipantInfo> { + self.participants + .iter() + .find(|(a_id, _, _)| a_id == account_id) + .map(|(_, _, info)| info) + } + pub fn update_info( + &mut self, + account_id: AccountId, + new_info: ParticipantInfo, + ) -> Result<(), Error> { + for (participant_account_id, _, participant_info) in self + .participants + .iter_mut() + { + if *participant_account_id == account_id { + *participant_info = new_info.clone(); + return Ok(()); + } + } + Err(crate::errors::InvalidState::NotParticipant.into()) + } + } + } + pub mod signature { + use crate::crypto_shared; + use crate::errors::{Error, InvalidParameters}; + use crate::DomainId; + use crypto_shared::derive_tweak; + use near_account_id::AccountId; + use near_sdk::{near, CryptoHash}; + use std::fmt::Debug; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct Tweak([u8; 32]); + impl ::near_sdk::borsh::ser::BorshSerialize for Tweak { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for Tweak { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Tweak { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "Tweak", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Tweak { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Tweak; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct Tweak", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: [u8; 32] = <[u8; 32] as _serde::Deserialize>::deserialize( + __e, + )?; + _serde::__private228::Ok(Tweak(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + [u8; 32], + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct Tweak with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(Tweak(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "Tweak", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for Tweak { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Tweak", &&self.0) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Tweak { + #[inline] + fn clone(&self) -> Tweak { + Tweak(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Tweak { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Tweak { + #[inline] + fn cmp(&self, other: &Tweak) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Tweak {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Tweak { + #[inline] + fn eq(&self, other: &Tweak) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Tweak { + #[inline] + fn partial_cmp( + &self, + other: &Tweak, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + impl Tweak { + pub fn as_bytes(&self) -> [u8; 32] { + self.0 + } + pub fn new(bytes: [u8; 32]) -> Self { + Self(bytes) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// A signature payload; the right payload must be passed in for the curve. + /// The json encoding for this payload converts the bytes to hex string. + pub enum Payload { + Ecdsa(Bytes<32, 32>), + Eddsa(Bytes<32, 1232>), + } + impl ::near_sdk::borsh::ser::BorshSerialize for Payload { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + let variant_idx: u8 = match self { + Payload::Ecdsa(..) => 0u8, + Payload::Eddsa(..) => 1u8, + }; + writer.write_all(&variant_idx.to_le_bytes())?; + match self { + Payload::Ecdsa(id0) => { + ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; + } + Payload::Eddsa(id0) => { + ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; + } + } + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for Payload { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + let tag = ::deserialize_reader( + reader, + )?; + ::deserialize_variant( + reader, + tag, + ) + } + } + impl ::near_sdk::borsh::de::EnumExt for Payload { + fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + variant_tag: u8, + ) -> ::core::result::Result { + let mut return_value = if variant_tag == 0u8 { + Payload::Ecdsa( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ) + } else if variant_tag == 1u8 { + Payload::Eddsa( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ) + } else { + return Err( + ::near_sdk::borsh::io::Error::new( + ::near_sdk::borsh::io::ErrorKind::InvalidData, + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Unexpected variant tag: {0:?}", variant_tag), + ); + res + }), + ), + ) + }; + Ok(return_value) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Payload { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + Payload::Ecdsa(ref __field0) => { + _serde::Serializer::serialize_newtype_variant( + __serializer, + "Payload", + 0u32, + "Ecdsa", + __field0, + ) + } + Payload::Eddsa(ref __field0) => { + _serde::Serializer::serialize_newtype_variant( + __serializer, + "Payload", + 1u32, + "Eddsa", + __field0, + ) + } + } + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Payload { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => { + _serde::__private228::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "Ecdsa" => _serde::__private228::Ok(__Field::__field0), + "Eddsa" => _serde::__private228::Ok(__Field::__field1), + _ => { + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"Ecdsa" => _serde::__private228::Ok(__Field::__field0), + b"Eddsa" => _serde::__private228::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private228::from_utf8_lossy( + __value, + ); + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Payload; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "enum Payload", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::__private228::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes<32, 32>, + >(__variant), + Payload::Ecdsa, + ) + } + (__Field::__field1, __variant) => { + _serde::__private228::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes<32, 1232>, + >(__variant), + Payload::Eddsa, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &["Ecdsa", "Eddsa"]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "Payload", + VARIANTS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for Payload { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Payload::Ecdsa(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ecdsa", + &__self_0, + ) + } + Payload::Eddsa(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Eddsa", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for Payload { + #[inline] + fn clone(&self) -> Payload { + match self { + Payload::Ecdsa(__self_0) => { + Payload::Ecdsa(::core::clone::Clone::clone(__self_0)) + } + Payload::Eddsa(__self_0) => { + Payload::Eddsa(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Payload { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Payload { + #[inline] + fn cmp(&self, other: &Payload) -> ::core::cmp::Ordering { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) { + ::core::cmp::Ordering::Equal => { + match (self, other) { + (Payload::Ecdsa(__self_0), Payload::Ecdsa(__arg1_0)) => { + ::core::cmp::Ord::cmp(__self_0, __arg1_0) + } + (Payload::Eddsa(__self_0), Payload::Eddsa(__arg1_0)) => { + ::core::cmp::Ord::cmp(__self_0, __arg1_0) + } + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Payload {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Payload { + #[inline] + fn eq(&self, other: &Payload) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + (Payload::Ecdsa(__self_0), Payload::Ecdsa(__arg1_0)) => { + __self_0 == __arg1_0 + } + (Payload::Eddsa(__self_0), Payload::Eddsa(__arg1_0)) => { + __self_0 == __arg1_0 + } + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Payload { + #[inline] + fn partial_cmp( + &self, + other: &Payload, + ) -> ::core::option::Option<::core::cmp::Ordering> { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + match (self, other) { + (Payload::Ecdsa(__self_0), Payload::Ecdsa(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + (Payload::Eddsa(__self_0), Payload::Eddsa(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + _ => { + ::core::cmp::PartialOrd::partial_cmp( + &__self_discr, + &__arg1_discr, + ) + } + } + } + } + impl Payload { + pub fn from_legacy_ecdsa(bytes: [u8; 32]) -> Self { + Payload::Ecdsa(Bytes::new(bytes.to_vec()).unwrap()) + } + pub fn as_ecdsa(&self) -> Option<&[u8; 32]> { + match self { + Payload::Ecdsa(bytes) => Some(bytes.as_fixed_bytes()), + _ => None, + } + } + pub fn as_eddsa(&self) -> Option<&[u8]> { + match self { + Payload::Eddsa(bytes) => Some(bytes.as_bytes()), + _ => None, + } + } + } + #[borsh(crate = ":: near_sdk :: borsh")] + /// A byte array with a statically encoded minimum and maximum length. + /// The `new` function as well as json deserialization checks that the length is within bounds. + /// The borsh deserialization does not perform such checks, as the borsh serialization is only + /// used for internal contract storage. + pub struct Bytes(Vec); + impl< + const MIN_LEN: usize, + const MAX_LEN: usize, + > ::near_sdk::borsh::ser::BorshSerialize for Bytes { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl< + const MIN_LEN: usize, + const MAX_LEN: usize, + > ::near_sdk::borsh::de::BorshDeserialize for Bytes { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for Bytes { + #[inline] + fn clone(&self) -> Bytes { + Bytes(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for Bytes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::cmp::Ord + for Bytes { + #[inline] + fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl< + const MIN_LEN: usize, + const MAX_LEN: usize, + > ::core::marker::StructuralPartialEq for Bytes {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for Bytes { + #[inline] + fn eq(&self, other: &Bytes) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd + for Bytes { + #[inline] + fn partial_cmp( + &self, + other: &Bytes, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + impl Bytes { + pub fn new(bytes: Vec) -> Result { + if bytes.len() < MIN_LEN || bytes.len() > MAX_LEN { + return Err(InvalidParameters::MalformedPayload.into()); + } + Ok(Self(bytes)) + } + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + } + impl Bytes { + pub fn as_fixed_bytes(&self) -> &[u8; N] { + self.0.as_slice().try_into().unwrap() + } + } + impl Debug + for Bytes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("Bytes").field(&hex::encode(&self.0)).finish() + } + } + impl near_sdk::serde::Serialize + for Bytes { + fn serialize(&self, serializer: S) -> Result + where + S: near_sdk::serde::Serializer, + { + hex::encode(&self.0).serialize(serializer) + } + } + impl< + 'de, + const MIN_LEN: usize, + const MAX_LEN: usize, + > near_sdk::serde::Deserialize<'de> for Bytes { + fn deserialize(deserializer: D) -> Result + where + D: near_sdk::serde::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + let bytes = hex::decode(&s).map_err(near_sdk::serde::de::Error::custom)?; + Self::new(bytes).map_err(near_sdk::serde::de::Error::custom) + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// The index into calling the YieldResume feature of NEAR. This will allow to resume + /// a yield call after the contract has been called back via this index. + pub struct YieldIndex { + pub data_id: CryptoHash, + } + impl ::near_sdk::borsh::ser::BorshSerialize for YieldIndex { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.data_id, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for YieldIndex { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + data_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for YieldIndex { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "YieldIndex", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "data_id", + &self.data_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for YieldIndex { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "data_id" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"data_id" => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = YieldIndex; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct YieldIndex", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + CryptoHash, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct YieldIndex with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(YieldIndex { data_id: __field0 }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "data_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("data_id")? + } + }; + _serde::__private228::Ok(YieldIndex { data_id: __field0 }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["data_id"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "YieldIndex", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for YieldIndex { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "YieldIndex", + "data_id", + &&self.data_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for YieldIndex { + #[inline] + fn clone(&self) -> YieldIndex { + YieldIndex { + data_id: ::core::clone::Clone::clone(&self.data_id), + } + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct SignatureRequest { + pub tweak: Tweak, + pub payload: Payload, + pub domain_id: DomainId, + } + impl ::near_sdk::borsh::ser::BorshSerialize for SignatureRequest { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.tweak, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.payload, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for SignatureRequest { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + tweak: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + payload: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SignatureRequest { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SignatureRequest", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "tweak", + &self.tweak, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "payload", + &self.payload, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SignatureRequest { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "tweak" => _serde::__private228::Ok(__Field::__field0), + "payload" => _serde::__private228::Ok(__Field::__field1), + "domain_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"tweak" => _serde::__private228::Ok(__Field::__field0), + b"payload" => _serde::__private228::Ok(__Field::__field1), + b"domain_id" => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SignatureRequest; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct SignatureRequest", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Tweak, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SignatureRequest with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Payload, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct SignatureRequest with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + DomainId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct SignatureRequest with 3 elements", + ), + ); + } + }; + _serde::__private228::Ok(SignatureRequest { + tweak: __field0, + payload: __field1, + domain_id: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("tweak"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "payload", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domain_id", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("tweak")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("payload")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domain_id")? + } + }; + _serde::__private228::Ok(SignatureRequest { + tweak: __field0, + payload: __field1, + domain_id: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "tweak", + "payload", + "domain_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SignatureRequest", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + SignatureRequest, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for SignatureRequest { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "SignatureRequest", + "tweak", + &self.tweak, + "payload", + &self.payload, + "domain_id", + &&self.domain_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for SignatureRequest { + #[inline] + fn clone(&self) -> SignatureRequest { + SignatureRequest { + tweak: ::core::clone::Clone::clone(&self.tweak), + payload: ::core::clone::Clone::clone(&self.payload), + domain_id: ::core::clone::Clone::clone(&self.domain_id), + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for SignatureRequest { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::Ord for SignatureRequest { + #[inline] + fn cmp(&self, other: &SignatureRequest) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.tweak, &other.tweak) { + ::core::cmp::Ordering::Equal => { + match ::core::cmp::Ord::cmp(&self.payload, &other.payload) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.domain_id, &other.domain_id) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for SignatureRequest {} + #[automatically_derived] + impl ::core::cmp::PartialEq for SignatureRequest { + #[inline] + fn eq(&self, other: &SignatureRequest) -> bool { + self.tweak == other.tweak && self.payload == other.payload + && self.domain_id == other.domain_id + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for SignatureRequest { + #[inline] + fn partial_cmp( + &self, + other: &SignatureRequest, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp(&self.tweak, &other.tweak) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + match ::core::cmp::PartialOrd::partial_cmp( + &self.payload, + &other.payload, + ) { + ::core::option::Option::Some( + ::core::cmp::Ordering::Equal, + ) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.domain_id, + &other.domain_id, + ) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + impl SignatureRequest { + pub fn new( + domain: DomainId, + payload: Payload, + predecessor_id: &AccountId, + path: &str, + ) -> Self { + let tweak = derive_tweak(predecessor_id, path); + SignatureRequest { + domain_id: domain, + tweak, + payload, + } + } + } + #[serde(crate = ":: near_sdk :: serde")] + pub struct SignRequestArgs { + pub path: String, + pub payload_v2: Option, + #[serde(rename = "payload")] + pub deprecated_payload: Option<[u8; 32]>, + pub domain_id: Option, + #[serde(rename = "key_version")] + pub deprecated_key_version: Option, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for SignRequestArgs { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SignRequestArgs", + false as usize + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "path", + &self.path, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "payload_v2", + &self.payload_v2, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "payload", + &self.deprecated_payload, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key_version", + &self.deprecated_key_version, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SignRequestArgs { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + 4u64 => _serde::__private228::Ok(__Field::__field4), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "path" => _serde::__private228::Ok(__Field::__field0), + "payload_v2" => _serde::__private228::Ok(__Field::__field1), + "payload" => _serde::__private228::Ok(__Field::__field2), + "domain_id" => _serde::__private228::Ok(__Field::__field3), + "key_version" => _serde::__private228::Ok(__Field::__field4), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"path" => _serde::__private228::Ok(__Field::__field0), + b"payload_v2" => _serde::__private228::Ok(__Field::__field1), + b"payload" => _serde::__private228::Ok(__Field::__field2), + b"domain_id" => _serde::__private228::Ok(__Field::__field3), + b"key_version" => { + _serde::__private228::Ok(__Field::__field4) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SignRequestArgs; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct SignRequestArgs", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SignRequestArgs with 5 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct SignRequestArgs with 5 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + Option<[u8; 32]>, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct SignRequestArgs with 5 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct SignRequestArgs with 5 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct SignRequestArgs with 5 elements", + ), + ); + } + }; + _serde::__private228::Ok(SignRequestArgs { + path: __field0, + payload_v2: __field1, + deprecated_payload: __field2, + domain_id: __field3, + deprecated_key_version: __field4, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option< + Option<[u8; 32]>, + > = _serde::__private228::None; + let mut __field3: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + let mut __field4: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("path"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "payload_v2", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "payload", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option<[u8; 32]>, + >(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private228::Option::is_some(&__field3) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domain_id", + ), + ); + } + __field3 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private228::Option::is_some(&__field4) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "key_version", + ), + ); + } + __field4 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("path")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("payload_v2")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("payload")? + } + }; + let __field3 = match __field3 { + _serde::__private228::Some(__field3) => __field3, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domain_id")? + } + }; + let __field4 = match __field4 { + _serde::__private228::Some(__field4) => __field4, + _serde::__private228::None => { + _serde::__private228::de::missing_field("key_version")? + } + }; + _serde::__private228::Ok(SignRequestArgs { + path: __field0, + payload_v2: __field1, + deprecated_payload: __field2, + domain_id: __field3, + deprecated_key_version: __field4, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "path", + "payload_v2", + "payload", + "domain_id", + "key_version", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SignRequestArgs", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for SignRequestArgs { + #[inline] + fn clone(&self) -> SignRequestArgs { + SignRequestArgs { + path: ::core::clone::Clone::clone(&self.path), + payload_v2: ::core::clone::Clone::clone(&self.payload_v2), + deprecated_payload: ::core::clone::Clone::clone( + &self.deprecated_payload, + ), + domain_id: ::core::clone::Clone::clone(&self.domain_id), + deprecated_key_version: ::core::clone::Clone::clone( + &self.deprecated_key_version, + ), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for SignRequestArgs { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "SignRequestArgs", + "path", + &self.path, + "payload_v2", + &self.payload_v2, + "deprecated_payload", + &self.deprecated_payload, + "domain_id", + &self.domain_id, + "deprecated_key_version", + &&self.deprecated_key_version, + ) + } + } + #[automatically_derived] + impl ::core::default::Default for SignRequestArgs { + #[inline] + fn default() -> SignRequestArgs { + SignRequestArgs { + path: ::core::default::Default::default(), + payload_v2: ::core::default::Default::default(), + deprecated_payload: ::core::default::Default::default(), + domain_id: ::core::default::Default::default(), + deprecated_key_version: ::core::default::Default::default(), + } + } + } + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct SignRequest { + pub payload: Payload, + pub path: String, + pub domain_id: DomainId, + } + impl ::near_sdk::borsh::ser::BorshSerialize for SignRequest { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.payload, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.path, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for SignRequest { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + payload: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + path: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for SignRequest { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "SignRequest", + "payload", + &self.payload, + "path", + &self.path, + "domain_id", + &&self.domain_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for SignRequest { + #[inline] + fn clone(&self) -> SignRequest { + SignRequest { + payload: ::core::clone::Clone::clone(&self.payload), + path: ::core::clone::Clone::clone(&self.path), + domain_id: ::core::clone::Clone::clone(&self.domain_id), + } + } + } + impl TryFrom for SignRequest { + type Error = Error; + fn try_from(args: SignRequestArgs) -> Result { + let payload = match (args.payload_v2, args.deprecated_payload) { + (Some(payload), None) => payload, + (None, Some(payload)) => Payload::from_legacy_ecdsa(payload), + _ => return Err(InvalidParameters::MalformedPayload.into()), + }; + let domain_id = match (args.domain_id, args.deprecated_key_version) { + (Some(domain_id), None) => domain_id, + (None, Some(key_version)) => DomainId(key_version.into()), + _ => return Err(InvalidParameters::InvalidDomainId.into()), + }; + Ok(SignRequest { + payload, + path: args.path, + domain_id, + }) + } + } + #[borsh(crate = ":: near_sdk :: borsh")] + pub enum SignatureResult { + Ok(T), + Err(E), + } + impl ::near_sdk::borsh::ser::BorshSerialize for SignatureResult + where + T: ::near_sdk::borsh::ser::BorshSerialize, + E: ::near_sdk::borsh::ser::BorshSerialize, + { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + let variant_idx: u8 = match self { + SignatureResult::Ok(..) => 0u8, + SignatureResult::Err(..) => 1u8, + }; + writer.write_all(&variant_idx.to_le_bytes())?; + match self { + SignatureResult::Ok(id0) => { + ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; + } + SignatureResult::Err(id0) => { + ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; + } + } + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for SignatureResult + where + T: ::near_sdk::borsh::de::BorshDeserialize, + E: ::near_sdk::borsh::de::BorshDeserialize, + { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + let tag = ::deserialize_reader( + reader, + )?; + ::deserialize_variant( + reader, + tag, + ) + } + } + impl ::near_sdk::borsh::de::EnumExt for SignatureResult + where + T: ::near_sdk::borsh::de::BorshDeserialize, + E: ::near_sdk::borsh::de::BorshDeserialize, + { + fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + variant_tag: u8, + ) -> ::core::result::Result { + let mut return_value = if variant_tag == 0u8 { + SignatureResult::Ok( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ) + } else if variant_tag == 1u8 { + SignatureResult::Err( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ) + } else { + return Err( + ::near_sdk::borsh::io::Error::new( + ::near_sdk::borsh::io::ErrorKind::InvalidData, + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Unexpected variant tag: {0:?}", variant_tag), + ); + res + }), + ), + ) + }; + Ok(return_value) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for SignatureResult { + #[inline] + fn clone(&self) -> SignatureResult { + match self { + SignatureResult::Ok(__self_0) => { + SignatureResult::Ok(::core::clone::Clone::clone(__self_0)) + } + SignatureResult::Err(__self_0) => { + SignatureResult::Err(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug + for SignatureResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + SignatureResult::Ok(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ok", + &__self_0, + ) + } + SignatureResult::Err(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Err", + &__self_0, + ) + } + } + } + } + } + pub mod thresholds { + use super::participants::{ParticipantId, ParticipantInfo, Participants}; + use crate::errors::{Error, InvalidCandidateSet, InvalidThreshold}; + use near_account_id::AccountId; + use near_sdk::near; + use std::collections::BTreeMap; + /// Minimum absolute threshold required. + const MIN_THRESHOLD_ABSOLUTE: u64 = 2; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Stores the cryptographic threshold for a distributed key. + /// ``` + /// use mpc_contract::primitives::thresholds::Threshold; + /// let dt = Threshold::new(8); + /// assert!(dt.value() == 8); + /// ``` + pub struct Threshold(u64); + #[automatically_derived] + impl ::core::fmt::Debug for Threshold { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Threshold", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Threshold {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Threshold { + #[inline] + fn eq(&self, other: &Threshold) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Threshold { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Threshold { + #[inline] + fn partial_cmp( + &self, + other: &Threshold, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Threshold { + #[inline] + fn cmp(&self, other: &Threshold) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Threshold { + #[inline] + fn clone(&self) -> Threshold { + Threshold(::core::clone::Clone::clone(&self.0)) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for Threshold { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for Threshold { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok( + Self( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ), + ) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Threshold { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "Threshold", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Threshold { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Threshold; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct Threshold", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: u64 = ::deserialize( + __e, + )?; + _serde::__private228::Ok(Threshold(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct Threshold with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(Threshold(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "Threshold", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl Threshold { + pub fn new(val: u64) -> Self { + Threshold(val) + } + pub fn value(&self) -> u64 { + self.0 + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Stores information about the threshold key parameters: + /// - owners of key shares + /// - cryptographic threshold + pub struct ThresholdParameters { + participants: Participants, + threshold: Threshold, + } + #[automatically_derived] + impl ::core::fmt::Debug for ThresholdParameters { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "ThresholdParameters", + "participants", + &self.participants, + "threshold", + &&self.threshold, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ThresholdParameters {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ThresholdParameters { + #[inline] + fn eq(&self, other: &ThresholdParameters) -> bool { + self.participants == other.participants + && self.threshold == other.threshold + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ThresholdParameters { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for ThresholdParameters { + #[inline] + fn partial_cmp( + &self, + other: &ThresholdParameters, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.participants, + &other.participants, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.threshold, + &other.threshold, + ) + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::Ord for ThresholdParameters { + #[inline] + fn cmp(&self, other: &ThresholdParameters) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.participants, &other.participants) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.threshold, &other.threshold) + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for ThresholdParameters { + #[inline] + fn clone(&self) -> ThresholdParameters { + ThresholdParameters { + participants: ::core::clone::Clone::clone(&self.participants), + threshold: ::core::clone::Clone::clone(&self.threshold), + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for ThresholdParameters { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.participants, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.threshold, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for ThresholdParameters { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + participants: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + threshold: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ThresholdParameters { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "ThresholdParameters", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "participants", + &self.participants, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "threshold", + &self.threshold, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ThresholdParameters { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "participants" => { + _serde::__private228::Ok(__Field::__field0) + } + "threshold" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"participants" => { + _serde::__private228::Ok(__Field::__field0) + } + b"threshold" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ThresholdParameters; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct ThresholdParameters", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Participants, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ThresholdParameters with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Threshold, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct ThresholdParameters with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(ThresholdParameters { + participants: __field0, + threshold: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + Participants, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "participants", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Participants, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "threshold", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("participants")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("threshold")? + } + }; + _serde::__private228::Ok(ThresholdParameters { + participants: __field0, + threshold: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "participants", + "threshold", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ThresholdParameters", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + ThresholdParameters, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl ThresholdParameters { + /// Constructs Threshold parameters from `participants` and `threshold` if the + /// threshold meets the absolute and relative validation criteria. + pub fn new( + participants: Participants, + threshold: Threshold, + ) -> Result { + match Self::validate_threshold( + participants.len() as u64, + threshold.clone(), + ) { + Ok(_) => { + Ok(ThresholdParameters { + participants, + threshold, + }) + } + Err(err) => Err(err), + } + } + /// Ensures that the threshold `k` is sensible and meets the absolute and minimum requirements. + /// That is: + /// - threshold must be at least `MIN_THRESHOLD_ABSOLUTE` + /// - threshold can not exceed the number of shares `n_shares`. + /// - threshold must be at least 60% of the number of shares (rounded upwards). + pub fn validate_threshold(n_shares: u64, k: Threshold) -> Result<(), Error> { + if k.value() > n_shares { + return Err( + InvalidThreshold::MaxRequirementFailed + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("cannot exceed {0}, found {1:?}", n_shares, k), + ); + res + }), + ), + ); + } + if k.value() < MIN_THRESHOLD_ABSOLUTE { + return Err(InvalidThreshold::MinAbsRequirementFailed.into()); + } + let percentage_bound = (3 * n_shares).div_ceil(5); + if k.value() < percentage_bound { + return Err( + InvalidThreshold::MinRelRequirementFailed + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "require at least {0}, found {1:?}", + percentage_bound, + k, + ), + ); + res + }), + ), + ); + } + Ok(()) + } + pub fn validate(&self) -> Result<(), Error> { + Self::validate_threshold( + self.participants.len() as u64, + self.threshold(), + )?; + self.participants.validate() + } + /// Validates the incoming proposal against the current one, ensuring it's allowed based on the + /// current participants and threshold settings. Also verifies the TEE quote of the participant + /// who submitted the proposal. + pub fn validate_incoming_proposal( + &self, + proposal: &ThresholdParameters, + ) -> Result<(), Error> { + proposal.validate()?; + let mut old_by_id: BTreeMap = BTreeMap::new(); + let mut old_by_acc: BTreeMap< + AccountId, + (ParticipantId, ParticipantInfo), + > = BTreeMap::new(); + for (acc, id, info) in self.participants().participants() { + old_by_id.insert(id.clone(), acc.clone()); + old_by_acc.insert(acc.clone(), (id.clone(), info.clone())); + } + let new_participants = proposal.participants().participants(); + let mut new_min_id = u32::MAX; + let mut new_max_id = 0u32; + let mut n_old = 0u64; + for (new_account, new_id, new_info) in new_participants { + match old_by_acc.get(new_account) { + Some((old_id, old_info)) => { + if new_id != old_id { + return Err( + InvalidCandidateSet::IncoherentParticipantIds.into(), + ); + } + if *new_info != *old_info { + return Err( + InvalidCandidateSet::IncoherentParticipantIds.into(), + ); + } + n_old += 1; + } + None => { + if old_by_id.contains_key(new_id) { + return Err( + InvalidCandidateSet::IncoherentParticipantIds.into(), + ); + } + new_min_id = std::cmp::min(new_min_id, new_id.get()); + new_max_id = std::cmp::max(new_max_id, new_id.get()); + } + } + } + if n_old < self.threshold().value() { + return Err(InvalidCandidateSet::InsufficientOldParticipants.into()); + } + let n_new = proposal.participants().len() as u64 - n_old; + if n_new > 0 { + if n_new - 1 != (new_max_id - new_min_id) as u64 { + return Err( + InvalidCandidateSet::NewParticipantIdsNotContiguous.into(), + ); + } + if new_min_id != self.participants().next_id().get() { + return Err( + InvalidCandidateSet::NewParticipantIdsNotContiguous.into(), + ); + } + if new_max_id + 1 != proposal.participants().next_id().get() { + return Err(InvalidCandidateSet::NewParticipantIdsTooHigh.into()); + } + } + Ok(()) + } + pub fn threshold(&self) -> Threshold { + self.threshold.clone() + } + /// Returns the map of Participants. + pub fn participants(&self) -> &Participants { + &self.participants + } + /// For integration testing. + pub fn new_unvalidated( + participants: Participants, + threshold: Threshold, + ) -> Self { + ThresholdParameters { + participants, + threshold, + } + } + pub fn update_info( + &mut self, + account_id: AccountId, + new_info: ParticipantInfo, + ) -> Result<(), Error> { + self.participants.update_info(account_id, new_info) + } + } + } + pub mod votes { + use super::thresholds::ThresholdParameters; + use super::{key_state::AuthenticatedAccountId, participants::Participants}; + use near_sdk::{log, near}; + use std::collections::BTreeMap; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Tracks votes for ThresholdParameters (new participants and threshold). + /// Each current participant can maintain one vote. + pub struct ThresholdParametersVotes { + proposal_by_account: BTreeMap, + } + #[automatically_derived] + impl ::core::clone::Clone for ThresholdParametersVotes { + #[inline] + fn clone(&self) -> ThresholdParametersVotes { + ThresholdParametersVotes { + proposal_by_account: ::core::clone::Clone::clone( + &self.proposal_by_account, + ), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ThresholdParametersVotes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "ThresholdParametersVotes", + "proposal_by_account", + &&self.proposal_by_account, + ) + } + } + #[automatically_derived] + impl ::core::default::Default for ThresholdParametersVotes { + #[inline] + fn default() -> ThresholdParametersVotes { + ThresholdParametersVotes { + proposal_by_account: ::core::default::Default::default(), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ThresholdParametersVotes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ThresholdParametersVotes { + #[inline] + fn eq(&self, other: &ThresholdParametersVotes) -> bool { + self.proposal_by_account == other.proposal_by_account + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ThresholdParametersVotes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq< + BTreeMap, + >; + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for ThresholdParametersVotes { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.proposal_by_account, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for ThresholdParametersVotes { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + proposal_by_account: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ThresholdParametersVotes { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "ThresholdParametersVotes", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "proposal_by_account", + &self.proposal_by_account, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ThresholdParametersVotes { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "proposal_by_account" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"proposal_by_account" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + ThresholdParametersVotes, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ThresholdParametersVotes; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct ThresholdParametersVotes", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + BTreeMap, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ThresholdParametersVotes with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(ThresholdParametersVotes { + proposal_by_account: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + BTreeMap, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "proposal_by_account", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + BTreeMap, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "proposal_by_account", + )? + } + }; + _serde::__private228::Ok(ThresholdParametersVotes { + proposal_by_account: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["proposal_by_account"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ThresholdParametersVotes", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + ThresholdParametersVotes, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl ThresholdParametersVotes { + /// return the number of votes for `proposal` casted by members of `participants` + pub fn n_votes( + &self, + proposal: &ThresholdParameters, + participants: &Participants, + ) -> u64 { + self + .proposal_by_account + .iter() + .filter(|&(acc, prop)| { + participants + .participants() + .iter() + .any(|(acc_id, _, _)| acc.get() == acc_id) + && prop == proposal + }) + .count() as u64 + } + /// Registers a vote by `participant` for `proposal`. + /// Removes any existing votes by `participant`. + /// Returns the number of participants who have voted for the same proposal (including the new + /// vote). + pub fn vote( + &mut self, + proposal: &ThresholdParameters, + participant: AuthenticatedAccountId, + ) -> u64 { + if self + .proposal_by_account + .insert(participant, proposal.clone()) + .is_some() + { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("removed one vote for signer"), + ); + res + }) + .as_str(), + ); + } + self + .proposal_by_account + .values() + .filter(|&prop| prop == proposal) + .count() as u64 + } + } + } + pub(crate) mod time { + use std::time::Duration; + pub(crate) struct Timestamp { + duration_since_unix_epoch: Duration, + } + #[automatically_derived] + impl ::core::fmt::Debug for Timestamp { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Timestamp", + "duration_since_unix_epoch", + &&self.duration_since_unix_epoch, + ) + } + } + #[automatically_derived] + impl ::core::marker::Copy for Timestamp {} + #[automatically_derived] + impl ::core::clone::Clone for Timestamp { + #[inline] + fn clone(&self) -> Timestamp { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Timestamp {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Timestamp { + #[inline] + fn eq(&self, other: &Timestamp) -> bool { + self.duration_since_unix_epoch == other.duration_since_unix_epoch + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Timestamp { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Timestamp { + #[inline] + fn partial_cmp( + &self, + other: &Timestamp, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp( + &self.duration_since_unix_epoch, + &other.duration_since_unix_epoch, + ) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Timestamp { + #[inline] + fn cmp(&self, other: &Timestamp) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp( + &self.duration_since_unix_epoch, + &other.duration_since_unix_epoch, + ) + } + } + impl Timestamp { + pub(crate) fn now() -> Self { + let block_time_nano_seconds = near_sdk::env::block_timestamp(); + Self { + duration_since_unix_epoch: Duration::from_nanos( + block_time_nano_seconds, + ), + } + } + pub(crate) fn checked_add(self, duration: Duration) -> Option { + let current_time_stamp = self.duration_since_unix_epoch; + let new_time_stamp = current_time_stamp.checked_add(duration)?; + Some(Timestamp { + duration_since_unix_epoch: new_time_stamp, + }) + } + } + impl borsh::BorshSerialize for Timestamp { + fn serialize( + &self, + writer: &mut W, + ) -> std::io::Result<()> { + let duration_milliseconds: u64 = self + .duration_since_unix_epoch + .as_secs(); + let duration_milliseconds_bytes: [u8; 8] = duration_milliseconds + .to_be_bytes(); + writer.write_all(&duration_milliseconds_bytes) + } + } + impl borsh::BorshDeserialize for Timestamp { + fn deserialize_reader( + reader: &mut R, + ) -> std::io::Result { + let mut duration_milliseconds_bytes: [u8; 8] = [0; 8]; + reader.read_exact(&mut duration_milliseconds_bytes)?; + let duration_milliseconds = u64::from_be_bytes( + duration_milliseconds_bytes, + ); + let duration_since_unix_epoch = Duration::from_secs( + duration_milliseconds, + ); + Ok(Self { duration_since_unix_epoch }) + } + } + } +} +pub mod state { + pub mod initializing { + use super::key_event::KeyEvent; + use super::running::RunningContractState; + use crate::crypto_shared::types::PublicKeyExtended; + use crate::errors::{Error, InvalidParameters}; + use crate::primitives::domain::DomainRegistry; + use crate::primitives::key_state::{ + AuthenticatedParticipantId, EpochId, KeyEventId, KeyForDomain, Keyset, + }; + use near_account_id::AccountId; + use near_sdk::near; + use std::collections::BTreeSet; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// In this state, we generate a new key for each new domain. At any given point of time, we are + /// generating the key of a single domain. After that, we move on to the next domain, or if there + /// are no more domains, transition into the Running state. + /// + /// This state is reached by calling vote_add_domains from the Running state by a threshold number + /// of participants. + /// + /// While generating the key for a domain, the `generating_key` field internally handles multiple + /// attempts as needed, only finishing when an attempt has succeeded. + /// + /// Additionally, a threshold number of participants can vote to cancel this state; doing so will + /// revert back to the Running state but deleting the domains for which we have not yet successfully + /// generated a key. This can be useful if the current set of participants are no longer all online + /// and we wish to perform a resharing before adding domains again. + pub struct InitializingContractState { + /// All domains, including the already existing ones and the ones we're generating a new key for + pub domains: DomainRegistry, + /// The epoch ID; this is the same as the Epoch ID of the Running state we transitioned from. + pub epoch_id: EpochId, + /// The key for each domain we have already generated a key for; this is in the same order as + /// the domains in the DomainRegistry, except that it only has a prefix of the domains. + pub generated_keys: Vec, + /// The key generation state for the currently generating domain (the next domain after + /// `generated_keys`). + pub generating_key: KeyEvent, + /// Votes that have been cast to cancel the key generation. + pub cancel_votes: BTreeSet, + } + #[automatically_derived] + impl ::core::fmt::Debug for InitializingContractState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "InitializingContractState", + "domains", + &self.domains, + "epoch_id", + &self.epoch_id, + "generated_keys", + &self.generated_keys, + "generating_key", + &self.generating_key, + "cancel_votes", + &&self.cancel_votes, + ) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for InitializingContractState { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.generated_keys, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.generating_key, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.cancel_votes, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for InitializingContractState { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + generated_keys: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + generating_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + cancel_votes: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for InitializingContractState { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "InitializingContractState", + false as usize + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domains", + &self.domains, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "epoch_id", + &self.epoch_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "generated_keys", + &self.generated_keys, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "generating_key", + &self.generating_key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "cancel_votes", + &self.cancel_votes, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for InitializingContractState { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + 4u64 => _serde::__private228::Ok(__Field::__field4), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "domains" => _serde::__private228::Ok(__Field::__field0), + "epoch_id" => _serde::__private228::Ok(__Field::__field1), + "generated_keys" => { + _serde::__private228::Ok(__Field::__field2) + } + "generating_key" => { + _serde::__private228::Ok(__Field::__field3) + } + "cancel_votes" => { + _serde::__private228::Ok(__Field::__field4) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"domains" => _serde::__private228::Ok(__Field::__field0), + b"epoch_id" => _serde::__private228::Ok(__Field::__field1), + b"generated_keys" => { + _serde::__private228::Ok(__Field::__field2) + } + b"generating_key" => { + _serde::__private228::Ok(__Field::__field3) + } + b"cancel_votes" => { + _serde::__private228::Ok(__Field::__field4) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + InitializingContractState, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = InitializingContractState; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct InitializingContractState", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + DomainRegistry, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct InitializingContractState with 5 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + EpochId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct InitializingContractState with 5 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct InitializingContractState with 5 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + KeyEvent, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct InitializingContractState with 5 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + BTreeSet, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct InitializingContractState with 5 elements", + ), + ); + } + }; + _serde::__private228::Ok(InitializingContractState { + domains: __field0, + epoch_id: __field1, + generated_keys: __field2, + generating_key: __field3, + cancel_votes: __field4, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + DomainRegistry, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + let mut __field2: _serde::__private228::Option< + Vec, + > = _serde::__private228::None; + let mut __field3: _serde::__private228::Option = _serde::__private228::None; + let mut __field4: _serde::__private228::Option< + BTreeSet, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domains", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + DomainRegistry, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "epoch_id", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "generated_keys", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Vec, + >(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private228::Option::is_some(&__field3) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "generating_key", + ), + ); + } + __field3 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private228::Option::is_some(&__field4) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "cancel_votes", + ), + ); + } + __field4 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + BTreeSet, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domains")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("epoch_id")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("generated_keys")? + } + }; + let __field3 = match __field3 { + _serde::__private228::Some(__field3) => __field3, + _serde::__private228::None => { + _serde::__private228::de::missing_field("generating_key")? + } + }; + let __field4 = match __field4 { + _serde::__private228::Some(__field4) => __field4, + _serde::__private228::None => { + _serde::__private228::de::missing_field("cancel_votes")? + } + }; + _serde::__private228::Ok(InitializingContractState { + domains: __field0, + epoch_id: __field1, + generated_keys: __field2, + generating_key: __field3, + cancel_votes: __field4, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "domains", + "epoch_id", + "generated_keys", + "generating_key", + "cancel_votes", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "InitializingContractState", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + InitializingContractState, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl InitializingContractState { + /// Starts a new attempt to generate a key for the current domain. + /// Returns an Error if the signer is not the leader (the participant with the lowest ID). + pub fn start( + &mut self, + key_event_id: KeyEventId, + key_event_timeout_blocks: u64, + ) -> Result<(), Error> { + self.generating_key.start(key_event_id, key_event_timeout_blocks) + } + /// Casts a vote for `public_key` for the attempt identified by `key_event_id`. + /// Upon success (a return of Ok(...)), the effect of this method is one of the following: + /// - A vote has been collected but we don't have enough votes yet. + /// - This vote is for a public key that disagrees from an earlier voted public key, causing + /// the attempt to abort; another call to `start` is then necessary. + /// - Everyone has now voted for the same public key; the state transitions into generating a + /// key for the next domain. (This returns Ok(None) still). + /// - Same as the last case, except that all domains have a generated key now, and we return + /// Ok(Some(running state)) that the caller should now transition into. + /// + /// Fails in the following cases: + /// - There is no active key generation attempt (including if the attempt timed out). + /// - The key_event_id corresponds to a different domain, different epoch, or different attempt + /// from the current key generation attempt. + /// - The signer is not a participant. + pub fn vote_pk( + &mut self, + key_event_id: KeyEventId, + public_key: PublicKeyExtended, + ) -> Result, Error> { + if self.generating_key.vote_success(&key_event_id, public_key.clone())? { + self.generated_keys + .push(KeyForDomain { + domain_id: key_event_id.domain_id, + key: public_key.clone(), + attempt: key_event_id.attempt_id, + }); + if let Some(next_domain) = self + .domains + .get_domain_by_index(self.generated_keys.len()) + { + self.generating_key = KeyEvent::new( + self.epoch_id, + next_domain.clone(), + self.generating_key.proposed_parameters().clone(), + ); + } else { + return Ok( + Some( + RunningContractState::new( + self.domains.clone(), + Keyset::new(self.epoch_id, self.generated_keys.clone()), + self.generating_key.proposed_parameters().clone(), + ), + ), + ); + } + } + Ok(None) + } + /// Casts a vote to abort the current key generation attempt. + /// After aborting, another call to start() is necessary to start a new attempt. + /// Returns error if there is no active attempt, or if the signer is not a participant. + pub fn vote_abort(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { + self.generating_key.vote_abort(key_event_id) + } + /// Casts a vote to cancel key generation. Any keys that have already been generated + /// are kept and we transition into Running state; remaining domains are permanently deleted. + /// Deleted domain IDs are not reused again. + /// + /// The next_domain_id parameter is used to verify that this cancel vote is indeed for this + /// particular instance of key generation, not some older instance. + pub fn vote_cancel( + &mut self, + next_domain_id: u64, + ) -> Result, Error> { + if next_domain_id != self.domains.next_domain_id() { + return Err(InvalidParameters::NextDomainIdMismatch.into()); + } + let participant = AuthenticatedParticipantId::new( + self.generating_key.proposed_parameters().participants(), + )?; + let required_threshold = self + .generating_key + .proposed_parameters() + .threshold() + .value() as usize; + if self.cancel_votes.insert(participant) + && self.cancel_votes.len() >= required_threshold + { + let mut domains = self.domains.clone(); + domains.retain_domains(self.generated_keys.len()); + return Ok( + Some( + RunningContractState::new( + domains, + Keyset::new(self.epoch_id, self.generated_keys.clone()), + self.generating_key.proposed_parameters().clone(), + ), + ), + ); + } + Ok(None) + } + pub fn is_participant(&self, account_id: &AccountId) -> bool { + self.generating_key + .proposed_parameters() + .participants() + .is_participant(account_id) + } + } + } + pub mod key_event { + use crate::crypto_shared::types::PublicKeyExtended; + use crate::errors::Error; + use crate::errors::KeyEventError; + use crate::errors::VoteError; + use crate::primitives::domain::DomainConfig; + use crate::primitives::key_state::KeyEventId; + use crate::primitives::key_state::{AttemptId, EpochId}; + use crate::primitives::thresholds::ThresholdParameters; + use crate::state::AuthenticatedParticipantId; + use near_sdk::BlockHeight; + use near_sdk::{env, log, near}; + use std::collections::BTreeSet; + use utilities::AccountIdExtV1; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Maintains the state for the current key generation or resharing. + pub struct KeyEvent { + /// The epoch ID that we're generating or resharing keys for. + epoch_id: EpochId, + /// The domain that we're generating or resharing the key for. + domain: DomainConfig, + /// The participants and threshold that shall participate in the key event. + parameters: ThresholdParameters, + /// If exists, the current attempt to generate or reshare the key. + instance: Option, + /// The ID of the next attempt to generate or reshare the key. + next_attempt_id: AttemptId, + } + #[automatically_derived] + impl ::core::fmt::Debug for KeyEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "KeyEvent", + "epoch_id", + &self.epoch_id, + "domain", + &self.domain, + "parameters", + &self.parameters, + "instance", + &self.instance, + "next_attempt_id", + &&self.next_attempt_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for KeyEvent { + #[inline] + fn clone(&self) -> KeyEvent { + KeyEvent { + epoch_id: ::core::clone::Clone::clone(&self.epoch_id), + domain: ::core::clone::Clone::clone(&self.domain), + parameters: ::core::clone::Clone::clone(&self.parameters), + instance: ::core::clone::Clone::clone(&self.instance), + next_attempt_id: ::core::clone::Clone::clone(&self.next_attempt_id), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for KeyEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq for KeyEvent { + #[inline] + fn eq(&self, other: &KeyEvent) -> bool { + self.epoch_id == other.epoch_id && self.domain == other.domain + && self.parameters == other.parameters + && self.instance == other.instance + && self.next_attempt_id == other.next_attempt_id + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for KeyEvent { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.domain, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.parameters, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.instance, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.next_attempt_id, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for KeyEvent { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + domain: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + parameters: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + instance: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + next_attempt_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for KeyEvent { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "KeyEvent", + false as usize + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "epoch_id", + &self.epoch_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain", + &self.domain, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "parameters", + &self.parameters, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "instance", + &self.instance, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "next_attempt_id", + &self.next_attempt_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for KeyEvent { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + 4u64 => _serde::__private228::Ok(__Field::__field4), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "epoch_id" => _serde::__private228::Ok(__Field::__field0), + "domain" => _serde::__private228::Ok(__Field::__field1), + "parameters" => _serde::__private228::Ok(__Field::__field2), + "instance" => _serde::__private228::Ok(__Field::__field3), + "next_attempt_id" => { + _serde::__private228::Ok(__Field::__field4) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"epoch_id" => _serde::__private228::Ok(__Field::__field0), + b"domain" => _serde::__private228::Ok(__Field::__field1), + b"parameters" => _serde::__private228::Ok(__Field::__field2), + b"instance" => _serde::__private228::Ok(__Field::__field3), + b"next_attempt_id" => { + _serde::__private228::Ok(__Field::__field4) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = KeyEvent; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct KeyEvent", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + EpochId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct KeyEvent with 5 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + DomainConfig, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct KeyEvent with 5 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + ThresholdParameters, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct KeyEvent with 5 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct KeyEvent with 5 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + AttemptId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct KeyEvent with 5 elements", + ), + ); + } + }; + _serde::__private228::Ok(KeyEvent { + epoch_id: __field0, + domain: __field1, + parameters: __field2, + instance: __field3, + next_attempt_id: __field4, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + DomainConfig, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option< + ThresholdParameters, + > = _serde::__private228::None; + let mut __field3: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + let mut __field4: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "epoch_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("domain"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + DomainConfig, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "parameters", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + ThresholdParameters, + >(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private228::Option::is_some(&__field3) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "instance", + ), + ); + } + __field3 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private228::Option::is_some(&__field4) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "next_attempt_id", + ), + ); + } + __field4 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("epoch_id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domain")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("parameters")? + } + }; + let __field3 = match __field3 { + _serde::__private228::Some(__field3) => __field3, + _serde::__private228::None => { + _serde::__private228::de::missing_field("instance")? + } + }; + let __field4 = match __field4 { + _serde::__private228::Some(__field4) => __field4, + _serde::__private228::None => { + _serde::__private228::de::missing_field("next_attempt_id")? + } + }; + _serde::__private228::Ok(KeyEvent { + epoch_id: __field0, + domain: __field1, + parameters: __field2, + instance: __field3, + next_attempt_id: __field4, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "epoch_id", + "domain", + "parameters", + "instance", + "next_attempt_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "KeyEvent", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl KeyEvent { + pub fn new( + epoch_id: EpochId, + domain: DomainConfig, + proposed_parameters: ThresholdParameters, + ) -> Self { + KeyEvent { + epoch_id, + domain, + parameters: proposed_parameters, + instance: None, + next_attempt_id: AttemptId::new(), + } + } + /// Start a new key event instance as the leader, if one isn't already active. + /// The leader is always the participant with the lowest participant ID. + pub fn start( + &mut self, + key_event_id: KeyEventId, + timeout_blocks: u64, + ) -> Result<(), Error> { + self.cleanup_if_timed_out(); + if self.instance.is_some() { + return Err(KeyEventError::ActiveKeyEvent.into()); + } + let expected_key_event_id = KeyEventId::new( + self.epoch_id, + self.domain.id, + self.next_attempt_id, + ); + if key_event_id != expected_key_event_id { + return Err(KeyEventError::KeyEventIdMismatch.into()); + } + self.verify_leader()?; + self.instance = Some( + KeyEventInstance::new(self.next_attempt_id, timeout_blocks), + ); + self.next_attempt_id = self.next_attempt_id.next(); + Ok(()) + } + /// Ensures that the signer account matches the leader participant. + /// The leader is the one with the lowest participant ID. + pub fn verify_leader(&self) -> Result<(), Error> { + let signer_account_id = env::signer_account_id().as_v2_account_id(); + if self + .parameters + .participants() + .participants() + .iter() + .min_by_key(|(_, participant_id, _)| participant_id) + .unwrap() + .0 != signer_account_id + { + return Err(VoteError::VoterNotLeader.into()); + } + Ok(()) + } + pub fn epoch_id(&self) -> EpochId { + self.epoch_id + } + pub fn domain(&self) -> DomainConfig { + self.domain.clone() + } + pub fn proposed_parameters(&self) -> &ThresholdParameters { + &self.parameters + } + /// Casts a vote for `public_key` in `key_event_id`. + /// Fails if `signer` is not a candidate, if the candidate already voted or if there is no active key event. + /// If this vote disagrees with an earlier vote on the public key, aborts the current attempt. + /// Otherwise, returns true iff all participants have voted for the same public key. + pub fn vote_success( + &mut self, + key_event_id: &KeyEventId, + public_key: PublicKeyExtended, + ) -> Result { + let candidate = self.verify_vote(key_event_id)?; + match self + .instance + .as_mut() + .unwrap() + .vote_success(candidate, public_key)? + { + VoteSuccessResult::Voted(count) => { + if count == self.parameters.participants().len() { + Ok(true) + } else { + Ok(false) + } + } + VoteSuccessResult::PublicKeyDisagreement => { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Public key disagreement; aborting key event instance.", + ), + ); + res + }) + .as_str(), + ); + self.instance = None; + Ok(false) + } + } + } + /// Casts a vote to abort the current keygen instance. + /// A new instance needs to be started later to start a new keygen attempt. + pub fn vote_abort(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { + let candidate = self.verify_vote(&key_event_id)?; + if self.instance.as_ref().unwrap().completed.contains(&candidate) { + return Err(VoteError::VoteAlreadySubmitted.into()); + } + self.instance = None; + Ok(()) + } + /// Convenience function to internally remove the current instance if it timed out. + /// Whoever reads and parses the state must treat a timed out instance as equivalent to not + /// having an instance at all; thus this function performs no functional change. + fn cleanup_if_timed_out(&mut self) { + if let Some(instance) = self.instance.as_ref() { + if !instance.active() { + self.instance = None; + } + } + } + /// Verifies that the signer is authorized to cast a vote and that the key event ID corresponds + /// to the current generation attempt. + fn verify_vote( + &mut self, + key_event_id: &KeyEventId, + ) -> Result { + let candidate = AuthenticatedParticipantId::new( + self.parameters.participants(), + )?; + self.cleanup_if_timed_out(); + let Some(instance) = self.instance.as_ref() else { + return Err(KeyEventError::NoActiveKeyEvent.into()); + }; + if key_event_id.epoch_id != self.epoch_id + || key_event_id.domain_id != self.domain.id + || key_event_id.attempt_id != instance.attempt_id + { + return Err(KeyEventError::KeyEventIdMismatch.into()); + } + Ok(candidate) + } + /// Returns the KeyEventId that identifies the current key generation or resharing attempt. + /// It returns None if there is no active attempt (including if the attempt has timed out). + pub fn current_key_event_id(&self) -> Option { + let instance = self.instance.as_ref()?; + if instance.expires_on <= env::block_height() { + return None; + } + Some(KeyEventId::new(self.epoch_id, self.domain.id, instance.attempt_id)) + } + pub fn domain_id(&self) -> crate::primitives::domain::DomainId { + self.domain.id + } + /// Returns the current key event instance (or none) + pub fn instance(&self) -> &Option { + &self.instance + } + pub fn next_attempt_id(&self) -> AttemptId { + self.next_attempt_id + } + } + /// See KeyEventInstance::vote_success. + enum VoteSuccessResult { + /// Voted successfully, returning the number of votes so far. + Voted(usize), + /// Participants disagreed on the public key, consensus failed. + PublicKeyDisagreement, + } + #[automatically_derived] + impl ::core::fmt::Debug for VoteSuccessResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + VoteSuccessResult::Voted(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Voted", + &__self_0, + ) + } + VoteSuccessResult::PublicKeyDisagreement => { + ::core::fmt::Formatter::write_str(f, "PublicKeyDisagreement") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for VoteSuccessResult {} + #[automatically_derived] + impl ::core::cmp::PartialEq for VoteSuccessResult { + #[inline] + fn eq(&self, other: &VoteSuccessResult) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + ( + VoteSuccessResult::Voted(__self_0), + VoteSuccessResult::Voted(__arg1_0), + ) => __self_0 == __arg1_0, + _ => true, + } + } + } + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// State for a single attempt at generating or resharing a key. + pub struct KeyEventInstance { + attempt_id: AttemptId, + /// The block in which KeyEvent::start() was called. + started_in: BlockHeight, + /// The block that this attempt expires on. To clarify off-by-one behavior: if the contract were + /// called *on* or after this height, the attempt is considered no longer existent. + expires_on: BlockHeight, + /// The participants that voted that they successfully completed the keygen or resharing. + completed: BTreeSet, + /// The public key currently voted for. This is None iff no one has voted. + public_key: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for KeyEventInstance { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "KeyEventInstance", + "attempt_id", + &self.attempt_id, + "started_in", + &self.started_in, + "expires_on", + &self.expires_on, + "completed", + &self.completed, + "public_key", + &&self.public_key, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for KeyEventInstance { + #[inline] + fn clone(&self) -> KeyEventInstance { + KeyEventInstance { + attempt_id: ::core::clone::Clone::clone(&self.attempt_id), + started_in: ::core::clone::Clone::clone(&self.started_in), + expires_on: ::core::clone::Clone::clone(&self.expires_on), + completed: ::core::clone::Clone::clone(&self.completed), + public_key: ::core::clone::Clone::clone(&self.public_key), + } + } + } + #[automatically_derived] + impl ::core::default::Default for KeyEventInstance { + #[inline] + fn default() -> KeyEventInstance { + KeyEventInstance { + attempt_id: ::core::default::Default::default(), + started_in: ::core::default::Default::default(), + expires_on: ::core::default::Default::default(), + completed: ::core::default::Default::default(), + public_key: ::core::default::Default::default(), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for KeyEventInstance {} + #[automatically_derived] + impl ::core::cmp::PartialEq for KeyEventInstance { + #[inline] + fn eq(&self, other: &KeyEventInstance) -> bool { + self.attempt_id == other.attempt_id + && self.started_in == other.started_in + && self.expires_on == other.expires_on + && self.completed == other.completed + && self.public_key == other.public_key + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for KeyEventInstance { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.attempt_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.started_in, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.expires_on, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.completed, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.public_key, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for KeyEventInstance { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + attempt_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + started_in: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + expires_on: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + completed: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for KeyEventInstance { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "KeyEventInstance", + false as usize + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "attempt_id", + &self.attempt_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "started_in", + &self.started_in, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "expires_on", + &self.expires_on, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "completed", + &self.completed, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "public_key", + &self.public_key, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for KeyEventInstance { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + 4u64 => _serde::__private228::Ok(__Field::__field4), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "attempt_id" => _serde::__private228::Ok(__Field::__field0), + "started_in" => _serde::__private228::Ok(__Field::__field1), + "expires_on" => _serde::__private228::Ok(__Field::__field2), + "completed" => _serde::__private228::Ok(__Field::__field3), + "public_key" => _serde::__private228::Ok(__Field::__field4), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"attempt_id" => _serde::__private228::Ok(__Field::__field0), + b"started_in" => _serde::__private228::Ok(__Field::__field1), + b"expires_on" => _serde::__private228::Ok(__Field::__field2), + b"completed" => _serde::__private228::Ok(__Field::__field3), + b"public_key" => _serde::__private228::Ok(__Field::__field4), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = KeyEventInstance; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct KeyEventInstance", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + AttemptId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct KeyEventInstance with 5 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + BlockHeight, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct KeyEventInstance with 5 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + BlockHeight, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct KeyEventInstance with 5 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + BTreeSet, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct KeyEventInstance with 5 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct KeyEventInstance with 5 elements", + ), + ); + } + }; + _serde::__private228::Ok(KeyEventInstance { + attempt_id: __field0, + started_in: __field1, + expires_on: __field2, + completed: __field3, + public_key: __field4, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + BlockHeight, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option< + BlockHeight, + > = _serde::__private228::None; + let mut __field3: _serde::__private228::Option< + BTreeSet, + > = _serde::__private228::None; + let mut __field4: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "attempt_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "started_in", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + BlockHeight, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "expires_on", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + BlockHeight, + >(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private228::Option::is_some(&__field3) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "completed", + ), + ); + } + __field3 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + BTreeSet, + >(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private228::Option::is_some(&__field4) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "public_key", + ), + ); + } + __field4 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("attempt_id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("started_in")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("expires_on")? + } + }; + let __field3 = match __field3 { + _serde::__private228::Some(__field3) => __field3, + _serde::__private228::None => { + _serde::__private228::de::missing_field("completed")? + } + }; + let __field4 = match __field4 { + _serde::__private228::Some(__field4) => __field4, + _serde::__private228::None => { + _serde::__private228::de::missing_field("public_key")? + } + }; + _serde::__private228::Ok(KeyEventInstance { + attempt_id: __field0, + started_in: __field1, + expires_on: __field2, + completed: __field3, + public_key: __field4, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "attempt_id", + "started_in", + "expires_on", + "completed", + "public_key", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "KeyEventInstance", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + KeyEventInstance, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl KeyEventInstance { + pub fn new(attempt_id: AttemptId, timeout_blocks: u64) -> Self { + KeyEventInstance { + attempt_id, + started_in: env::block_height(), + expires_on: env::block_height() + 1 + timeout_blocks, + completed: BTreeSet::new(), + public_key: None, + } + } + pub fn completed(&self) -> &BTreeSet { + &self.completed + } + pub fn active(&self) -> bool { + env::block_height() < self.expires_on + } + pub fn attempt_id(&self) -> AttemptId { + self.attempt_id + } + pub fn expires_on(&self) -> u64 { + self.expires_on + } + /// Commits the vote of `candidate` to `public_key`, returning either Voted with the number of + /// votes already cast, or PublicKeyDisagreement if this vote conflicts with an earlier vote's + /// public key. + /// Fails if the candidate already submitted a vote. + fn vote_success( + &mut self, + candidate: AuthenticatedParticipantId, + public_key: PublicKeyExtended, + ) -> Result { + if let Some(existing_public_key) = &self.public_key { + if existing_public_key != &public_key { + return Ok(VoteSuccessResult::PublicKeyDisagreement); + } + } else { + self.public_key = Some(public_key); + } + if self.completed.contains(&candidate) { + return Err(VoteError::VoteAlreadySubmitted.into()); + } + self.completed.insert(candidate.clone()); + Ok(VoteSuccessResult::Voted(self.completed.len())) + } + } + } + pub mod resharing { + use std::collections::HashSet; + use super::key_event::KeyEvent; + use super::running::RunningContractState; + use crate::errors::{Error, InvalidParameters}; + use crate::primitives::key_state::{ + AuthenticatedAccountId, EpochId, KeyEventId, KeyForDomain, Keyset, + }; + use crate::primitives::thresholds::ThresholdParameters; + use near_account_id::AccountId; + use near_sdk::near; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// In this state, we reshare the key of every domain onto a new set of participants and threshold. + /// Similar to key generation, we reshare the key of one domain at a time; when we finish resharing + /// for one domain, we move on to the next or transition to the Running state. + /// + /// This state is reached by calling vote_new_parameters from the Running state. + /// + /// This state keeps the previous running state because: + /// - The previous running state's ThresholdParameters are needed in order to facilitate the + /// possible re-proposal of a new ThresholdParameters, in case the currently proposed set of + /// participants are no longer all online. For tracking the votes we also use the same + /// tracking structure in the running state. + /// - The previous running state's keys are needed to copy the public keys. + /// - We use the previous running state's DomainRegistry. + pub struct ResharingContractState { + pub previous_running_state: RunningContractState, + pub reshared_keys: Vec, + pub resharing_key: KeyEvent, + pub cancellation_requests: HashSet, + } + #[automatically_derived] + impl ::core::fmt::Debug for ResharingContractState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "ResharingContractState", + "previous_running_state", + &self.previous_running_state, + "reshared_keys", + &self.reshared_keys, + "resharing_key", + &self.resharing_key, + "cancellation_requests", + &&self.cancellation_requests, + ) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for ResharingContractState { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.previous_running_state, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.reshared_keys, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.resharing_key, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.cancellation_requests, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for ResharingContractState { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + previous_running_state: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + reshared_keys: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + resharing_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + cancellation_requests: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ResharingContractState { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "ResharingContractState", + false as usize + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "previous_running_state", + &self.previous_running_state, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "reshared_keys", + &self.reshared_keys, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "resharing_key", + &self.resharing_key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "cancellation_requests", + &self.cancellation_requests, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ResharingContractState { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "previous_running_state" => { + _serde::__private228::Ok(__Field::__field0) + } + "reshared_keys" => { + _serde::__private228::Ok(__Field::__field1) + } + "resharing_key" => { + _serde::__private228::Ok(__Field::__field2) + } + "cancellation_requests" => { + _serde::__private228::Ok(__Field::__field3) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"previous_running_state" => { + _serde::__private228::Ok(__Field::__field0) + } + b"reshared_keys" => { + _serde::__private228::Ok(__Field::__field1) + } + b"resharing_key" => { + _serde::__private228::Ok(__Field::__field2) + } + b"cancellation_requests" => { + _serde::__private228::Ok(__Field::__field3) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData< + ResharingContractState, + >, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ResharingContractState; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct ResharingContractState", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + RunningContractState, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ResharingContractState with 4 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct ResharingContractState with 4 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + KeyEvent, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct ResharingContractState with 4 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + HashSet, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct ResharingContractState with 4 elements", + ), + ); + } + }; + _serde::__private228::Ok(ResharingContractState { + previous_running_state: __field0, + reshared_keys: __field1, + resharing_key: __field2, + cancellation_requests: __field3, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + RunningContractState, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + Vec, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option = _serde::__private228::None; + let mut __field3: _serde::__private228::Option< + HashSet, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "previous_running_state", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + RunningContractState, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "reshared_keys", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Vec, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "resharing_key", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private228::Option::is_some(&__field3) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "cancellation_requests", + ), + ); + } + __field3 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + HashSet, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "previous_running_state", + )? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("reshared_keys")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("resharing_key")? + } + }; + let __field3 = match __field3 { + _serde::__private228::Some(__field3) => __field3, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "cancellation_requests", + )? + } + }; + _serde::__private228::Ok(ResharingContractState { + previous_running_state: __field0, + reshared_keys: __field1, + resharing_key: __field2, + cancellation_requests: __field3, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "previous_running_state", + "reshared_keys", + "resharing_key", + "cancellation_requests", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ResharingContractState", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + ResharingContractState, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl ResharingContractState { + pub fn previous_keyset(&self) -> &Keyset { + &self.previous_running_state.keyset + } + /// Returns the epoch ID that we would transition into if resharing were completed successfully. + /// This would increment if we end up voting for a re-proposal. + pub fn prospective_epoch_id(&self) -> EpochId { + self.resharing_key.epoch_id() + } + /// Casts a vote for a re-proposal. Requires the signer to be a participant of the prospective epoch. + /// Returns a new [`ResharingContractState`] if all participants of the re-proposal voted for the re-proposal. + /// Note that transitioning to a new state implicitly requires `threshold` number of votes from participants of the + /// previous running state. + pub fn vote_new_parameters( + &mut self, + prospective_epoch_id: EpochId, + proposal: &ThresholdParameters, + ) -> Result, Error> { + let expected_prospective_epoch_id = self.prospective_epoch_id().next(); + if prospective_epoch_id != expected_prospective_epoch_id { + return Err( + InvalidParameters::EpochMismatch { + expected: expected_prospective_epoch_id, + provided: prospective_epoch_id, + } + .into(), + ); + } + if self.previous_running_state.process_new_parameters_proposal(proposal)? + { + return Ok( + Some(ResharingContractState { + previous_running_state: RunningContractState::new( + self.previous_running_state.domains.clone(), + self.previous_running_state.keyset.clone(), + self.previous_running_state.parameters.clone(), + ), + reshared_keys: Vec::new(), + resharing_key: KeyEvent::new( + self.prospective_epoch_id().next(), + self + .previous_running_state + .domains + .get_domain_by_index(0) + .unwrap() + .clone(), + proposal.clone(), + ), + cancellation_requests: HashSet::new(), + }), + ); + } + Ok(None) + } + /// Starts a new attempt to reshare the key for the current domain. + /// Returns an Error if the signer is not the leader (the participant with the lowest ID). + pub fn start( + &mut self, + key_event_id: KeyEventId, + key_event_timeout_blocks: u64, + ) -> Result<(), Error> { + self.resharing_key.start(key_event_id, key_event_timeout_blocks) + } + /// Casts a successfully-reshared vote for for the attempt identified by `key_event_id`. + /// Upon success (a return of Ok(...)), the effect of this method is one of the following: + /// - A vote has been collected but we don't have enough votes yet. + /// - Everyone has now voted; the state transitions into resharing the key for the next domain. + /// (This returns Ok(None) still). + /// - Same as the last case, except that all domains' keys have been reshared now, and we + /// return Ok(Some(running state)) that the caller should now transition into. + /// + /// Fails in the following cases: + /// - There is no active key resharing attempt (including if the attempt timed out). + /// - The key_event_id corresponds to a different domain, different epoch, or different attempt + /// from the current key resharing attempt. + /// - The signer is not a participant in the *proposed* set of participants. + pub fn vote_reshared( + &mut self, + key_event_id: KeyEventId, + ) -> Result, Error> { + let previous_key = self + .previous_keyset() + .domains[self.reshared_keys.len()] + .clone(); + if self + .resharing_key + .vote_success(&key_event_id, previous_key.key.clone())? + { + let new_key = KeyForDomain { + domain_id: key_event_id.domain_id, + attempt: key_event_id.attempt_id, + key: previous_key.key, + }; + self.reshared_keys.push(new_key); + if let Some(next_domain) = self + .previous_running_state + .domains + .get_domain_by_index(self.reshared_keys.len()) + { + self.resharing_key = KeyEvent::new( + self.prospective_epoch_id(), + next_domain.clone(), + self.resharing_key.proposed_parameters().clone(), + ); + } else { + return Ok( + Some( + RunningContractState::new( + self.previous_running_state.domains.clone(), + Keyset::new( + self.prospective_epoch_id(), + self.reshared_keys.clone(), + ), + self.resharing_key.proposed_parameters().clone(), + ), + ), + ); + } + } + Ok(None) + } + /// Casts a vote to abort the current key resharing attempt. + /// After aborting, another call to start() is necessary to start a new attempt. + /// Returns error if there is no active attempt, or if the signer is not a proposed participant. + pub fn vote_abort(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { + self.resharing_key.vote_abort(key_event_id) + } + pub fn vote_cancel_resharing( + &mut self, + ) -> Result, Error> { + let previous_running_participants = self + .previous_running_state + .parameters + .participants(); + let authenticated_candidate = AuthenticatedAccountId::new( + previous_running_participants, + )?; + self.cancellation_requests.insert(authenticated_candidate); + let cancellation_votes_count = self.cancellation_requests.len() as u64; + let previous_running_threshold = self + .previous_running_state + .parameters + .threshold(); + let threshold_cancellation_votes_reached: bool = cancellation_votes_count + >= previous_running_threshold.value(); + let running_state = if threshold_cancellation_votes_reached { + let mut previous_running_state = self.previous_running_state.clone(); + let prospective_epoch_id = self.prospective_epoch_id(); + previous_running_state.previously_cancelled_resharing_epoch_id = Some( + prospective_epoch_id, + ); + Some(previous_running_state) + } else { + None + }; + Ok(running_state) + } + pub fn is_participant_or_prospective_participant( + &self, + account_id: &AccountId, + ) -> bool { + self.previous_running_state.is_participant(account_id) + || self + .resharing_key + .proposed_parameters() + .participants() + .is_participant(account_id) + } + } + } + pub mod running { + use super::initializing::InitializingContractState; + use super::key_event::KeyEvent; + use super::resharing::ResharingContractState; + use crate::errors::{DomainError, Error, InvalidParameters, VoteError}; + use crate::primitives::{ + domain::{AddDomainsVotes, DomainConfig, DomainRegistry}, + key_state::{ + AuthenticatedAccountId, AuthenticatedParticipantId, EpochId, Keyset, + }, + thresholds::ThresholdParameters, votes::ThresholdParametersVotes, + }; + use near_account_id::AccountId; + use near_sdk::near; + use std::collections::{BTreeSet, HashSet}; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// In this state, the contract is ready to process signature requests. + /// + /// Proposals can be submitted to modify the state: + /// - vote_add_domains, upon threshold agreement, transitions into the + /// Initializing state to generate keys for new domains. + /// - vote_new_parameters, upon threshold agreement, transitions into the + /// Resharing state to reshare keys for new participants and also change the + /// threshold if desired. + pub struct RunningContractState { + /// The domains for which we have a key ready for signature processing. + pub domains: DomainRegistry, + /// The keys that are currently in use; for each domain provides an unique identifier for a + /// distributed key, so that the nodes can identify which local keyshare to use. + pub keyset: Keyset, + /// The current participants and threshold. + pub parameters: ThresholdParameters, + /// Votes for proposals for a new set of participants and threshold. + pub parameters_votes: ThresholdParametersVotes, + /// Votes for proposals to add new domains. + pub add_domains_votes: AddDomainsVotes, + /// The previous epoch id for a resharing state that was cancelled. + /// This epoch id is tracked, as the next time the state transitions to resharing, + /// we can't reuse a previously cancelled epoch id. + pub previously_cancelled_resharing_epoch_id: Option, + } + #[automatically_derived] + impl ::core::clone::Clone for RunningContractState { + #[inline] + fn clone(&self) -> RunningContractState { + RunningContractState { + domains: ::core::clone::Clone::clone(&self.domains), + keyset: ::core::clone::Clone::clone(&self.keyset), + parameters: ::core::clone::Clone::clone(&self.parameters), + parameters_votes: ::core::clone::Clone::clone( + &self.parameters_votes, + ), + add_domains_votes: ::core::clone::Clone::clone( + &self.add_domains_votes, + ), + previously_cancelled_resharing_epoch_id: ::core::clone::Clone::clone( + &self.previously_cancelled_resharing_epoch_id, + ), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for RunningContractState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "domains", + "keyset", + "parameters", + "parameters_votes", + "add_domains_votes", + "previously_cancelled_resharing_epoch_id", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.domains, + &self.keyset, + &self.parameters, + &self.parameters_votes, + &self.add_domains_votes, + &&self.previously_cancelled_resharing_epoch_id, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "RunningContractState", + names, + values, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RunningContractState {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RunningContractState { + #[inline] + fn eq(&self, other: &RunningContractState) -> bool { + self.domains == other.domains && self.keyset == other.keyset + && self.parameters == other.parameters + && self.parameters_votes == other.parameters_votes + && self.add_domains_votes == other.add_domains_votes + && self.previously_cancelled_resharing_epoch_id + == other.previously_cancelled_resharing_epoch_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RunningContractState { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for RunningContractState { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.keyset, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.parameters, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.parameters_votes, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.add_domains_votes, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.previously_cancelled_resharing_epoch_id, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for RunningContractState { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + keyset: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + parameters: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + parameters_votes: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + add_domains_votes: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + previously_cancelled_resharing_epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for RunningContractState { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "RunningContractState", + false as usize + 1 + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domains", + &self.domains, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "keyset", + &self.keyset, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "parameters", + &self.parameters, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "parameters_votes", + &self.parameters_votes, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "add_domains_votes", + &self.add_domains_votes, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "previously_cancelled_resharing_epoch_id", + &self.previously_cancelled_resharing_epoch_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RunningContractState { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + 4u64 => _serde::__private228::Ok(__Field::__field4), + 5u64 => _serde::__private228::Ok(__Field::__field5), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "domains" => _serde::__private228::Ok(__Field::__field0), + "keyset" => _serde::__private228::Ok(__Field::__field1), + "parameters" => _serde::__private228::Ok(__Field::__field2), + "parameters_votes" => { + _serde::__private228::Ok(__Field::__field3) + } + "add_domains_votes" => { + _serde::__private228::Ok(__Field::__field4) + } + "previously_cancelled_resharing_epoch_id" => { + _serde::__private228::Ok(__Field::__field5) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"domains" => _serde::__private228::Ok(__Field::__field0), + b"keyset" => _serde::__private228::Ok(__Field::__field1), + b"parameters" => _serde::__private228::Ok(__Field::__field2), + b"parameters_votes" => { + _serde::__private228::Ok(__Field::__field3) + } + b"add_domains_votes" => { + _serde::__private228::Ok(__Field::__field4) + } + b"previously_cancelled_resharing_epoch_id" => { + _serde::__private228::Ok(__Field::__field5) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = RunningContractState; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct RunningContractState", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + DomainRegistry, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct RunningContractState with 6 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Keyset, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct RunningContractState with 6 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + ThresholdParameters, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct RunningContractState with 6 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + ThresholdParametersVotes, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct RunningContractState with 6 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + AddDomainsVotes, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct RunningContractState with 6 elements", + ), + ); + } + }; + let __field5 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 5usize, + &"struct RunningContractState with 6 elements", + ), + ); + } + }; + _serde::__private228::Ok(RunningContractState { + domains: __field0, + keyset: __field1, + parameters: __field2, + parameters_votes: __field3, + add_domains_votes: __field4, + previously_cancelled_resharing_epoch_id: __field5, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + DomainRegistry, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + let mut __field2: _serde::__private228::Option< + ThresholdParameters, + > = _serde::__private228::None; + let mut __field3: _serde::__private228::Option< + ThresholdParametersVotes, + > = _serde::__private228::None; + let mut __field4: _serde::__private228::Option< + AddDomainsVotes, + > = _serde::__private228::None; + let mut __field5: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "domains", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + DomainRegistry, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("keyset"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "parameters", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + ThresholdParameters, + >(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private228::Option::is_some(&__field3) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "parameters_votes", + ), + ); + } + __field3 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + ThresholdParametersVotes, + >(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private228::Option::is_some(&__field4) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "add_domains_votes", + ), + ); + } + __field4 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + AddDomainsVotes, + >(&mut __map)?, + ); + } + __Field::__field5 => { + if _serde::__private228::Option::is_some(&__field5) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "previously_cancelled_resharing_epoch_id", + ), + ); + } + __field5 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("domains")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("keyset")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field("parameters")? + } + }; + let __field3 = match __field3 { + _serde::__private228::Some(__field3) => __field3, + _serde::__private228::None => { + _serde::__private228::de::missing_field("parameters_votes")? + } + }; + let __field4 = match __field4 { + _serde::__private228::Some(__field4) => __field4, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "add_domains_votes", + )? + } + }; + let __field5 = match __field5 { + _serde::__private228::Some(__field5) => __field5, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "previously_cancelled_resharing_epoch_id", + )? + } + }; + _serde::__private228::Ok(RunningContractState { + domains: __field0, + keyset: __field1, + parameters: __field2, + parameters_votes: __field3, + add_domains_votes: __field4, + previously_cancelled_resharing_epoch_id: __field5, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "domains", + "keyset", + "parameters", + "parameters_votes", + "add_domains_votes", + "previously_cancelled_resharing_epoch_id", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "RunningContractState", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::< + RunningContractState, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl RunningContractState { + pub fn new( + domains: DomainRegistry, + keyset: Keyset, + parameters: ThresholdParameters, + ) -> Self { + RunningContractState { + domains, + keyset, + parameters, + parameters_votes: ThresholdParametersVotes::default(), + add_domains_votes: AddDomainsVotes::default(), + previously_cancelled_resharing_epoch_id: None, + } + } + pub fn transition_to_resharing_no_checks( + &mut self, + proposal: &ThresholdParameters, + ) -> Option { + if let Some(first_domain) = self.domains.get_domain_by_index(0) { + let epoch_id = self.prospective_epoch_id(); + Some(ResharingContractState { + previous_running_state: RunningContractState::new( + self.domains.clone(), + self.keyset.clone(), + self.parameters.clone(), + ), + reshared_keys: Vec::new(), + resharing_key: KeyEvent::new( + epoch_id, + first_domain.clone(), + proposal.clone(), + ), + cancellation_requests: HashSet::new(), + }) + } else { + *self = RunningContractState::new( + self.domains.clone(), + Keyset::new(self.keyset.epoch_id.next(), Vec::new()), + proposal.clone(), + ); + None + } + } + /// Casts a vote for `proposal` to the current state, propagating any errors. + /// Returns ResharingContractState if the proposal is accepted. + pub fn vote_new_parameters( + &mut self, + prospective_epoch_id: EpochId, + proposal: &ThresholdParameters, + ) -> Result, Error> { + let expected_prospective_epoch_id = self.prospective_epoch_id(); + if prospective_epoch_id != expected_prospective_epoch_id { + return Err( + InvalidParameters::EpochMismatch { + expected: expected_prospective_epoch_id, + provided: prospective_epoch_id, + } + .into(), + ); + } + if self.process_new_parameters_proposal(proposal)? { + return Ok(self.transition_to_resharing_no_checks(proposal)); + } + Ok(None) + } + pub fn prospective_epoch_id(&self) -> EpochId { + match self.previously_cancelled_resharing_epoch_id { + Some(cancelled_epoch_id) => cancelled_epoch_id, + None => self.keyset.epoch_id, + } + .next() + } + /// Casts a vote for `proposal`, removing any previous votes by `env::signer_account_id()`. + /// Fails if the proposal is invalid or the signer is not a proposed participant. + /// Returns true if all participants of the proposed parameters voted for it. + pub(super) fn process_new_parameters_proposal( + &mut self, + proposal: &ThresholdParameters, + ) -> Result { + self.parameters.validate_incoming_proposal(proposal)?; + let candidate = AuthenticatedAccountId::new(proposal.participants())?; + if AuthenticatedAccountId::new(self.parameters.participants()).is_err() { + let n_votes = self + .parameters_votes + .n_votes(proposal, self.parameters.participants()); + if n_votes < self.parameters.threshold().value() { + return Err(VoteError::VoterPending.into()); + } + } + let n_votes = self.parameters_votes.vote(proposal, candidate); + Ok(proposal.participants().len() as u64 == n_votes) + } + /// Casts a vote for the signer participant to add new domains, replacing any previous vote. + /// If the number of votes for the same set of new domains reaches the number of participants, + /// returns the InitializingContractState we should transition into to generate keys for these + /// new domains. + pub fn vote_add_domains( + &mut self, + domains: Vec, + ) -> Result, Error> { + if domains.is_empty() { + return Err(DomainError::AddDomainsMustAddAtLeastOneDomain.into()); + } + let participant = AuthenticatedParticipantId::new( + self.parameters.participants(), + )?; + let n_votes = self.add_domains_votes.vote(domains.clone(), &participant); + if self.parameters.participants().len() as u64 == n_votes { + let new_domains = self.domains.add_domains(domains.clone())?; + Ok( + Some(InitializingContractState { + generated_keys: self.keyset.domains.clone(), + domains: new_domains, + epoch_id: self.keyset.epoch_id, + generating_key: KeyEvent::new( + self.keyset.epoch_id, + domains[0].clone(), + self.parameters.clone(), + ), + cancel_votes: BTreeSet::new(), + }), + ) + } else { + Ok(None) + } + } + pub fn is_participant(&self, account_id: &AccountId) -> bool { + self.parameters.participants().is_participant(account_id) + } + } + } + use crate::crypto_shared::types::PublicKeyExtended; + use crate::errors::{DomainError, Error, InvalidState}; + use crate::primitives::{ + domain::{DomainConfig, DomainId, DomainRegistry, SignatureScheme}, + key_state::{AuthenticatedParticipantId, EpochId, KeyEventId}, + participants::Participants, thresholds::{Threshold, ThresholdParameters}, + }; + use initializing::InitializingContractState; + use near_account_id::AccountId; + use near_sdk::near; + use resharing::ResharingContractState; + use running::RunningContractState; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub enum ProtocolContractState { + NotInitialized, + Initializing(InitializingContractState), + Running(RunningContractState), + Resharing(ResharingContractState), + } + #[automatically_derived] + impl ::core::fmt::Debug for ProtocolContractState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ProtocolContractState::NotInitialized => { + ::core::fmt::Formatter::write_str(f, "NotInitialized") + } + ProtocolContractState::Initializing(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Initializing", + &__self_0, + ) + } + ProtocolContractState::Running(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Running", + &__self_0, + ) + } + ProtocolContractState::Resharing(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Resharing", + &__self_0, + ) + } + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for ProtocolContractState { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + let variant_idx: u8 = match self { + ProtocolContractState::NotInitialized => 0u8, + ProtocolContractState::Initializing(..) => 1u8, + ProtocolContractState::Running(..) => 2u8, + ProtocolContractState::Resharing(..) => 3u8, + }; + writer.write_all(&variant_idx.to_le_bytes())?; + match self { + ProtocolContractState::Initializing(id0) => { + ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; + } + ProtocolContractState::Running(id0) => { + ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; + } + ProtocolContractState::Resharing(id0) => { + ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; + } + _ => {} + } + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for ProtocolContractState { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + let tag = ::deserialize_reader( + reader, + )?; + ::deserialize_variant(reader, tag) + } + } + impl ::near_sdk::borsh::de::EnumExt for ProtocolContractState { + fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + variant_tag: u8, + ) -> ::core::result::Result { + let mut return_value = if variant_tag == 0u8 { + ProtocolContractState::NotInitialized + } else if variant_tag == 1u8 { + ProtocolContractState::Initializing( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ) + } else if variant_tag == 2u8 { + ProtocolContractState::Running( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ) + } else if variant_tag == 3u8 { + ProtocolContractState::Resharing( + ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + ) + } else { + return Err( + ::near_sdk::borsh::io::Error::new( + ::near_sdk::borsh::io::ErrorKind::InvalidData, + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Unexpected variant tag: {0:?}", variant_tag), + ); + res + }), + ), + ) + }; + Ok(return_value) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ProtocolContractState { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + ProtocolContractState::NotInitialized => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "ProtocolContractState", + 0u32, + "NotInitialized", + ) + } + ProtocolContractState::Initializing(ref __field0) => { + _serde::Serializer::serialize_newtype_variant( + __serializer, + "ProtocolContractState", + 1u32, + "Initializing", + __field0, + ) + } + ProtocolContractState::Running(ref __field0) => { + _serde::Serializer::serialize_newtype_variant( + __serializer, + "ProtocolContractState", + 2u32, + "Running", + __field0, + ) + } + ProtocolContractState::Resharing(ref __field0) => { + _serde::Serializer::serialize_newtype_variant( + __serializer, + "ProtocolContractState", + 3u32, + "Resharing", + __field0, + ) + } + } + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ProtocolContractState { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + 3u64 => _serde::__private228::Ok(__Field::__field3), + _ => { + _serde::__private228::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 4", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "NotInitialized" => { + _serde::__private228::Ok(__Field::__field0) + } + "Initializing" => _serde::__private228::Ok(__Field::__field1), + "Running" => _serde::__private228::Ok(__Field::__field2), + "Resharing" => _serde::__private228::Ok(__Field::__field3), + _ => { + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"NotInitialized" => { + _serde::__private228::Ok(__Field::__field0) + } + b"Initializing" => { + _serde::__private228::Ok(__Field::__field1) + } + b"Running" => _serde::__private228::Ok(__Field::__field2), + b"Resharing" => _serde::__private228::Ok(__Field::__field3), + _ => { + let __value = &_serde::__private228::from_utf8_lossy( + __value, + ); + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ProtocolContractState; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "enum ProtocolContractState", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private228::Ok( + ProtocolContractState::NotInitialized, + ) + } + (__Field::__field1, __variant) => { + _serde::__private228::Result::map( + _serde::de::VariantAccess::newtype_variant::< + InitializingContractState, + >(__variant), + ProtocolContractState::Initializing, + ) + } + (__Field::__field2, __variant) => { + _serde::__private228::Result::map( + _serde::de::VariantAccess::newtype_variant::< + RunningContractState, + >(__variant), + ProtocolContractState::Running, + ) + } + (__Field::__field3, __variant) => { + _serde::__private228::Result::map( + _serde::de::VariantAccess::newtype_variant::< + ResharingContractState, + >(__variant), + ProtocolContractState::Resharing, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "NotInitialized", + "Initializing", + "Running", + "Resharing", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "ProtocolContractState", + VARIANTS, + __Visitor { + marker: _serde::__private228::PhantomData::< + ProtocolContractState, + >, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl ProtocolContractState { + pub fn domain_registry(&self) -> Result<&DomainRegistry, Error> { + let domain_registry = match self { + ProtocolContractState::Running(state) => &state.domains, + ProtocolContractState::Resharing(state) => { + &state.previous_running_state.domains + } + _ => return Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), + }; + Ok(domain_registry) + } + pub fn public_key( + &self, + domain_id: DomainId, + ) -> Result { + match self { + ProtocolContractState::Running(state) => { + state.keyset.public_key(domain_id) + } + ProtocolContractState::Resharing(state) => { + state.previous_keyset().public_key(domain_id) + } + _ => Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), + } + } + pub fn threshold(&self) -> Result { + match self { + ProtocolContractState::Initializing(state) => { + Ok(state.generating_key.proposed_parameters().threshold()) + } + ProtocolContractState::Running(state) => Ok(state.parameters.threshold()), + ProtocolContractState::Resharing(state) => { + Ok(state.previous_running_state.parameters.threshold()) + } + ProtocolContractState::NotInitialized => { + Err(InvalidState::UnexpectedProtocolState.into()) + } + } + } + pub fn start_keygen_instance( + &mut self, + key_event_id: KeyEventId, + key_event_timeout_blocks: u64, + ) -> Result<(), Error> { + let ProtocolContractState::Initializing(state) = self else { + return Err(InvalidState::ProtocolStateNotInitializing.into()); + }; + state.start(key_event_id, key_event_timeout_blocks) + } + pub fn start_reshare_instance( + &mut self, + key_event_id: KeyEventId, + key_event_timeout_blocks: u64, + ) -> Result<(), Error> { + let ProtocolContractState::Resharing(state) = self else { + return Err(InvalidState::ProtocolStateNotResharing.into()); + }; + state.start(key_event_id, key_event_timeout_blocks) + } + pub fn vote_reshared( + &mut self, + key_event_id: KeyEventId, + ) -> Result, Error> { + let ProtocolContractState::Resharing(state) = self else { + return Err(InvalidState::ProtocolStateNotResharing.into()); + }; + state + .vote_reshared(key_event_id) + .map(|x| x.map(ProtocolContractState::Running)) + } + pub fn vote_cancel_resharing( + &mut self, + ) -> Result, Error> { + let ProtocolContractState::Resharing(state) = self else { + return Err(InvalidState::ProtocolStateNotResharing.into()); + }; + state.vote_cancel_resharing().map(|x| x.map(ProtocolContractState::Running)) + } + /// Casts a vote for `public_key` in `key_event_id` during Initialization. + /// Fails if the protocol is not in `Initializing` state. + /// Returns the new protocol state if enough votes have been submitted. + pub fn vote_pk( + &mut self, + key_event_id: KeyEventId, + public_key: PublicKeyExtended, + ) -> Result, Error> { + let ProtocolContractState::Initializing(state) = self else { + return Err(InvalidState::ProtocolStateNotInitializing.into()); + }; + state + .vote_pk(key_event_id, public_key) + .map(|x| x.map(ProtocolContractState::Running)) + } + /// Casts a vote for `proposed_parameters`, returning the new protocol state if the proposal is + /// accepted. Returns an error if the protocol is not in the Running or Resharing state. + pub fn vote_new_parameters( + &mut self, + prospective_epoch_id: EpochId, + proposed_parameters: &ThresholdParameters, + ) -> Result, Error> { + match self { + ProtocolContractState::Running(state) => { + state.vote_new_parameters(prospective_epoch_id, proposed_parameters) + } + ProtocolContractState::Resharing(state) => { + state.vote_new_parameters(prospective_epoch_id, proposed_parameters) + } + _ => Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), + } + .map(|x| x.map(ProtocolContractState::Resharing)) + } + pub fn vote_add_domains( + &mut self, + domains: Vec, + ) -> Result, Error> { + match self { + ProtocolContractState::Running(state) => state.vote_add_domains(domains), + _ => Err(InvalidState::ProtocolStateNotRunning.into()), + } + .map(|x| x.map(ProtocolContractState::Initializing)) + } + pub fn vote_abort_key_event_instance( + &mut self, + key_event_id: KeyEventId, + ) -> Result<(), Error> { + match self { + ProtocolContractState::Resharing(state) => state.vote_abort(key_event_id), + ProtocolContractState::Initializing(state) => { + state.vote_abort(key_event_id) + } + _ => Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), + } + } + pub fn vote_cancel_keygen( + &mut self, + next_domain_id: u64, + ) -> Result, Error> { + match self { + ProtocolContractState::Initializing(state) => { + state.vote_cancel(next_domain_id) + } + _ => Err(InvalidState::ProtocolStateNotInitializing.into()), + } + .map(|x| x.map(ProtocolContractState::Running)) + } + pub fn most_recent_domain_for_protocol( + &self, + signature_scheme: SignatureScheme, + ) -> Result { + self.domain_registry()? + .most_recent_domain_for_protocol(signature_scheme) + .ok_or_else(|| DomainError::NoSuchDomain.into()) + } + pub(super) fn threshold_parameters( + &self, + ) -> Result<&ThresholdParameters, ContractNotInitialized> { + match self { + ProtocolContractState::NotInitialized => Err(ContractNotInitialized), + ProtocolContractState::Initializing(initializing_contract_state) => { + Ok(initializing_contract_state.generating_key.proposed_parameters()) + } + ProtocolContractState::Running(running_contract_state) => { + Ok(&running_contract_state.parameters) + } + ProtocolContractState::Resharing(resharing_contract_state) => { + Ok(&resharing_contract_state.previous_running_state.parameters) + } + } + } + } + impl ProtocolContractState { + pub fn name(&self) -> &'static str { + match self { + ProtocolContractState::NotInitialized => "NotInitialized", + ProtocolContractState::Initializing(_) => "Initializing", + ProtocolContractState::Running(_) => "Running", + ProtocolContractState::Resharing(_) => "Resharing", + } + } + pub fn is_running_or_resharing(&self) -> bool { + match self { + ProtocolContractState::Running(_) + | ProtocolContractState::Resharing(_) => true, + _ => false, + } + } + pub fn authenticate_update_vote(&self) -> Result<(), Error> { + match &self { + ProtocolContractState::Initializing(state) => { + AuthenticatedParticipantId::new( + state.generating_key.proposed_parameters().participants(), + )?; + } + ProtocolContractState::Running(state) => { + AuthenticatedParticipantId::new(state.parameters.participants())?; + } + ProtocolContractState::Resharing(state) => { + AuthenticatedParticipantId::new( + state.previous_running_state.parameters.participants(), + )?; + } + ProtocolContractState::NotInitialized => { + return Err( + InvalidState::UnexpectedProtocolState.message(self.name()), + ); + } + }; + Ok(()) + } + /// Returns a reference to the relevant `Participants` list + /// based on the current protocol phase. + /// + /// - `Initializing` → uses proposed participants from generating_key + /// - `Running` → uses current active participants + /// - `Resharing` → uses new participants from resharing proposal + /// + /// Panics if called when `NotInitialized`. + pub fn active_participants(&self) -> &Participants { + match self { + ProtocolContractState::Initializing(state) => { + state.generating_key.proposed_parameters().participants() + } + ProtocolContractState::Running(state) => state.parameters.participants(), + ProtocolContractState::Resharing(state) => { + state.resharing_key.proposed_parameters().participants() + } + ProtocolContractState::NotInitialized => { + { + ::core::panicking::panic_fmt( + format_args!( + "Protocol must be Initializing, Running, or Resharing to access active participants", + ), + ); + }; + } + } + } + pub fn is_existing_or_prospective_participant( + &self, + account_id: &AccountId, + ) -> Result { + let is_existing_or_prospective_participant = match &self { + ProtocolContractState::Initializing(state) => { + state.is_participant(account_id) + } + ProtocolContractState::Running(state) => state.is_participant(account_id), + ProtocolContractState::Resharing(state) => { + state.is_participant_or_prospective_participant(account_id) + } + ProtocolContractState::NotInitialized => { + return Err( + InvalidState::UnexpectedProtocolState.message(self.name()), + ); + } + }; + Ok(is_existing_or_prospective_participant) + } + } + pub(super) struct ContractNotInitialized; + #[automatically_derived] + impl ::core::fmt::Debug for ContractNotInitialized { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "ContractNotInitialized") + } + } + #[automatically_derived] + impl ::core::clone::Clone for ContractNotInitialized { + #[inline] + fn clone(&self) -> ContractNotInitialized { + ContractNotInitialized + } + } +} +pub mod storage_keys { + use near_sdk::{near, BorshStorageKey}; + #[borsh(crate = ":: near_sdk :: borsh")] + pub enum StorageKey { + _DeprecatedPendingRequests, + /// Proposed updates to the contract code and config. + _DeprecatedProposedUpdatesEntries, + _DeprecatedRequestsByTimestamp, + PendingSignatureRequestsV2, + ProposedUpdatesEntriesV2, + ProposedUpdatesVotesV2, + _DeprecatedTeeParticipantAttestation, + PendingCKDRequests, + BackupServicesInfo, + NodeMigrations, + } + #[automatically_derived] + impl ::core::hash::Hash for StorageKey { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + let __self_discr = ::core::intrinsics::discriminant_value(self); + ::core::hash::Hash::hash(&__self_discr, state) + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageKey { + #[inline] + fn clone(&self) -> StorageKey { + match self { + StorageKey::_DeprecatedPendingRequests => { + StorageKey::_DeprecatedPendingRequests + } + StorageKey::_DeprecatedProposedUpdatesEntries => { + StorageKey::_DeprecatedProposedUpdatesEntries + } + StorageKey::_DeprecatedRequestsByTimestamp => { + StorageKey::_DeprecatedRequestsByTimestamp + } + StorageKey::PendingSignatureRequestsV2 => { + StorageKey::PendingSignatureRequestsV2 + } + StorageKey::ProposedUpdatesEntriesV2 => { + StorageKey::ProposedUpdatesEntriesV2 + } + StorageKey::ProposedUpdatesVotesV2 => StorageKey::ProposedUpdatesVotesV2, + StorageKey::_DeprecatedTeeParticipantAttestation => { + StorageKey::_DeprecatedTeeParticipantAttestation + } + StorageKey::PendingCKDRequests => StorageKey::PendingCKDRequests, + StorageKey::BackupServicesInfo => StorageKey::BackupServicesInfo, + StorageKey::NodeMigrations => StorageKey::NodeMigrations, + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageKey { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + StorageKey::_DeprecatedPendingRequests => { + "_DeprecatedPendingRequests" + } + StorageKey::_DeprecatedProposedUpdatesEntries => { + "_DeprecatedProposedUpdatesEntries" + } + StorageKey::_DeprecatedRequestsByTimestamp => { + "_DeprecatedRequestsByTimestamp" + } + StorageKey::PendingSignatureRequestsV2 => { + "PendingSignatureRequestsV2" + } + StorageKey::ProposedUpdatesEntriesV2 => "ProposedUpdatesEntriesV2", + StorageKey::ProposedUpdatesVotesV2 => "ProposedUpdatesVotesV2", + StorageKey::_DeprecatedTeeParticipantAttestation => { + "_DeprecatedTeeParticipantAttestation" + } + StorageKey::PendingCKDRequests => "PendingCKDRequests", + StorageKey::BackupServicesInfo => "BackupServicesInfo", + StorageKey::NodeMigrations => "NodeMigrations", + }, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageKey {} + #[automatically_derived] + impl ::core::cmp::PartialEq for StorageKey { + #[inline] + fn eq(&self, other: &StorageKey) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageKey { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + impl ::near_sdk::__private::BorshIntoStorageKey for StorageKey + where + StorageKey: ::near_sdk::borsh::BorshSerialize, + {} + impl ::near_sdk::borsh::ser::BorshSerialize for StorageKey { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + let variant_idx: u8 = match self { + StorageKey::_DeprecatedPendingRequests => 0u8, + StorageKey::_DeprecatedProposedUpdatesEntries => 1u8, + StorageKey::_DeprecatedRequestsByTimestamp => 2u8, + StorageKey::PendingSignatureRequestsV2 => 3u8, + StorageKey::ProposedUpdatesEntriesV2 => 4u8, + StorageKey::ProposedUpdatesVotesV2 => 5u8, + StorageKey::_DeprecatedTeeParticipantAttestation => 6u8, + StorageKey::PendingCKDRequests => 7u8, + StorageKey::BackupServicesInfo => 8u8, + StorageKey::NodeMigrations => 9u8, + }; + writer.write_all(&variant_idx.to_le_bytes())?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for StorageKey { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + let tag = ::deserialize_reader( + reader, + )?; + ::deserialize_variant(reader, tag) + } + } + impl ::near_sdk::borsh::de::EnumExt for StorageKey { + fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + variant_tag: u8, + ) -> ::core::result::Result { + let mut return_value = if variant_tag == 0u8 { + StorageKey::_DeprecatedPendingRequests + } else if variant_tag == 1u8 { + StorageKey::_DeprecatedProposedUpdatesEntries + } else if variant_tag == 2u8 { + StorageKey::_DeprecatedRequestsByTimestamp + } else if variant_tag == 3u8 { + StorageKey::PendingSignatureRequestsV2 + } else if variant_tag == 4u8 { + StorageKey::ProposedUpdatesEntriesV2 + } else if variant_tag == 5u8 { + StorageKey::ProposedUpdatesVotesV2 + } else if variant_tag == 6u8 { + StorageKey::_DeprecatedTeeParticipantAttestation + } else if variant_tag == 7u8 { + StorageKey::PendingCKDRequests + } else if variant_tag == 8u8 { + StorageKey::BackupServicesInfo + } else if variant_tag == 9u8 { + StorageKey::NodeMigrations + } else { + return Err( + ::near_sdk::borsh::io::Error::new( + ::near_sdk::borsh::io::ErrorKind::InvalidData, + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Unexpected variant tag: {0:?}", variant_tag), + ); + res + }), + ), + ) + }; + Ok(return_value) + } + } +} +pub mod tee { + pub mod proposal { + use borsh::{BorshDeserialize, BorshSerialize}; + use near_sdk::{env::sha256, log, near}; + use std::{collections::BTreeMap, time::Duration}; + use crate::primitives::{key_state::AuthenticatedParticipantId, time::Timestamp}; + pub use mpc_primitives::hash::{LauncherDockerComposeHash, MpcDockerImageHash}; + /// TCB info JSON file containing measurement values. + const LAUNCHER_DOCKER_COMPOSE_YAML_TEMPLATE: &str = "version: \'3.8\'\n\nservices:\n launcher:\n image: nearone/mpc-launcher@sha256:4065f2fce41415962be92471a4e793ff5147b00b2784617c7e8098be2761a875\n\n container_name: launcher\n\n environment:\n - DOCKER_CONTENT_TRUST=1\n - DEFAULT_IMAGE_DIGEST=sha256:{{DEFAULT_IMAGE_DIGEST_HASH}}\n\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - /var/run/dstack.sock:/var/run/dstack.sock\n - /tapp:/tapp:ro\n - shared-volume:/mnt/shared:ro\n\n security_opt:\n - no-new-privileges:true\n\n read_only: true\n\n tmpfs:\n - /tmp\n\nvolumes:\n shared-volume:\n name: shared-volume\n"; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + /// Tracks votes to add whitelisted TEE code hashes. Each participant can at any given time vote for + /// a code hash to add. + pub struct CodeHashesVotes { + pub proposal_by_account: BTreeMap< + AuthenticatedParticipantId, + MpcDockerImageHash, + >, + } + #[automatically_derived] + impl ::core::fmt::Debug for CodeHashesVotes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "CodeHashesVotes", + "proposal_by_account", + &&self.proposal_by_account, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for CodeHashesVotes { + #[inline] + fn clone(&self) -> CodeHashesVotes { + CodeHashesVotes { + proposal_by_account: ::core::clone::Clone::clone( + &self.proposal_by_account, + ), + } + } + } + #[automatically_derived] + impl ::core::default::Default for CodeHashesVotes { + #[inline] + fn default() -> CodeHashesVotes { + CodeHashesVotes { + proposal_by_account: ::core::default::Default::default(), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for CodeHashesVotes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for CodeHashesVotes { + #[inline] + fn eq(&self, other: &CodeHashesVotes) -> bool { + self.proposal_by_account == other.proposal_by_account + } + } + #[automatically_derived] + impl ::core::cmp::Eq for CodeHashesVotes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq< + BTreeMap, + >; + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for CodeHashesVotes { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.proposal_by_account, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for CodeHashesVotes { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + proposal_by_account: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for CodeHashesVotes { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "CodeHashesVotes", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "proposal_by_account", + &self.proposal_by_account, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for CodeHashesVotes { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "proposal_by_account" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"proposal_by_account" => { + _serde::__private228::Ok(__Field::__field0) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = CodeHashesVotes; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct CodeHashesVotes", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + BTreeMap, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct CodeHashesVotes with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(CodeHashesVotes { + proposal_by_account: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + BTreeMap, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "proposal_by_account", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + BTreeMap, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "proposal_by_account", + )? + } + }; + _serde::__private228::Ok(CodeHashesVotes { + proposal_by_account: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["proposal_by_account"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "CodeHashesVotes", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl CodeHashesVotes { + /// Casts a vote for the proposal and returns the total number of participants who have voted + /// for the same code hash. If the participant already voted, their previous vote is replaced. + pub fn vote( + &mut self, + proposal: MpcDockerImageHash, + participant: &AuthenticatedParticipantId, + ) -> u64 { + if self + .proposal_by_account + .insert(participant.clone(), proposal.clone()) + .is_some() + { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("removed old vote for signer"), + ); + res + }) + .as_str(), + ); + } + let total = self.count_votes(&proposal); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("total votes for proposal: {0}", total), + ); + res + }) + .as_str(), + ); + total + } + /// Counts the total number of participants who have voted for the given code hash. + fn count_votes(&self, proposal: &MpcDockerImageHash) -> u64 { + self + .proposal_by_account + .values() + .filter(|&prop| prop == proposal) + .count() as u64 + } + /// Clears all proposals. + pub fn clear_votes(&mut self) { + self.proposal_by_account.clear(); + } + } + /// An allowed Docker image configuration entry containing both the MPC image hash and its + /// corresponding launcher compose hash, along with when it was added to the allowlist. + pub struct AllowedMpcDockerImage { + pub(crate) image_hash: MpcDockerImageHash, + pub(crate) docker_compose_hash: LauncherDockerComposeHash, + pub(crate) added: Timestamp, + } + #[automatically_derived] + impl ::core::fmt::Debug for AllowedMpcDockerImage { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "AllowedMpcDockerImage", + "image_hash", + &self.image_hash, + "docker_compose_hash", + &self.docker_compose_hash, + "added", + &&self.added, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for AllowedMpcDockerImage { + #[inline] + fn clone(&self) -> AllowedMpcDockerImage { + AllowedMpcDockerImage { + image_hash: ::core::clone::Clone::clone(&self.image_hash), + docker_compose_hash: ::core::clone::Clone::clone( + &self.docker_compose_hash, + ), + added: ::core::clone::Clone::clone(&self.added), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AllowedMpcDockerImage {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AllowedMpcDockerImage { + #[inline] + fn eq(&self, other: &AllowedMpcDockerImage) -> bool { + self.image_hash == other.image_hash + && self.docker_compose_hash == other.docker_compose_hash + && self.added == other.added + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AllowedMpcDockerImage { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + impl borsh::ser::BorshSerialize for AllowedMpcDockerImage { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.image_hash, writer)?; + borsh::BorshSerialize::serialize(&self.docker_compose_hash, writer)?; + borsh::BorshSerialize::serialize(&self.added, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for AllowedMpcDockerImage { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + image_hash: borsh::BorshDeserialize::deserialize_reader(reader)?, + docker_compose_hash: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + added: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + /// Collection of whitelisted Docker code hashes that are the only ones MPC nodes are allowed to + /// run. + pub(crate) struct AllowedDockerImageHashes { + /// Whitelisted code hashes, sorted by when they were added (oldest first). Expired entries are + /// lazily cleaned up during insertions and TEE validation. + allowed_tee_proposals: Vec, + } + #[automatically_derived] + impl ::core::clone::Clone for AllowedDockerImageHashes { + #[inline] + fn clone(&self) -> AllowedDockerImageHashes { + AllowedDockerImageHashes { + allowed_tee_proposals: ::core::clone::Clone::clone( + &self.allowed_tee_proposals, + ), + } + } + } + #[automatically_derived] + impl ::core::default::Default for AllowedDockerImageHashes { + #[inline] + fn default() -> AllowedDockerImageHashes { + AllowedDockerImageHashes { + allowed_tee_proposals: ::core::default::Default::default(), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for AllowedDockerImageHashes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "AllowedDockerImageHashes", + "allowed_tee_proposals", + &&self.allowed_tee_proposals, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AllowedDockerImageHashes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AllowedDockerImageHashes { + #[inline] + fn eq(&self, other: &AllowedDockerImageHashes) -> bool { + self.allowed_tee_proposals == other.allowed_tee_proposals + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AllowedDockerImageHashes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + impl borsh::ser::BorshSerialize for AllowedDockerImageHashes { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.allowed_tee_proposals, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for AllowedDockerImageHashes { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + allowed_tee_proposals: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + impl AllowedDockerImageHashes { + /// Checks if a Docker image hash is still valid (not expired). + fn valid_entries( + &self, + tee_upgrade_deadline_duration: Duration, + ) -> Vec { + let current_time = Timestamp::now(); + let cutoff_index = self + .allowed_tee_proposals + .iter() + .rposition(|allowed_docker_image| { + let Some(grace_period_deadline) = allowed_docker_image + .added + .checked_add(tee_upgrade_deadline_duration) else { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Error: timestamp overflowed when calculating grace_period_deadline.", + ), + ); + res + }) + .as_str(), + ); + return true; + }; + grace_period_deadline < current_time + }) + .unwrap_or(0); + self.allowed_tee_proposals.get(cutoff_index..).unwrap_or(&[]).to_vec() + } + /// Removes all expired code hashes and returns the number of removed entries. + /// Ensures that at least one (the latest) proposal always remains in the whitelist. + pub fn cleanup_expired_hashes( + &mut self, + tee_upgrade_deadline_duration: Duration, + ) { + let valid_entries = self.valid_entries(tee_upgrade_deadline_duration); + self.allowed_tee_proposals = valid_entries; + } + /// Inserts a new code hash into the list after cleaning expired entries. Maintains the sorted + /// order by `added` (ascending). + pub fn insert( + &mut self, + code_hash: MpcDockerImageHash, + tee_upgrade_deadline_duration: Duration, + ) { + self.cleanup_expired_hashes(tee_upgrade_deadline_duration); + if let Some(pos) = self + .allowed_tee_proposals + .iter() + .position(|entry| entry.image_hash == code_hash) + { + self.allowed_tee_proposals.remove(pos); + } + let docker_compose_hash = Self::get_docker_compose_hash( + code_hash.clone(), + ); + let new_entry = AllowedMpcDockerImage { + image_hash: code_hash, + docker_compose_hash, + added: Timestamp::now(), + }; + let insert_index = self + .allowed_tee_proposals + .iter() + .rposition(|entry| new_entry.added < entry.added) + .unwrap_or(self.allowed_tee_proposals.len()); + self.allowed_tee_proposals.insert(insert_index, new_entry); + } + /// Returns valid hashes without cleaning expired entries (read-only). Ensures that at least + /// one proposal (the latest) is always returned. Use [`Self::cleanup_expired_hashes`] + /// explicitly when cleanup of the internal structure is needed. + pub fn get( + &self, + tee_upgrade_deadline_duration: Duration, + ) -> Vec { + self.valid_entries(tee_upgrade_deadline_duration) + } + pub fn get_docker_compose_hash( + mpc_docker_image_hash: MpcDockerImageHash, + ) -> LauncherDockerComposeHash { + let filled_yaml = LAUNCHER_DOCKER_COMPOSE_YAML_TEMPLATE + .replace( + "{{DEFAULT_IMAGE_DIGEST_HASH}}", + &mpc_docker_image_hash.as_hex(), + ); + let hash = sha256(filled_yaml.as_bytes()); + if !(hash.len() == 32) { + { + ::core::panicking::panic_fmt( + format_args!("Docker compose hash must be 32 bytes long"), + ); + } + } + let mut hash_arr = [0u8; 32]; + hash_arr.copy_from_slice(&hash); + LauncherDockerComposeHash::from(hash_arr) + } + } + } + pub mod tee_state { + use crate::{ + primitives::{ + key_state::AuthenticatedParticipantId, participants::Participants, + }, + tee::proposal::{ + AllowedDockerImageHashes, AllowedMpcDockerImage, CodeHashesVotes, + MpcDockerImageHash, + }, + TryIntoInterfaceType, + }; + use borsh::{BorshDeserialize, BorshSerialize}; + use mpc_attestation::{ + attestation::{self, Attestation, VerifiedAttestation}, + report_data::{ReportData, ReportDataV1}, + }; + use mpc_primitives::hash::LauncherDockerComposeHash; + use near_account_id::AccountId; + use near_sdk::{env, near}; + use std::{collections::BTreeMap, hash::{Hash, Hasher}}; + use std::{collections::HashSet, time::Duration}; + use utilities::AccountIdExtV1; + #[serde(crate = ":: near_sdk :: serde")] + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct NodeId { + /// Operator account + pub account_id: AccountId, + /// TLS public key, MUST BE of type Ed25519 + pub tls_public_key: near_sdk::PublicKey, + pub account_public_key: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for NodeId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "NodeId", + "account_id", + &self.account_id, + "tls_public_key", + &self.tls_public_key, + "account_public_key", + &&self.account_public_key, + ) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for NodeId { + #[inline] + fn cmp(&self, other: &NodeId) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.account_id, &other.account_id) { + ::core::cmp::Ordering::Equal => { + match ::core::cmp::Ord::cmp( + &self.tls_public_key, + &other.tls_public_key, + ) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp( + &self.account_public_key, + &other.account_public_key, + ) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for NodeId { + #[inline] + fn partial_cmp( + &self, + other: &NodeId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.account_id, + &other.account_id, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + match ::core::cmp::PartialOrd::partial_cmp( + &self.tls_public_key, + &other.tls_public_key, + ) { + ::core::option::Option::Some( + ::core::cmp::Ordering::Equal, + ) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.account_public_key, + &other.account_public_key, + ) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for NodeId { + #[inline] + fn clone(&self) -> NodeId { + NodeId { + account_id: ::core::clone::Clone::clone(&self.account_id), + tls_public_key: ::core::clone::Clone::clone(&self.tls_public_key), + account_public_key: ::core::clone::Clone::clone( + &self.account_public_key, + ), + } + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for NodeId { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.account_id, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.tls_public_key, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize( + &self.account_public_key, + writer, + )?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for NodeId { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + account_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + tls_public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + account_public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl _serde::Serialize for NodeId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "NodeId", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "account_id", + &self.account_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "tls_public_key", + &self.tls_public_key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "account_public_key", + &self.account_public_key, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for NodeId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + 2u64 => _serde::__private228::Ok(__Field::__field2), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "account_id" => _serde::__private228::Ok(__Field::__field0), + "tls_public_key" => { + _serde::__private228::Ok(__Field::__field1) + } + "account_public_key" => { + _serde::__private228::Ok(__Field::__field2) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"account_id" => _serde::__private228::Ok(__Field::__field0), + b"tls_public_key" => { + _serde::__private228::Ok(__Field::__field1) + } + b"account_public_key" => { + _serde::__private228::Ok(__Field::__field2) + } + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = NodeId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct NodeId", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + AccountId, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct NodeId with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + near_sdk::PublicKey, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct NodeId with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct NodeId with 3 elements", + ), + ); + } + }; + _serde::__private228::Ok(NodeId { + account_id: __field0, + tls_public_key: __field1, + account_public_key: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + near_sdk::PublicKey, + > = _serde::__private228::None; + let mut __field2: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "account_id", + ), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "tls_public_key", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + near_sdk::PublicKey, + >(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private228::Option::is_some(&__field2) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "account_public_key", + ), + ); + } + __field2 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("account_id")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("tls_public_key")? + } + }; + let __field2 = match __field2 { + _serde::__private228::Some(__field2) => __field2, + _serde::__private228::None => { + _serde::__private228::de::missing_field( + "account_public_key", + )? + } + }; + _serde::__private228::Ok(NodeId { + account_id: __field0, + tls_public_key: __field1, + account_public_key: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "account_id", + "tls_public_key", + "account_public_key", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "NodeId", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl PartialEq for NodeId { + fn eq(&self, other: &Self) -> bool { + self.account_id == other.account_id + && self.tls_public_key == other.tls_public_key + } + } + impl Eq for NodeId {} + impl Hash for NodeId { + fn hash(&self, state: &mut H) { + self.account_id.hash(state); + self.tls_public_key.hash(state); + } + } + pub enum TeeQuoteStatus { + /// TEE quote and Docker image verification both passed successfully. + /// The participant is considered to have a valid, verified TEE status. + Valid, + /// TEE verification failed - either the quote verification failed, + /// the Docker image verification failed, or both validations failed. + /// The participant should not be trusted for TEE-dependent operations. + Invalid(String), + } + #[automatically_derived] + impl ::core::fmt::Debug for TeeQuoteStatus { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TeeQuoteStatus::Valid => { + ::core::fmt::Formatter::write_str(f, "Valid") + } + TeeQuoteStatus::Invalid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Invalid", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for TeeQuoteStatus { + #[inline] + fn clone(&self) -> TeeQuoteStatus { + match self { + TeeQuoteStatus::Valid => TeeQuoteStatus::Valid, + TeeQuoteStatus::Invalid(__self_0) => { + TeeQuoteStatus::Invalid(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TeeQuoteStatus {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TeeQuoteStatus { + #[inline] + fn eq(&self, other: &TeeQuoteStatus) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + ( + TeeQuoteStatus::Invalid(__self_0), + TeeQuoteStatus::Invalid(__arg1_0), + ) => __self_0 == __arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TeeQuoteStatus { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + pub(crate) enum AttestationSubmissionError { + #[error("the submitted attestation failed verification, reason: {:?}", .0)] + InvalidAttestation(#[from] attestation::VerificationError), + #[error("the submitted attestation's TLS key is not a valid ED25519 key")] + InvalidTlsKey, + } + #[automatically_derived] + impl ::core::fmt::Debug for AttestationSubmissionError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + AttestationSubmissionError::InvalidAttestation(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InvalidAttestation", + &__self_0, + ) + } + AttestationSubmissionError::InvalidTlsKey => { + ::core::fmt::Formatter::write_str(f, "InvalidTlsKey") + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for AttestationSubmissionError { + #[inline] + fn clone(&self) -> AttestationSubmissionError { + match self { + AttestationSubmissionError::InvalidAttestation(__self_0) => { + AttestationSubmissionError::InvalidAttestation( + ::core::clone::Clone::clone(__self_0), + ) + } + AttestationSubmissionError::InvalidTlsKey => { + AttestationSubmissionError::InvalidTlsKey + } + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::thiserror::__private17::Error for AttestationSubmissionError { + fn source( + &self, + ) -> ::core::option::Option< + &(dyn ::thiserror::__private17::Error + 'static), + > { + use ::thiserror::__private17::AsDynError as _; + #[allow(deprecated)] + match self { + AttestationSubmissionError::InvalidAttestation { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + AttestationSubmissionError::InvalidTlsKey { .. } => { + ::core::option::Option::None + } + } + } + } + #[allow(unused_qualifications)] + #[automatically_derived] + impl ::core::fmt::Display for AttestationSubmissionError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + AttestationSubmissionError::InvalidAttestation(_0) => { + __formatter + .write_fmt( + format_args!( + "the submitted attestation failed verification, reason: {0:?}", + _0, + ), + ) + } + AttestationSubmissionError::InvalidTlsKey {} => { + __formatter + .write_str( + "the submitted attestation's TLS key is not a valid ED25519 key", + ) + } + } + } + } + #[allow( + deprecated, + unused_qualifications, + clippy::elidable_lifetime_names, + clippy::needless_lifetimes, + )] + #[automatically_derived] + impl ::core::convert::From + for AttestationSubmissionError { + fn from(source: attestation::VerificationError) -> Self { + AttestationSubmissionError::InvalidAttestation { + 0: source, + } + } + } + pub(crate) enum ParticipantInsertion { + NewlyInsertedParticipant, + UpdatedExistingParticipant, + } + #[automatically_derived] + impl ::core::fmt::Debug for ParticipantInsertion { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + ParticipantInsertion::NewlyInsertedParticipant => { + "NewlyInsertedParticipant" + } + ParticipantInsertion::UpdatedExistingParticipant => { + "UpdatedExistingParticipant" + } + }, + ) + } + } + pub enum TeeValidationResult { + /// All participants are valid + Full, + /// Only a subset of the participants have a valid attestation. + Partial { participants_with_valid_attestation: Participants }, + } + #[automatically_derived] + impl ::core::fmt::Debug for TeeValidationResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TeeValidationResult::Full => { + ::core::fmt::Formatter::write_str(f, "Full") + } + TeeValidationResult::Partial { + participants_with_valid_attestation: __self_0, + } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Partial", + "participants_with_valid_attestation", + &__self_0, + ) + } + } + } + } + pub(crate) struct NodeAttestation { + pub(crate) node_id: NodeId, + pub(crate) verified_attestation: VerifiedAttestation, + } + #[automatically_derived] + impl ::core::fmt::Debug for NodeAttestation { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "NodeAttestation", + "node_id", + &self.node_id, + "verified_attestation", + &&self.verified_attestation, + ) + } + } + impl borsh::ser::BorshSerialize for NodeAttestation { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.node_id, writer)?; + borsh::BorshSerialize::serialize(&self.verified_attestation, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for NodeAttestation { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + node_id: borsh::BorshDeserialize::deserialize_reader(reader)?, + verified_attestation: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + pub struct TeeState { + pub(crate) allowed_docker_image_hashes: AllowedDockerImageHashes, + pub(crate) allowed_launcher_compose_hashes: Vec, + pub(crate) votes: CodeHashesVotes, + /// Mapping of TLS public key of a participant to its [`NodeAttestation`]. + /// Attestations are stored for any valid participant that has submitted one, not + /// just for the currently active participants. + pub(crate) stored_attestations: BTreeMap< + near_sdk::PublicKey, + NodeAttestation, + >, + } + #[automatically_derived] + impl ::core::default::Default for TeeState { + #[inline] + fn default() -> TeeState { + TeeState { + allowed_docker_image_hashes: ::core::default::Default::default(), + allowed_launcher_compose_hashes: ::core::default::Default::default(), + votes: ::core::default::Default::default(), + stored_attestations: ::core::default::Default::default(), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TeeState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "TeeState", + "allowed_docker_image_hashes", + &self.allowed_docker_image_hashes, + "allowed_launcher_compose_hashes", + &self.allowed_launcher_compose_hashes, + "votes", + &self.votes, + "stored_attestations", + &&self.stored_attestations, + ) + } + } + impl borsh::ser::BorshSerialize for TeeState { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize( + &self.allowed_docker_image_hashes, + writer, + )?; + borsh::BorshSerialize::serialize( + &self.allowed_launcher_compose_hashes, + writer, + )?; + borsh::BorshSerialize::serialize(&self.votes, writer)?; + borsh::BorshSerialize::serialize(&self.stored_attestations, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for TeeState { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + allowed_docker_image_hashes: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + allowed_launcher_compose_hashes: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + votes: borsh::BorshDeserialize::deserialize_reader(reader)?, + stored_attestations: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + impl TeeState { + /// Creates a [`TeeState`] with an initial set of participants that will receive a valid mocked attestation. + pub(crate) fn with_mocked_participant_attestations( + participants: &Participants, + ) -> Self { + let mut participants_attestations = BTreeMap::new(); + participants + .participants() + .iter() + .for_each(|(account_id, _, participant_info)| { + let node_id = NodeId { + account_id: account_id.clone(), + tls_public_key: participant_info.sign_pk.clone(), + account_public_key: None, + }; + participants_attestations + .insert( + participant_info.sign_pk.clone(), + NodeAttestation { + node_id, + verified_attestation: VerifiedAttestation::Mock( + attestation::MockAttestation::Valid, + ), + }, + ); + }); + Self { + stored_attestations: participants_attestations, + ..Default::default() + } + } + fn current_time_seconds() -> u64 { + let current_time_milliseconds = env::block_timestamp_ms(); + current_time_milliseconds / 1_000 + } + /// Adds a participant attestation for the given node iff the attestation succeeds verification. + pub(crate) fn add_participant( + &mut self, + node_id: NodeId, + attestation: Attestation, + tee_upgrade_deadline_duration: Duration, + ) -> Result { + let tls_public_key = node_id + .tls_public_key + .clone() + .try_into_dto_type() + .map_err(|_| AttestationSubmissionError::InvalidTlsKey)?; + let account_public_key = match node_id.account_public_key.clone() { + Some(pk) => pk.try_into_dto_type().ok(), + None => None, + }; + let account_key_bytes = match account_public_key { + Some(ref pk) => *pk.as_bytes(), + None => [0u8; 32], + }; + let expected_report_data: ReportData = ReportDataV1::new( + *tls_public_key.as_bytes(), + account_key_bytes, + ) + .into(); + let verified_attestation = attestation + .verify( + expected_report_data.into(), + Self::current_time_seconds(), + &self + .get_allowed_mpc_docker_image_hashes( + tee_upgrade_deadline_duration, + ), + &self.allowed_launcher_compose_hashes, + )?; + let tls_pk = node_id.tls_public_key.clone(); + let insertion = self + .stored_attestations + .insert( + tls_pk, + NodeAttestation { + node_id, + verified_attestation, + }, + ); + Ok( + match insertion { + Some(_previous_attestation) => { + ParticipantInsertion::UpdatedExistingParticipant + } + None => ParticipantInsertion::NewlyInsertedParticipant, + }, + ) + } + /// reverifies stored participant attestations. + pub(crate) fn reverify_participants( + &self, + node_id: &NodeId, + tee_upgrade_deadline_duration: Duration, + ) -> TeeQuoteStatus { + let allowed_mpc_docker_image_hashes = self + .get_allowed_mpc_docker_image_hashes(tee_upgrade_deadline_duration); + let allowed_launcher_compose_hashes = &self + .allowed_launcher_compose_hashes; + let participant_attestation = self + .stored_attestations + .get(&node_id.tls_public_key); + let Some(participant_attestation) = participant_attestation else { + return TeeQuoteStatus::Invalid( + "participant has no attestation".to_string(), + ); + }; + let time_stamp_seconds = Self::current_time_seconds(); + match participant_attestation + .verified_attestation + .re_verify( + time_stamp_seconds, + &allowed_mpc_docker_image_hashes, + allowed_launcher_compose_hashes, + ) + { + Ok(()) => TeeQuoteStatus::Valid, + Err(err) => TeeQuoteStatus::Invalid(err.to_string()), + } + } + /// reverifies stored participant attestations and removes any participant attestation + /// from the internal state that fails reverifications. Reverification can fail for example + /// the MPC image hash the attestation was tied to is no longer allowed, or due to certificate + /// expiries. + pub fn reverify_and_cleanup_participants( + &mut self, + participants: &Participants, + tee_upgrade_deadline_duration: Duration, + ) -> TeeValidationResult { + self.allowed_docker_image_hashes + .cleanup_expired_hashes(tee_upgrade_deadline_duration); + let participants_with_valid_attestation: Vec<_> = participants + .participants() + .iter() + .filter(|(account_id, _, participant_info)| { + let tls_public_key = participant_info.sign_pk.clone(); + let maybe_node = self.find_node_id_by_tls_key(&tls_public_key); + let node_id = NodeId { + account_id: account_id.clone(), + tls_public_key: tls_public_key.clone(), + account_public_key: maybe_node + .and_then(|n| n.account_public_key.clone()), + }; + let tee_status = self + .reverify_participants( + &node_id, + tee_upgrade_deadline_duration, + ); + match tee_status { + TeeQuoteStatus::Valid => true, + _ => false, + } + }) + .cloned() + .collect(); + if participants_with_valid_attestation.len() != participants.len() { + let participants_with_valid_attestation = Participants::init( + participants.next_id(), + participants_with_valid_attestation, + ); + TeeValidationResult::Partial { + participants_with_valid_attestation, + } + } else { + TeeValidationResult::Full + } + } + pub fn vote( + &mut self, + code_hash: MpcDockerImageHash, + participant: &AuthenticatedParticipantId, + ) -> u64 { + self.votes.vote(code_hash.clone(), participant) + } + pub fn get_allowed_mpc_docker_image_hashes( + &self, + tee_upgrade_deadline_duration: Duration, + ) -> Vec { + self.get_allowed_mpc_docker_images(tee_upgrade_deadline_duration) + .into_iter() + .map(|entry| entry.image_hash) + .collect() + } + pub fn get_allowed_mpc_docker_images( + &self, + tee_upgrade_deadline_duration: Duration, + ) -> Vec { + self.allowed_docker_image_hashes.get(tee_upgrade_deadline_duration) + } + pub fn whitelist_tee_proposal( + &mut self, + tee_proposal: MpcDockerImageHash, + tee_upgrade_deadline_duration: Duration, + ) { + self.votes.clear_votes(); + self.allowed_launcher_compose_hashes + .push( + AllowedDockerImageHashes::get_docker_compose_hash( + tee_proposal.clone(), + ), + ); + self.allowed_docker_image_hashes + .insert(tee_proposal, tee_upgrade_deadline_duration); + } + /// Removes TEE information for nodes that are not in the provided participants list. + /// Used to clean up storage after a resharing concludes. + pub fn clean_non_participants(&mut self, participants: &Participants) { + let active_tls_keys: HashSet<&near_sdk::PublicKey> = participants + .participants() + .iter() + .map(|(_, _, p_info)| &p_info.sign_pk) + .collect(); + let stale_keys: Vec = self + .stored_attestations + .keys() + .filter(|tls_pk| !active_tls_keys.contains(*tls_pk)) + .cloned() + .collect(); + for tls_pk in stale_keys { + self.stored_attestations.remove(&tls_pk); + } + } + /// Returns the list of accounts that currently have TEE attestations stored. + /// Note: This may include accounts that are no longer active protocol participants. + pub fn get_tee_accounts(&self) -> Vec { + self.stored_attestations + .values() + .map(|node_attestation| node_attestation.node_id.clone()) + .collect() + } + /// Find a NodeId by its TLS public key. + pub fn find_node_id_by_tls_key( + &self, + tls_public_key: &near_sdk::PublicKey, + ) -> Option { + self.stored_attestations + .get(tls_public_key) + .map(|node_attestation| node_attestation.node_id.clone()) + } + /// Returns Ok(()) if the caller has at least one participant entry + /// whose TLS key matches an attested node belonging to the caller account. + /// + /// Handles multiple participants per account and supports legacy mock nodes. + pub(crate) fn is_caller_an_attested_participant( + &self, + participants: &Participants, + ) -> Result<(), AttestationCheckError> { + let signer_pk = env::signer_account_pk(); + let signer_id = env::signer_account_id().as_v2_account_id(); + let info = participants + .info(&signer_id) + .ok_or(AttestationCheckError::CallerNotParticipant)?; + let attestation = self + .stored_attestations + .get(&info.sign_pk) + .ok_or(AttestationCheckError::AttestationNotFound)?; + if attestation.node_id.account_id != signer_id { + return Err(AttestationCheckError::AttestationOwnerMismatch); + } + if let Some(node_pk) = &attestation.node_id.account_public_key { + if node_pk != &signer_pk { + return Err(AttestationCheckError::AttestationKeyMismatch); + } + } + Ok(()) + } + } + pub(crate) enum AttestationCheckError { + CallerNotParticipant, + AttestationNotFound, + AttestationOwnerMismatch, + AttestationKeyMismatch, + } + #[automatically_derived] + impl ::core::fmt::Debug for AttestationCheckError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + AttestationCheckError::CallerNotParticipant => { + "CallerNotParticipant" + } + AttestationCheckError::AttestationNotFound => { + "AttestationNotFound" + } + AttestationCheckError::AttestationOwnerMismatch => { + "AttestationOwnerMismatch" + } + AttestationCheckError::AttestationKeyMismatch => { + "AttestationKeyMismatch" + } + }, + ) + } + } + } +} +pub mod update { + use std::collections::BTreeMap; + use std::hash::Hash; + use crate::{ + dto_mapping::IntoInterfaceType, errors::{ConversionError, Error}, + primitives::participants::Participants, storage_keys::StorageKey, + }; + use borsh::{self, BorshDeserialize, BorshSerialize}; + use contract_interface::types::UpdateHash; + use derive_more::Deref; + use near_account_id::AccountId; + use near_sdk::{ + env, near, serde::{Deserialize, Serialize}, + store::IterableMap, Gas, NearToken, Promise, + }; + pub struct UpdateId(pub(crate) u64); + #[automatically_derived] + impl ::core::marker::Copy for UpdateId {} + #[automatically_derived] + impl ::core::clone::Clone for UpdateId { + #[inline] + fn clone(&self) -> UpdateId { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::default::Default for UpdateId { + #[inline] + fn default() -> UpdateId { + UpdateId(::core::default::Default::default()) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for UpdateId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "UpdateId", &&self.0) + } + } + impl borsh::de::BorshDeserialize for UpdateId { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self(borsh::BorshDeserialize::deserialize_reader(reader)?)) + } + } + impl borsh::ser::BorshSerialize for UpdateId { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.0, writer)?; + Ok(()) + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for UpdateId { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "UpdateId", + &self.0, + ) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for UpdateId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = UpdateId; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "tuple struct UpdateId", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private228::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: u64 = ::deserialize( + __e, + )?; + _serde::__private228::Ok(UpdateId(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct UpdateId with 1 element", + ), + ); + } + }; + _serde::__private228::Ok(UpdateId(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "UpdateId", + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for UpdateId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for UpdateId { + #[inline] + fn eq(&self, other: &UpdateId) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for UpdateId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for UpdateId { + #[inline] + fn partial_cmp( + &self, + other: &UpdateId, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for UpdateId { + #[inline] + fn cmp(&self, other: &UpdateId) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::hash::Hash for UpdateId { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[allow(unreachable_code)] + #[automatically_derived] + impl derive_more::with_trait::Deref for UpdateId { + type Target = u64; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl UpdateId { + pub fn generate(&mut self) -> Self { + let id = self.0; + self.0 += 1; + Self(id) + } + } + impl From for UpdateId { + fn from(id: u64) -> Self { + Self(id) + } + } + pub enum Update { + Contract(Vec), + Config(contract_interface::types::Config), + } + #[automatically_derived] + impl ::core::clone::Clone for Update { + #[inline] + fn clone(&self) -> Update { + match self { + Update::Contract(__self_0) => { + Update::Contract(::core::clone::Clone::clone(__self_0)) + } + Update::Config(__self_0) => { + Update::Config(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Update { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Update::Contract(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Contract", + &__self_0, + ) + } + Update::Config(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Config", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Update {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Update { + #[inline] + fn eq(&self, other: &Update) -> bool { + let __self_discr = ::core::intrinsics::discriminant_value(self); + let __arg1_discr = ::core::intrinsics::discriminant_value(other); + __self_discr == __arg1_discr + && match (self, other) { + (Update::Contract(__self_0), Update::Contract(__arg1_0)) => { + __self_0 == __arg1_0 + } + (Update::Config(__self_0), Update::Config(__arg1_0)) => { + __self_0 == __arg1_0 + } + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Update { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + Update::Contract(ref __field0) => { + _serde::Serializer::serialize_newtype_variant( + __serializer, + "Update", + 0u32, + "Contract", + __field0, + ) + } + Update::Config(ref __field0) => { + _serde::Serializer::serialize_newtype_variant( + __serializer, + "Update", + 1u32, + "Config", + __field0, + ) + } + } + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Update { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => { + _serde::__private228::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "Contract" => _serde::__private228::Ok(__Field::__field0), + "Config" => _serde::__private228::Ok(__Field::__field1), + _ => { + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"Contract" => _serde::__private228::Ok(__Field::__field0), + b"Config" => _serde::__private228::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private228::from_utf8_lossy( + __value, + ); + _serde::__private228::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Update; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "enum Update", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::__private228::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Vec, + >(__variant), + Update::Contract, + ) + } + (__Field::__field1, __variant) => { + _serde::__private228::Result::map( + _serde::de::VariantAccess::newtype_variant::< + contract_interface::types::Config, + >(__variant), + Update::Config, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &["Contract", "Config"]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "Update", + VARIANTS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl borsh::ser::BorshSerialize for Update { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + let variant_idx: u8 = match self { + Update::Contract(..) => 0u8, + Update::Config(..) => 1u8, + }; + writer.write_all(&variant_idx.to_le_bytes())?; + match self { + Update::Contract(id0) => { + borsh::BorshSerialize::serialize(id0, writer)?; + } + Update::Config(id0) => { + borsh::BorshSerialize::serialize(id0, writer)?; + } + } + Ok(()) + } + } + impl borsh::de::BorshDeserialize for Update { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + let tag = ::deserialize_reader(reader)?; + ::deserialize_variant(reader, tag) + } + } + impl borsh::de::EnumExt for Update { + fn deserialize_variant<__R: borsh::io::Read>( + reader: &mut __R, + variant_tag: u8, + ) -> ::core::result::Result { + let mut return_value = if variant_tag == 0u8 { + Update::Contract(borsh::BorshDeserialize::deserialize_reader(reader)?) + } else if variant_tag == 1u8 { + Update::Config(borsh::BorshDeserialize::deserialize_reader(reader)?) + } else { + return Err( + borsh::io::Error::new( + borsh::io::ErrorKind::InvalidData, + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Unexpected variant tag: {0:?}", variant_tag), + ); + res + }), + ), + ) + }; + Ok(return_value) + } + } + pub struct ProposeUpdateArgs { + pub code: Option>, + pub config: Option, + } + #[automatically_derived] + impl ::core::clone::Clone for ProposeUpdateArgs { + #[inline] + fn clone(&self) -> ProposeUpdateArgs { + ProposeUpdateArgs { + code: ::core::clone::Clone::clone(&self.code), + config: ::core::clone::Clone::clone(&self.config), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ProposeUpdateArgs { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "ProposeUpdateArgs", + "code", + &self.code, + "config", + &&self.config, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ProposeUpdateArgs {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ProposeUpdateArgs { + #[inline] + fn eq(&self, other: &ProposeUpdateArgs) -> bool { + self.code == other.code && self.config == other.config + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ProposeUpdateArgs { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "ProposeUpdateArgs", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "code", + &self.code, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "config", + &self.config, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ProposeUpdateArgs { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "code" => _serde::__private228::Ok(__Field::__field0), + "config" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"code" => _serde::__private228::Ok(__Field::__field0), + b"config" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ProposeUpdateArgs; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct ProposeUpdateArgs", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Option>, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ProposeUpdateArgs with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct ProposeUpdateArgs with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(ProposeUpdateArgs { + code: __field0, + config: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option< + Option>, + > = _serde::__private228::None; + let mut __field1: _serde::__private228::Option< + Option, + > = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("code"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option>, + >(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("config"), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("code")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("config")? + } + }; + _serde::__private228::Ok(ProposeUpdateArgs { + code: __field0, + config: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["code", "config"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ProposeUpdateArgs", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl borsh::ser::BorshSerialize for ProposeUpdateArgs { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.code, writer)?; + borsh::BorshSerialize::serialize(&self.config, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for ProposeUpdateArgs { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + code: borsh::BorshDeserialize::deserialize_reader(reader)?, + config: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + impl TryFrom for Update { + type Error = Error; + fn try_from(value: ProposeUpdateArgs) -> Result { + let ProposeUpdateArgs { code, config } = value; + let update = match (code, config) { + (Some(contract), None) => Update::Contract(contract), + (None, Some(config)) => Update::Config(config), + (Some(_), Some(_)) => { + return Err( + ConversionError::DataConversion + .message( + "Code and config updates are not allowed at the same time", + ), + ); + } + _ => { + return Err( + ConversionError::DataConversion + .message( + "Expected either code or config update, received none of them", + ), + ); + } + }; + Ok(update) + } + } + pub(crate) struct UpdateEntry { + pub(super) update: Update, + pub(super) bytes_used: u128, + } + #[automatically_derived] + impl ::core::clone::Clone for UpdateEntry { + #[inline] + fn clone(&self) -> UpdateEntry { + UpdateEntry { + update: ::core::clone::Clone::clone(&self.update), + bytes_used: ::core::clone::Clone::clone(&self.bytes_used), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for UpdateEntry { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "UpdateEntry", + "update", + &self.update, + "bytes_used", + &&self.bytes_used, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for UpdateEntry {} + #[automatically_derived] + impl ::core::cmp::PartialEq for UpdateEntry { + #[inline] + fn eq(&self, other: &UpdateEntry) -> bool { + self.update == other.update && self.bytes_used == other.bytes_used + } + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for UpdateEntry { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "UpdateEntry", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "update", + &self.update, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "bytes_used", + &self.bytes_used, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for UpdateEntry { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private228::Ok(__Field::__field0), + 1u64 => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + "update" => _serde::__private228::Ok(__Field::__field0), + "bytes_used" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private228::Result + where + __E: _serde::de::Error, + { + match __value { + b"update" => _serde::__private228::Ok(__Field::__field0), + b"bytes_used" => _serde::__private228::Ok(__Field::__field1), + _ => _serde::__private228::Ok(__Field::__ignore), + } + } + } + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private228::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private228::PhantomData, + lifetime: _serde::__private228::PhantomData<&'de ()>, + } + #[automatically_derived] + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = UpdateEntry; + fn expecting( + &self, + __formatter: &mut _serde::__private228::Formatter, + ) -> _serde::__private228::fmt::Result { + _serde::__private228::Formatter::write_str( + __formatter, + "struct UpdateEntry", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Update, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct UpdateEntry with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + u128, + >(&mut __seq)? { + _serde::__private228::Some(__value) => __value, + _serde::__private228::None => { + return _serde::__private228::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct UpdateEntry with 2 elements", + ), + ); + } + }; + _serde::__private228::Ok(UpdateEntry { + update: __field0, + bytes_used: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private228::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private228::Option = _serde::__private228::None; + let mut __field1: _serde::__private228::Option = _serde::__private228::None; + while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< + __Field, + >(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private228::Option::is_some(&__field0) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field("update"), + ); + } + __field0 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private228::Option::is_some(&__field1) { + return _serde::__private228::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "bytes_used", + ), + ); + } + __field1 = _serde::__private228::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private228::Some(__field0) => __field0, + _serde::__private228::None => { + _serde::__private228::de::missing_field("update")? + } + }; + let __field1 = match __field1 { + _serde::__private228::Some(__field1) => __field1, + _serde::__private228::None => { + _serde::__private228::de::missing_field("bytes_used")? + } + }; + _serde::__private228::Ok(UpdateEntry { + update: __field0, + bytes_used: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["update", "bytes_used"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "UpdateEntry", + FIELDS, + __Visitor { + marker: _serde::__private228::PhantomData::, + lifetime: _serde::__private228::PhantomData, + }, + ) + } + } + }; + impl borsh::ser::BorshSerialize for UpdateEntry { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.update, writer)?; + borsh::BorshSerialize::serialize(&self.bytes_used, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for UpdateEntry { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + update: borsh::BorshDeserialize::deserialize_reader(reader)?, + bytes_used: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + pub(super) struct UpdateVotes { + pub(super) votes: BTreeMap, + pub(super) updates: BTreeMap, + } + #[automatically_derived] + impl ::core::clone::Clone for UpdateVotes { + #[inline] + fn clone(&self) -> UpdateVotes { + UpdateVotes { + votes: ::core::clone::Clone::clone(&self.votes), + updates: ::core::clone::Clone::clone(&self.updates), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for UpdateVotes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "UpdateVotes", + "votes", + &self.votes, + "updates", + &&self.updates, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for UpdateVotes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for UpdateVotes { + #[inline] + fn eq(&self, other: &UpdateVotes) -> bool { + self.votes == other.votes && self.updates == other.updates + } + } + #[borsh(crate = ":: near_sdk :: borsh")] + pub struct ProposedUpdates { + pub(super) vote_by_participant: IterableMap, + pub(super) entries: IterableMap, + pub(super) id: UpdateId, + } + #[automatically_derived] + impl ::core::fmt::Debug for ProposedUpdates { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "ProposedUpdates", + "vote_by_participant", + &self.vote_by_participant, + "entries", + &self.entries, + "id", + &&self.id, + ) + } + } + impl ::near_sdk::borsh::ser::BorshSerialize for ProposedUpdates { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize( + &self.vote_by_participant, + writer, + )?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.entries, writer)?; + ::near_sdk::borsh::BorshSerialize::serialize(&self.id, writer)?; + Ok(()) + } + } + impl ::near_sdk::borsh::de::BorshDeserialize for ProposedUpdates { + fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + vote_by_participant: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + entries: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + impl Default for ProposedUpdates { + fn default() -> Self { + Self { + vote_by_participant: IterableMap::new( + StorageKey::ProposedUpdatesVotesV2, + ), + entries: IterableMap::new(StorageKey::ProposedUpdatesEntriesV2), + id: UpdateId::default(), + } + } + } + impl ProposedUpdates { + pub fn required_deposit(update: &Update) -> NearToken { + required_deposit(bytes_used(update)) + } + /// Propose an update given the new contract code and/or config. + pub fn propose(&mut self, update: Update) -> UpdateId { + let bytes_used = bytes_used(&update); + let id = self.id.generate(); + self.entries.insert(id, UpdateEntry { update, bytes_used }); + id + } + /// Records a vote by [`AccountId`] for the update with the given [`UpdateId`]. + /// + /// If the voter has already voted for a different update, that vote is automatically removed + /// (each participant can only vote for one update at a time). + /// + /// Returns `None` if the [`UpdateId`] doesn't exist. + pub fn vote(&mut self, id: &UpdateId, voter: AccountId) -> Option<()> { + self.remove_vote(&voter); + if !self.entries.contains_key(id) { + env::log_str( + &::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("no update with id {0:?} exists", id), + ); + res + }), + ); + return None; + } + self.vote_by_participant.insert(voter.clone(), *id); + Some(()) + } + pub fn do_update(&mut self, id: &UpdateId, gas: Gas) -> Option { + let entry = self.entries.remove(id)?; + self.entries.clear(); + self.vote_by_participant.clear(); + let mut promise = Promise::new(env::current_account_id()); + match entry.update { + Update::Contract(code) => { + promise = promise + .deploy_contract(code) + .function_call( + "migrate", + Vec::new(), + NearToken::from_near(0), + gas, + ); + } + Update::Config(config) => { + let new_config_gas_value = Gas::from_tgas( + config.contract_upgrade_deposit_tera_gas, + ); + promise = promise + .function_call( + "update_config", + serde_json::to_vec(&(&config,)).unwrap(), + NearToken::from_near(0), + new_config_gas_value, + ); + } + } + Some(promise) + } + /// Removes the vote for [`AccountId`]. + pub fn remove_vote(&mut self, voter: &AccountId) { + self.vote_by_participant.remove(voter); + } + /// Removes votes from the specified accounts. + pub fn remove_votes(&mut self, accounts_to_remove: &[AccountId]) { + accounts_to_remove.iter().for_each(|account| self.remove_vote(account)); + } + /// Removes votes from accounts that are not participants. + pub fn remove_non_participant_votes(&mut self, participants: &Participants) { + let non_participants: Vec = self + .vote_by_participant + .keys() + .filter(|voter| !participants.is_participant(voter)) + .cloned() + .collect(); + self.remove_votes(&non_participants); + } + pub(super) fn all_updates(&self) -> UpdateVotes { + let votes = self + .vote_by_participant + .iter() + .map(|(account, update_id)| (account.clone(), *update_id)) + .collect(); + let updates = self + .entries + .iter() + .map(|(update_id, entry)| (*update_id, (&entry.update).into_dto_type())) + .collect(); + UpdateVotes { votes, updates } + } + } + fn bytes_used(update: &Update) -> u128 { + let mut bytes_used = std::mem::size_of::() as u128; + bytes_used += 128 * std::mem::size_of::() as u128; + match update { + Update::Contract(code) => { + bytes_used += code.len() as u128; + } + Update::Config(config) => { + let bytes = serde_json::to_vec(&config).unwrap(); + bytes_used += bytes.len() as u128; + } + } + bytes_used + } + fn required_deposit(bytes_used: u128) -> NearToken { + env::storage_byte_cost().saturating_mul(bytes_used) + } +} +pub mod v3_0_2_state { + //! ## Overview + //! This module stores the previous contract state—the one you want to migrate from. + //! The goal is to describe the data layout _exactly_ as it existed before. + //! + //! ## Guideline + //! In theory, you could copy-paste every struct from the specific commit you're migrating from. + //! However, this approach (a) requires manual effort from a developer and (b) increases the binary size. + //! A better approach: only copy the structures that have changed and import the rest from the existing codebase. + use borsh::{BorshDeserialize, BorshSerialize}; + use mpc_attestation::attestation::Attestation; + use mpc_primitives::hash::LauncherDockerComposeHash; + use near_account_id::AccountId; + use near_sdk::{env, store::{IterableMap, LookupMap}}; + use std::collections::HashSet; + use crate::{ + node_migrations::NodeMigrations, + primitives::{ckd::CKDRequest, signature::{SignatureRequest, YieldIndex}}, + state::ProtocolContractState, + tee::{ + proposal::{AllowedDockerImageHashes, CodeHashesVotes}, + tee_state::NodeId, + }, + update::{Update, UpdateId}, + }; + struct Config { + /// If a key event attempt has not successfully completed within this many blocks, + /// it is considered failed. + pub key_event_timeout_blocks: u64, + /// The grace period duration for expiry of old mpc image hashes once a new one is added. + pub tee_upgrade_deadline_duration_seconds: u64, + } + #[automatically_derived] + impl ::core::fmt::Debug for Config { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Config", + "key_event_timeout_blocks", + &self.key_event_timeout_blocks, + "tee_upgrade_deadline_duration_seconds", + &&self.tee_upgrade_deadline_duration_seconds, + ) + } + } + impl borsh::ser::BorshSerialize for Config { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.key_event_timeout_blocks, writer)?; + borsh::BorshSerialize::serialize( + &self.tee_upgrade_deadline_duration_seconds, + writer, + )?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for Config { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + key_event_timeout_blocks: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + tee_upgrade_deadline_duration_seconds: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + impl From for crate::config::Config { + fn from(value: Config) -> Self { + crate::config::Config { + key_event_timeout_blocks: value.key_event_timeout_blocks, + tee_upgrade_deadline_duration_seconds: value + .tee_upgrade_deadline_duration_seconds, + ..Default::default() + } + } + } + /// Old version of [`UpdateEntry`] that included votes. + struct UpdateEntry { + update: Update, + votes: HashSet, + bytes_used: u128, + } + #[automatically_derived] + impl ::core::clone::Clone for UpdateEntry { + #[inline] + fn clone(&self) -> UpdateEntry { + UpdateEntry { + update: ::core::clone::Clone::clone(&self.update), + votes: ::core::clone::Clone::clone(&self.votes), + bytes_used: ::core::clone::Clone::clone(&self.bytes_used), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for UpdateEntry { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "UpdateEntry", + "update", + &self.update, + "votes", + &self.votes, + "bytes_used", + &&self.bytes_used, + ) + } + } + impl borsh::ser::BorshSerialize for UpdateEntry { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.update, writer)?; + borsh::BorshSerialize::serialize(&self.votes, writer)?; + borsh::BorshSerialize::serialize(&self.bytes_used, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for UpdateEntry { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + update: borsh::BorshDeserialize::deserialize_reader(reader)?, + votes: borsh::BorshDeserialize::deserialize_reader(reader)?, + bytes_used: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + /// Old version of [`ProposedUpdates`] that used the old [`UpdateEntry`] with votes. + pub struct ProposedUpdates { + vote_by_participant: IterableMap, + entries: IterableMap, + id: UpdateId, + } + #[automatically_derived] + impl ::core::fmt::Debug for ProposedUpdates { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "ProposedUpdates", + "vote_by_participant", + &self.vote_by_participant, + "entries", + &self.entries, + "id", + &&self.id, + ) + } + } + impl borsh::ser::BorshSerialize for ProposedUpdates { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.vote_by_participant, writer)?; + borsh::BorshSerialize::serialize(&self.entries, writer)?; + borsh::BorshSerialize::serialize(&self.id, writer)?; + Ok(()) + } + } + impl borsh::de::BorshDeserialize for ProposedUpdates { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + vote_by_participant: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + entries: borsh::BorshDeserialize::deserialize_reader(reader)?, + id: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + impl From for crate::update::ProposedUpdates { + fn from(old: ProposedUpdates) -> Self { + if !old.entries.is_empty() { + { + ::core::panicking::panic_fmt( + format_args!( + "Migration error: Found {0} pending update entries. Expected empty state as do_update() clears entries.", + old.entries.len(), + ), + ); + }; + } + if !old.vote_by_participant.is_empty() { + { + ::core::panicking::panic_fmt( + format_args!( + "Migration error: Found {0} pending votes. Expected empty state as do_update() clears votes.", + old.vote_by_participant.len(), + ), + ); + }; + } + Self { + vote_by_participant: IterableMap::new( + crate::storage_keys::StorageKey::ProposedUpdatesVotesV2, + ), + entries: IterableMap::new( + crate::storage_keys::StorageKey::ProposedUpdatesEntriesV2, + ), + id: old.id, + } + } + } + struct TeeState { + _allowed_docker_image_hashes: AllowedDockerImageHashes, + _allowed_launcher_compose_hashes: Vec, + _votes: CodeHashesVotes, + participants_attestations: IterableMap< + near_sdk::PublicKey, + (NodeId, Attestation), + >, + } + #[automatically_derived] + impl ::core::fmt::Debug for TeeState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "TeeState", + "_allowed_docker_image_hashes", + &self._allowed_docker_image_hashes, + "_allowed_launcher_compose_hashes", + &self._allowed_launcher_compose_hashes, + "_votes", + &self._votes, + "participants_attestations", + &&self.participants_attestations, + ) + } + } + impl borsh::de::BorshDeserialize for TeeState { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + _allowed_docker_image_hashes: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + _allowed_launcher_compose_hashes: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + _votes: borsh::BorshDeserialize::deserialize_reader(reader)?, + participants_attestations: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + pub struct MpcContract { + protocol_state: ProtocolContractState, + pending_signature_requests: LookupMap, + pending_ckd_requests: LookupMap, + proposed_updates: ProposedUpdates, + config: Config, + tee_state: TeeState, + accept_requests: bool, + node_migrations: NodeMigrations, + } + #[automatically_derived] + impl ::core::fmt::Debug for MpcContract { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "protocol_state", + "pending_signature_requests", + "pending_ckd_requests", + "proposed_updates", + "config", + "tee_state", + "accept_requests", + "node_migrations", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.protocol_state, + &self.pending_signature_requests, + &self.pending_ckd_requests, + &self.proposed_updates, + &self.config, + &self.tee_state, + &self.accept_requests, + &&self.node_migrations, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "MpcContract", + names, + values, + ) + } + } + impl borsh::de::BorshDeserialize for MpcContract { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + protocol_state: borsh::BorshDeserialize::deserialize_reader(reader)?, + pending_signature_requests: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + pending_ckd_requests: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + proposed_updates: borsh::BorshDeserialize::deserialize_reader(reader)?, + config: borsh::BorshDeserialize::deserialize_reader(reader)?, + tee_state: borsh::BorshDeserialize::deserialize_reader(reader)?, + accept_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, + node_migrations: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + impl From for crate::MpcContract { + fn from(value: MpcContract) -> Self { + let protocol_state = value.protocol_state; + let crate::ProtocolContractState::Running(running_state) = &protocol_state + else { + env::panic_str("Contract must be in running state when migrating."); + }; + let mut previous_tee_state = value.tee_state; + let threshold_parameters = &running_state.parameters.participants(); + let tee_state = crate::TeeState::with_mocked_participant_attestations( + threshold_parameters, + ); + Self { + protocol_state, + pending_signature_requests: value.pending_signature_requests, + pending_ckd_requests: value.pending_ckd_requests, + proposed_updates: value.proposed_updates.into(), + config: value.config.into(), + tee_state, + accept_requests: value.accept_requests, + node_migrations: value.node_migrations, + } + } + } +} +pub mod v3_2_0_state { + //! ## Overview + //! This module stores the previous contract state—the one you want to migrate from. + //! The goal is to describe the data layout _exactly_ as it existed before. + //! + //! ## Guideline + //! In theory, you could copy-paste every struct from the specific commit you're migrating from. + //! However, this approach (a) requires manual effort from a developer and (b) increases the binary size. + //! A better approach: only copy the structures that have changed and import the rest from the existing codebase. + use borsh::BorshDeserialize; + use mpc_attestation::attestation::Attestation; + use mpc_primitives::hash::LauncherDockerComposeHash; + use near_sdk::{env, store::{IterableMap, LookupMap}}; + use crate::{ + node_migrations::NodeMigrations, + primitives::{ckd::CKDRequest, signature::{SignatureRequest, YieldIndex}}, + state::ProtocolContractState, + tee::{ + proposal::{AllowedDockerImageHashes, CodeHashesVotes}, + tee_state::NodeId, + }, + update::ProposedUpdates, Config, + }; + struct TeeState { + _allowed_docker_image_hashes: AllowedDockerImageHashes, + _allowed_launcher_compose_hashes: Vec, + _votes: CodeHashesVotes, + participants_attestations: IterableMap< + near_sdk::PublicKey, + (NodeId, Attestation), + >, + } + #[automatically_derived] + impl ::core::fmt::Debug for TeeState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "TeeState", + "_allowed_docker_image_hashes", + &self._allowed_docker_image_hashes, + "_allowed_launcher_compose_hashes", + &self._allowed_launcher_compose_hashes, + "_votes", + &self._votes, + "participants_attestations", + &&self.participants_attestations, + ) + } + } + impl borsh::de::BorshDeserialize for TeeState { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + _allowed_docker_image_hashes: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + _allowed_launcher_compose_hashes: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + _votes: borsh::BorshDeserialize::deserialize_reader(reader)?, + participants_attestations: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + }) + } + } + pub struct MpcContract { + protocol_state: ProtocolContractState, + pending_signature_requests: LookupMap, + pending_ckd_requests: LookupMap, + proposed_updates: ProposedUpdates, + config: Config, + tee_state: TeeState, + accept_requests: bool, + node_migrations: NodeMigrations, + } + #[automatically_derived] + impl ::core::fmt::Debug for MpcContract { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "protocol_state", + "pending_signature_requests", + "pending_ckd_requests", + "proposed_updates", + "config", + "tee_state", + "accept_requests", + "node_migrations", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.protocol_state, + &self.pending_signature_requests, + &self.pending_ckd_requests, + &self.proposed_updates, + &self.config, + &self.tee_state, + &self.accept_requests, + &&self.node_migrations, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "MpcContract", + names, + values, + ) + } + } + impl borsh::de::BorshDeserialize for MpcContract { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + protocol_state: borsh::BorshDeserialize::deserialize_reader(reader)?, + pending_signature_requests: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + pending_ckd_requests: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + proposed_updates: borsh::BorshDeserialize::deserialize_reader(reader)?, + config: borsh::BorshDeserialize::deserialize_reader(reader)?, + tee_state: borsh::BorshDeserialize::deserialize_reader(reader)?, + accept_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, + node_migrations: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } + } + impl From for crate::MpcContract { + fn from(value: MpcContract) -> Self { + let protocol_state = value.protocol_state; + let crate::ProtocolContractState::Running(running_state) = &protocol_state + else { + env::panic_str("Contract must be in running state when migrating."); + }; + let mut previous_tee_state = value.tee_state; + previous_tee_state.participants_attestations.clear(); + let threshold_parameters = &running_state.parameters.participants(); + let tee_state = crate::TeeState::with_mocked_participant_attestations( + threshold_parameters, + ); + Self { + protocol_state, + pending_signature_requests: value.pending_signature_requests, + pending_ckd_requests: value.pending_ckd_requests, + proposed_updates: value.proposed_updates.into(), + config: value.config.into(), + tee_state, + accept_requests: value.accept_requests, + node_migrations: value.node_migrations, + } + } + } +} +mod dto_mapping { + //! This module provides convenience methods to map contract interface types + //! from [`contract_interface::types`] to internal types. + //! + //! These types are mapped with the [IntoContractType] trait. We can not use [`From`] + //! and [`Into`] due to the [*orphan rule*](https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules). + use contract_interface::types as dtos; + use mpc_attestation::{ + attestation::{ + Attestation, DstackAttestation, MockAttestation, VerifiedAttestation, + }, + collateral::{Collateral, QuoteCollateralV3}, + EventLog, TcbInfo, + }; + use k256::{ + elliptic_curve::sec1::{FromEncodedPoint as _, ToEncodedPoint as _}, + EncodedPoint, + }; + use curve25519_dalek::edwards::CompressedEdwardsY; + use near_account_id::AccountId; + use near_sdk::env::sha256_array; + use crate::{ + config::Config, crypto_shared::k256_types, update::{ProposedUpdates, Update}, + }; + use crate::errors::{ConversionError, Error}; + pub(crate) trait IntoContractType { + fn into_contract_type(self) -> ContractType; + } + pub(crate) trait IntoInterfaceType { + fn into_dto_type(self) -> InterfaceType; + } + #[allow(dead_code)] + pub(crate) trait TryIntoContractType { + type Error; + fn try_into_contract_type(self) -> Result; + } + pub(crate) trait TryIntoInterfaceType { + type Error; + fn try_into_dto_type(self) -> Result; + } + impl IntoContractType for dtos::Attestation { + fn into_contract_type(self) -> Attestation { + match self { + dtos::Attestation::Dstack(dstack_attestation) => { + Attestation::Dstack(dstack_attestation.into_contract_type()) + } + dtos::Attestation::Mock(mock_attestation) => { + Attestation::Mock(mock_attestation.into_contract_type()) + } + } + } + } + impl IntoContractType for dtos::MockAttestation { + fn into_contract_type(self) -> MockAttestation { + match self { + dtos::MockAttestation::Valid => MockAttestation::Valid, + dtos::MockAttestation::Invalid => MockAttestation::Invalid, + dtos::MockAttestation::WithConstraints { + mpc_docker_image_hash, + launcher_docker_compose_hash, + expiry_timestamp_seconds, + } => { + MockAttestation::WithConstraints { + mpc_docker_image_hash: mpc_docker_image_hash.map(Into::into), + launcher_docker_compose_hash: launcher_docker_compose_hash + .map(Into::into), + expiry_timestamp_seconds, + } + } + } + } + } + impl IntoContractType for dtos::DstackAttestation { + fn into_contract_type(self) -> DstackAttestation { + let dtos::DstackAttestation { quote, collateral, tcb_info } = self; + DstackAttestation { + quote: quote.into(), + collateral: collateral.into_contract_type(), + tcb_info: tcb_info.into_contract_type(), + } + } + } + impl IntoContractType for dtos::Collateral { + fn into_contract_type(self) -> Collateral { + let dtos::Collateral { + pck_crl_issuer_chain, + root_ca_crl, + pck_crl, + tcb_info_issuer_chain, + tcb_info, + tcb_info_signature, + qe_identity_issuer_chain, + qe_identity, + qe_identity_signature, + } = self; + Collateral::from(QuoteCollateralV3 { + pck_crl_issuer_chain, + root_ca_crl, + pck_crl, + tcb_info_issuer_chain, + tcb_info, + tcb_info_signature, + qe_identity_issuer_chain, + qe_identity, + qe_identity_signature, + }) + } + } + impl IntoContractType for dtos::TcbInfo { + fn into_contract_type(self) -> TcbInfo { + let dtos::TcbInfo { + mrtd, + rtmr0, + rtmr1, + rtmr2, + rtmr3, + os_image_hash, + compose_hash, + device_id, + app_compose, + event_log, + } = self; + let event_log = event_log + .into_iter() + .map(IntoContractType::into_contract_type) + .collect(); + TcbInfo { + mrtd, + rtmr0, + rtmr1, + rtmr2, + rtmr3, + os_image_hash, + compose_hash, + device_id, + app_compose, + event_log, + } + } + } + impl IntoContractType for dtos::EventLog { + fn into_contract_type(self) -> EventLog { + let dtos::EventLog { imr, event_type, digest, event, event_payload } = self; + EventLog { + imr, + event_type, + digest, + event, + event_payload, + } + } + } + impl IntoInterfaceType for VerifiedAttestation { + fn into_dto_type(self) -> dtos::VerifiedAttestation { + match self { + VerifiedAttestation::Mock(mock_attestation) => { + dtos::VerifiedAttestation::Mock(mock_attestation.into_dto_type()) + } + VerifiedAttestation::Dstack(validated_dstack_attestation) => { + dtos::VerifiedAttestation::Dtack(dtos::VerifiedDstackAttestation { + mpc_image_hash: validated_dstack_attestation + .mpc_image_hash + .into(), + launcher_compose_hash: validated_dstack_attestation + .launcher_compose_hash + .into(), + expiry_timestamp_seconds: validated_dstack_attestation + .expiration_timestamp_seconds, + }) + } + } + } + } + impl IntoInterfaceType for MockAttestation { + fn into_dto_type(self) -> dtos::MockAttestation { + match self { + MockAttestation::Valid => dtos::MockAttestation::Valid, + MockAttestation::Invalid => dtos::MockAttestation::Invalid, + MockAttestation::WithConstraints { + mpc_docker_image_hash, + launcher_docker_compose_hash, + expiry_timestamp_seconds, + } => { + dtos::MockAttestation::WithConstraints { + mpc_docker_image_hash: mpc_docker_image_hash.map(Into::into), + launcher_docker_compose_hash: launcher_docker_compose_hash + .map(Into::into), + expiry_timestamp_seconds, + } + } + } + } + } + impl IntoInterfaceType for &k256_types::PublicKey { + fn into_dto_type(self) -> dtos::Secp256k1PublicKey { + let mut bytes = [0u8; 64]; + bytes.copy_from_slice(&self.to_encoded_point(false).to_bytes()[1..]); + dtos::Secp256k1PublicKey::from(bytes) + } + } + impl TryIntoContractType for dtos::Secp256k1PublicKey { + type Error = Error; + fn try_into_contract_type(self) -> Result { + let mut bytes = [0u8; 65]; + bytes[1..].copy_from_slice(&self.0); + bytes[0] = 0x4; + let point = EncodedPoint::from_bytes(bytes) + .map_err(|err| { + ConversionError::DataConversion + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Failed to get EncodedPoint: {0}", err), + ); + res + }), + ) + })?; + k256_types::PublicKey::from_encoded_point(&point) + .into_option() + .ok_or( + ConversionError::DataConversion + .message("Failed to convert EncodedPoint to PublicKey"), + ) + } + } + impl IntoInterfaceType for &CompressedEdwardsY { + fn into_dto_type(self) -> dtos::Ed25519PublicKey { + dtos::Ed25519PublicKey::from(self.to_bytes()) + } + } + impl TryIntoInterfaceType for &near_sdk::PublicKey { + type Error = Error; + fn try_into_dto_type(self) -> Result { + match self.curve_type() { + near_sdk::CurveType::ED25519 => { + let mut bytes = [0u8; 32]; + bytes.copy_from_slice(&self.as_bytes()[1..]); + Ok(dtos::Ed25519PublicKey::from(bytes)) + } + curve_type => { + Err( + ConversionError::DataConversion + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("Wrong curve type was used: {0:?}", curve_type), + ); + res + }), + ), + ) + } + } + } + } + impl IntoContractType for &dtos::Ed25519PublicKey { + fn into_contract_type(self) -> near_sdk::PublicKey { + near_sdk::PublicKey::from_parts(near_sdk::CurveType::ED25519, self.0.into()) + .unwrap() + } + } + impl IntoContractType for &dtos::Secp256k1PublicKey { + fn into_contract_type(self) -> near_sdk::PublicKey { + near_sdk::PublicKey::from_parts( + near_sdk::CurveType::SECP256K1, + self.0.into(), + ) + .unwrap() + } + } + impl IntoInterfaceType for &near_sdk::PublicKey { + fn into_dto_type(self) -> dtos::PublicKey { + match self.curve_type() { + near_sdk::CurveType::SECP256K1 => { + let mut bytes = [0u8; 64]; + bytes.copy_from_slice(&self.as_bytes()[1..]); + dtos::PublicKey::from(dtos::Secp256k1PublicKey::from(bytes)) + } + near_sdk::CurveType::ED25519 => { + let mut bytes = [0u8; 32]; + bytes.copy_from_slice(&self.as_bytes()[1..]); + dtos::PublicKey::from(dtos::Ed25519PublicKey::from(bytes)) + } + } + } + } + impl IntoInterfaceType for &AccountId { + fn into_dto_type(self) -> dtos::AccountId { + dtos::AccountId(self.clone().into()) + } + } + impl IntoInterfaceType for &Update { + fn into_dto_type(self) -> dtos::UpdateHash { + match self { + Update::Contract(code) => dtos::UpdateHash::Code(sha256_array(code)), + Update::Config(config) => { + dtos::UpdateHash::Config( + sha256_array( + serde_json::to_vec(config) + .expect("serde serialization must succeed"), + ), + ) + } + } + } + } + impl IntoInterfaceType for &ProposedUpdates { + fn into_dto_type(self) -> dtos::ProposedUpdates { + let all = self.all_updates(); + let votes = all + .votes + .into_iter() + .map(|(account, update_id)| (account.into_dto_type(), update_id.0)) + .collect(); + let updates = all + .updates + .into_iter() + .map(|(update_id, update)| (update_id.0, update)) + .collect(); + dtos::ProposedUpdates { + votes, + updates, + } + } + } + impl From for Config { + fn from(config_ext: contract_interface::types::InitConfig) -> Self { + let mut config = super::Config::default(); + if let Some(v) = config_ext.key_event_timeout_blocks { + config.key_event_timeout_blocks = v; + } + if let Some(v) = config_ext.tee_upgrade_deadline_duration_seconds { + config.tee_upgrade_deadline_duration_seconds = v; + } + if let Some(v) = config_ext.contract_upgrade_deposit_tera_gas { + config.contract_upgrade_deposit_tera_gas = v; + } + if let Some(v) = config_ext.sign_call_gas_attachment_requirement_tera_gas { + config.sign_call_gas_attachment_requirement_tera_gas = v; + } + if let Some(v) = config_ext.ckd_call_gas_attachment_requirement_tera_gas { + config.ckd_call_gas_attachment_requirement_tera_gas = v; + } + if let Some(v) = config_ext + .return_signature_and_clean_state_on_success_call_tera_gas + { + config.return_signature_and_clean_state_on_success_call_tera_gas = v; + } + if let Some(v) = config_ext + .return_ck_and_clean_state_on_success_call_tera_gas + { + config.return_ck_and_clean_state_on_success_call_tera_gas = v; + } + if let Some(v) = config_ext.fail_on_timeout_tera_gas { + config.fail_on_timeout_tera_gas = v; + } + if let Some(v) = config_ext.clean_tee_status_tera_gas { + config.clean_tee_status_tera_gas = v; + } + if let Some(v) = config_ext.cleanup_orphaned_node_migrations_tera_gas { + config.cleanup_orphaned_node_migrations_tera_gas = v; + } + if let Some(v) = config_ext.remove_non_participant_update_votes_tera_gas { + config.remove_non_participant_update_votes_tera_gas = v; + } + config + } + } + impl From<&Config> for contract_interface::types::Config { + fn from(value: &Config) -> Self { + contract_interface::types::Config { + key_event_timeout_blocks: value.key_event_timeout_blocks, + tee_upgrade_deadline_duration_seconds: value + .tee_upgrade_deadline_duration_seconds, + contract_upgrade_deposit_tera_gas: value + .contract_upgrade_deposit_tera_gas, + sign_call_gas_attachment_requirement_tera_gas: value + .sign_call_gas_attachment_requirement_tera_gas, + ckd_call_gas_attachment_requirement_tera_gas: value + .ckd_call_gas_attachment_requirement_tera_gas, + return_signature_and_clean_state_on_success_call_tera_gas: value + .return_signature_and_clean_state_on_success_call_tera_gas, + return_ck_and_clean_state_on_success_call_tera_gas: value + .return_ck_and_clean_state_on_success_call_tera_gas, + fail_on_timeout_tera_gas: value.fail_on_timeout_tera_gas, + clean_tee_status_tera_gas: value.clean_tee_status_tera_gas, + cleanup_orphaned_node_migrations_tera_gas: value + .cleanup_orphaned_node_migrations_tera_gas, + remove_non_participant_update_votes_tera_gas: value + .remove_non_participant_update_votes_tera_gas, + } + } + } + impl From for Config { + fn from(value: contract_interface::types::Config) -> Self { + Config { + key_event_timeout_blocks: value.key_event_timeout_blocks, + tee_upgrade_deadline_duration_seconds: value + .tee_upgrade_deadline_duration_seconds, + contract_upgrade_deposit_tera_gas: value + .contract_upgrade_deposit_tera_gas, + sign_call_gas_attachment_requirement_tera_gas: value + .sign_call_gas_attachment_requirement_tera_gas, + ckd_call_gas_attachment_requirement_tera_gas: value + .ckd_call_gas_attachment_requirement_tera_gas, + return_signature_and_clean_state_on_success_call_tera_gas: value + .return_signature_and_clean_state_on_success_call_tera_gas, + return_ck_and_clean_state_on_success_call_tera_gas: value + .return_ck_and_clean_state_on_success_call_tera_gas, + fail_on_timeout_tera_gas: value.fail_on_timeout_tera_gas, + clean_tee_status_tera_gas: value.clean_tee_status_tera_gas, + cleanup_orphaned_node_migrations_tera_gas: value + .cleanup_orphaned_node_migrations_tera_gas, + remove_non_participant_update_votes_tera_gas: value + .remove_non_participant_update_votes_tera_gas, + } + } + } +} +use std::{collections::BTreeMap, time::Duration}; +use crate::{ + crypto_shared::{near_public_key_to_affine_point, types::CKDResponse}, + dto_mapping::{IntoContractType, IntoInterfaceType, TryIntoInterfaceType}, + errors::{Error, RequestError}, + primitives::ckd::{CKDRequest, CKDRequestArgs}, + state::ContractNotInitialized, storage_keys::StorageKey, + tee::tee_state::{TeeQuoteStatus, TeeState}, + update::{ProposeUpdateArgs, ProposedUpdates, Update, UpdateId}, +}; +use borsh::{BorshDeserialize, BorshSerialize}; +use config::Config; +use contract_interface::types as dtos; +use crypto_shared::{ + derive_key_secp256k1, derive_tweak, + kdf::{check_ec_signature, derive_public_key_edwards_point_ed25519}, + types::{PublicKeyExtended, PublicKeyExtendedConversionError, SignatureResponse}, +}; +use errors::{ + DomainError, InvalidParameters, InvalidState, PublicKeyError, RespondError, TeeError, +}; +use k256::elliptic_curve::PrimeField; +use mpc_attestation::attestation::Attestation; +use mpc_primitives::hash::LauncherDockerComposeHash; +use near_account_id::AccountId; +use near_sdk::{ + env::{self, ed25519_verify}, + log, near_bindgen, state::ContractState, store::{IterableMap, LookupMap}, + CryptoHash, Gas, GasWeight, NearToken, Promise, PromiseError, PromiseOrValue, +}; +use node_migrations::{BackupServiceInfo, DestinationNodeInfo, NodeMigrations}; +use primitives::{ + domain::{DomainConfig, DomainId, DomainRegistry, SignatureScheme}, + key_state::{AuthenticatedParticipantId, EpochId, KeyEventId, Keyset}, + signature::{SignRequest, SignRequestArgs, SignatureRequest, YieldIndex}, + thresholds::{Threshold, ThresholdParameters}, +}; +use state::{running::RunningContractState, ProtocolContractState}; +use tee::{ + proposal::MpcDockerImageHash, + tee_state::{NodeId, ParticipantInsertion, TeeValidationResult}, +}; +use utilities::{AccountIdExtV1, AccountIdExtV2}; +/// Register used to receive data id from `promise_await_data`. +/// Note: This is an implementation constant, not a configurable policy value. +const DATA_ID_REGISTER: u64 = 0; +/// Minimum deposit required for sign requests +const MINIMUM_SIGN_REQUEST_DEPOSIT: NearToken = NearToken::from_yoctonear(1); +/// Minimum deposit required for CKD requests +const MINIMUM_CKD_REQUEST_DEPOSIT: NearToken = NearToken::from_yoctonear(1); +impl Default for MpcContract { + fn default() -> Self { + env::panic_str("Calling default not allowed."); + } +} +impl ContractState for MpcContract {} +pub struct MpcContract { + protocol_state: ProtocolContractState, + pending_signature_requests: LookupMap, + pending_ckd_requests: LookupMap, + proposed_updates: ProposedUpdates, + config: Config, + tee_state: TeeState, + accept_requests: bool, + node_migrations: NodeMigrations, +} +#[automatically_derived] +impl ::core::fmt::Debug for MpcContract { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "protocol_state", + "pending_signature_requests", + "pending_ckd_requests", + "proposed_updates", + "config", + "tee_state", + "accept_requests", + "node_migrations", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.protocol_state, + &self.pending_signature_requests, + &self.pending_ckd_requests, + &self.proposed_updates, + &self.config, + &self.tee_state, + &self.accept_requests, + &&self.node_migrations, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "MpcContract", + names, + values, + ) + } +} +impl borsh::ser::BorshSerialize for MpcContract { + fn serialize<__W: borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), borsh::io::Error> { + borsh::BorshSerialize::serialize(&self.protocol_state, writer)?; + borsh::BorshSerialize::serialize(&self.pending_signature_requests, writer)?; + borsh::BorshSerialize::serialize(&self.pending_ckd_requests, writer)?; + borsh::BorshSerialize::serialize(&self.proposed_updates, writer)?; + borsh::BorshSerialize::serialize(&self.config, writer)?; + borsh::BorshSerialize::serialize(&self.tee_state, writer)?; + borsh::BorshSerialize::serialize(&self.accept_requests, writer)?; + borsh::BorshSerialize::serialize(&self.node_migrations, writer)?; + Ok(()) + } +} +impl borsh::de::BorshDeserialize for MpcContract { + fn deserialize_reader<__R: borsh::io::Read>( + reader: &mut __R, + ) -> ::core::result::Result { + Ok(Self { + protocol_state: borsh::BorshDeserialize::deserialize_reader(reader)?, + pending_signature_requests: borsh::BorshDeserialize::deserialize_reader( + reader, + )?, + pending_ckd_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, + proposed_updates: borsh::BorshDeserialize::deserialize_reader(reader)?, + config: borsh::BorshDeserialize::deserialize_reader(reader)?, + tee_state: borsh::BorshDeserialize::deserialize_reader(reader)?, + accept_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, + node_migrations: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } +} +#[must_use] +pub struct MpcContractExt { + pub(crate) promise_or_create_on: ::near_sdk::PromiseOrValue<::near_sdk::AccountId>, + pub(crate) deposit: ::near_sdk::NearToken, + pub(crate) static_gas: ::near_sdk::Gas, + pub(crate) gas_weight: ::near_sdk::GasWeight, +} +impl MpcContractExt { + pub fn with_attached_deposit(mut self, amount: ::near_sdk::NearToken) -> Self { + self.deposit = amount; + self + } + pub fn with_static_gas(mut self, static_gas: ::near_sdk::Gas) -> Self { + self.static_gas = static_gas; + self + } + pub fn with_unused_gas_weight(mut self, gas_weight: u64) -> Self { + self.gas_weight = ::near_sdk::GasWeight(gas_weight); + self + } +} +impl MpcContract { + /// API for calling this contract's functions in a subsequent execution. + pub fn ext(account_id: ::near_sdk::AccountId) -> MpcContractExt { + MpcContractExt { + promise_or_create_on: ::near_sdk::PromiseOrValue::Value(account_id), + deposit: ::near_sdk::NearToken::from_near(0), + static_gas: ::near_sdk::Gas::from_gas(0), + gas_weight: ::near_sdk::GasWeight::default(), + } + } + pub fn ext_on(promise: ::near_sdk::Promise) -> MpcContractExt { + MpcContractExt { + promise_or_create_on: ::near_sdk::PromiseOrValue::Promise(promise), + deposit: ::near_sdk::NearToken::from_near(0), + static_gas: ::near_sdk::Gas::from_gas(0), + gas_weight: ::near_sdk::GasWeight::default(), + } + } +} +const CONTRACT_SOURCE_METADATA: &'static str = "{\"version\":\"3.2.0\",\"link\":\"https://github.com/near/mpc\",\"standards\":[{\"standard\":\"nep330\",\"version\":\"1.3.0\"}],\"build_info\":null}"; +impl MpcContractExt { + pub fn contract_source_metadata(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("contract_source_metadata"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } +} +impl MpcContract { + pub fn contract_source_metadata() { + near_sdk::env::value_return(CONTRACT_SOURCE_METADATA.as_bytes()) + } +} +impl MpcContract { + pub(crate) fn public_key_extended( + &self, + domain_id: DomainId, + ) -> Result { + self.protocol_state.public_key(domain_id) + } + fn threshold(&self) -> Result { + self.protocol_state.threshold() + } + /// Returns true if the request was already pending + fn add_signature_request( + &mut self, + request: &SignatureRequest, + data_id: CryptoHash, + ) -> bool { + self.pending_signature_requests + .insert(request.clone(), YieldIndex { data_id }) + .is_some() + } + /// Returns true if the request was already pending + fn add_ckd_request(&mut self, request: &CKDRequest, data_id: CryptoHash) -> bool { + self.pending_ckd_requests + .insert(request.clone(), YieldIndex { data_id }) + .is_some() + } +} +impl MpcContractExt { + pub fn sign(self, request: SignRequestArgs) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput SignRequestArgs, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { request: &request }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("sign"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn public_key(self, domain_id: Option) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + domain_id: &'nearinput Option, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { domain_id: &domain_id }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("public_key"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn derived_public_key( + self, + path: String, + predecessor: Option, + domain_id: Option, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + path: &'nearinput String, + predecessor: &'nearinput Option, + domain_id: &'nearinput Option, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "path", + &self.path, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "predecessor", + &self.predecessor, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domain_id", + &self.domain_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + path: &path, + predecessor: &predecessor, + domain_id: &domain_id, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("derived_public_key"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn latest_key_version( + self, + signature_scheme: Option, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + signature_scheme: &'nearinput Option, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "signature_scheme", + &self.signature_scheme, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + signature_scheme: &signature_scheme, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("latest_key_version"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn request_app_private_key( + self, + request: CKDRequestArgs, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput CKDRequestArgs, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { request: &request }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("request_app_private_key"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } +} +impl MpcContract { + /// `key_version` must be less than or equal to the value at `latest_key_version` + /// To avoid overloading the network with too many requests, + /// we ask for a small deposit for each signature request. + pub fn sign(&mut self, request: SignRequestArgs) { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "sign: predecessor={0:?}, request={1:?}", + env::predecessor_account_id(), + request, + ), + ); + res + }) + .as_str(), + ); + let initial_storage = env::storage_usage(); + let request: SignRequest = request.try_into().unwrap(); + let domains = match self.protocol_state.domain_registry() { + Ok(domains) => domains, + Err(err) => env::panic_str(&err.to_string()), + }; + let Some(domain_config) = domains.get_domain_by_domain_id(request.domain_id) + else { + env::panic_str( + &InvalidParameters::DomainNotFound { + provided: request.domain_id, + } + .to_string(), + ); + }; + match domain_config.scheme { + SignatureScheme::Secp256k1 | SignatureScheme::V2Secp256k1 => { + let hash = *request.payload.as_ecdsa().expect("Payload is not Ecdsa"); + k256::Scalar::from_repr(hash.into()) + .into_option() + .expect("Ecdsa payload cannot be converted to Scalar"); + } + SignatureScheme::Ed25519 => { + request.payload.as_eddsa().expect("Payload is not EdDSA"); + } + SignatureScheme::Bls12381 => { + env::panic_str( + &InvalidParameters::InvalidDomainId + .message( + "Selected domain is used for Bls12381, which is not compatible with this function", + ) + .to_string(), + ); + } + } + let gas_required = Gas::from_tgas( + self.config.sign_call_gas_attachment_requirement_tera_gas, + ); + if env::prepaid_gas() < gas_required { + env::panic_str( + &InvalidParameters::InsufficientGas + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Provided: {0}, required: {1}", + env::prepaid_gas(), + gas_required, + ), + ); + res + }), + ) + .to_string(), + ); + } + let predecessor = env::predecessor_account_id(); + let deposit = env::attached_deposit(); + let storage_used = env::storage_usage() - initial_storage; + let storage_cost = env::storage_byte_cost() + .saturating_mul(u128::from(storage_used)); + let cost = std::cmp::max(storage_cost, MINIMUM_SIGN_REQUEST_DEPOSIT); + match deposit.checked_sub(cost) { + None => { + env::panic_str( + &InvalidParameters::InsufficientDeposit + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Require a deposit of {0} yoctonear, found: {1}", + cost.as_yoctonear(), + deposit.as_yoctonear(), + ), + ); + res + }), + ) + .to_string(), + ); + } + Some(diff) => { + if diff > NearToken::from_yoctonear(0) { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "refund excess deposit {0} to {1}", + diff, + predecessor, + ), + ); + res + }) + .as_str(), + ); + Promise::new(predecessor.clone()).transfer(diff).detach(); + } + } + } + let request = SignatureRequest::new( + request.domain_id, + request.payload, + &predecessor.as_v2_account_id(), + &request.path, + ); + if !self.accept_requests { + env::panic_str(&TeeError::TeeValidationFailed.to_string()) + } + let callback_gas = Gas::from_tgas( + self.config.return_signature_and_clean_state_on_success_call_tera_gas, + ); + let promise_index = env::promise_yield_create( + "return_signature_and_clean_state_on_success", + serde_json::to_vec(&(&request,)).unwrap(), + callback_gas, + GasWeight(0), + DATA_ID_REGISTER, + ); + let return_sig_id: CryptoHash = env::read_register(DATA_ID_REGISTER) + .expect("read_register failed") + .try_into() + .expect("conversion to CryptoHash failed"); + if self.add_signature_request(&request, return_sig_id) { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "signature request already present, overriding callback.", + ), + ); + res + }) + .as_str(), + ) + } + env::promise_return(promise_index); + } + /// This is the root public key combined from all the public keys of the participants. + /// The domain parameter specifies which domain we're querying the public key for; + /// the default is the first domain. + pub fn public_key( + &self, + domain_id: Option, + ) -> Result { + let domain_id = domain_id.unwrap_or_else(DomainId::legacy_ecdsa_id); + self.public_key_extended(domain_id).map(Into::into) + } + /// This is the derived public key of the caller given path and predecessor + /// if predecessor is not provided, it will be the caller of the contract. + /// + /// The domain parameter specifies which domain we're deriving the public key for; + /// the default is the first domain. + pub fn derived_public_key( + &self, + path: String, + predecessor: Option, + domain_id: Option, + ) -> Result { + let predecessor: AccountId = predecessor + .unwrap_or_else(|| env::predecessor_account_id().as_v2_account_id()); + let tweak = derive_tweak(&predecessor, &path); + let domain = domain_id.unwrap_or_else(DomainId::legacy_ecdsa_id); + let public_key = self.public_key_extended(domain)?; + let derived_public_key: dtos::PublicKey = match public_key { + PublicKeyExtended::Secp256k1 { near_public_key } => { + let derived_public_key = derive_key_secp256k1( + &near_public_key_to_affine_point(near_public_key), + &tweak, + ) + .map_err(PublicKeyError::from)?; + derived_public_key.into_dto_type().into() + } + PublicKeyExtended::Ed25519 { edwards_point, .. } => { + let derived_public_key_edwards_point = derive_public_key_edwards_point_ed25519( + &edwards_point, + &tweak, + ); + derived_public_key_edwards_point.compress().into_dto_type().into() + } + PublicKeyExtended::Bls12381 { public_key } => public_key, + }; + Ok(derived_public_key) + } + /// Key versions refer new versions of the root key that we may choose to generate on cohort + /// changes. Older key versions will always work but newer key versions were never held by + /// older signers. Newer key versions may also add new security features, like only existing + /// within a secure enclave. The signature_scheme parameter specifies which protocol + /// we're querying the latest version for. The default is Secp256k1. The default is **NOT** + /// to query across all protocols. + pub fn latest_key_version(&self, signature_scheme: Option) -> u32 { + self + .state() + .most_recent_domain_for_protocol(signature_scheme.unwrap_or_default()) + .unwrap() + .0 as u32 + } + /// To avoid overloading the network with too many requests, + /// we ask for a small deposit for each ckd request. + pub fn request_app_private_key(&mut self, request: CKDRequestArgs) { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "request_app_private_key: predecessor={0:?}, request={1:?}", + env::predecessor_account_id(), + request, + ), + ); + res + }) + .as_str(), + ); + let initial_storage = env::storage_usage(); + let domains = match self.protocol_state.domain_registry() { + Ok(domains) => domains, + Err(err) => env::panic_str(&err.to_string()), + }; + let Some(domain_config) = domains.get_domain_by_domain_id(request.domain_id) + else { + env::panic_str( + &InvalidParameters::DomainNotFound { + provided: request.domain_id, + } + .to_string(), + ); + }; + if domain_config.scheme != SignatureScheme::Bls12381 { + env::panic_str( + &InvalidParameters::InvalidDomainId + .message("Provided domain ID key type is not Bls12381") + .to_string(), + ); + } + let gas_required = Gas::from_tgas( + self.config.ckd_call_gas_attachment_requirement_tera_gas, + ); + if env::prepaid_gas() < gas_required { + env::panic_str( + &InvalidParameters::InsufficientGas + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Provided: {0}, required: {1}", + env::prepaid_gas(), + gas_required, + ), + ); + res + }), + ) + .to_string(), + ); + } + let predecessor = env::predecessor_account_id(); + let deposit = env::attached_deposit(); + let storage_used = env::storage_usage() - initial_storage; + let storage_cost = env::storage_byte_cost() + .saturating_mul(u128::from(storage_used)); + let cost = std::cmp::max(storage_cost, MINIMUM_CKD_REQUEST_DEPOSIT); + match deposit.checked_sub(cost) { + None => { + env::panic_str( + &InvalidParameters::InsufficientDeposit + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Require a deposit of {0} yoctonear, found: {1}", + cost.as_yoctonear(), + deposit.as_yoctonear(), + ), + ); + res + }), + ) + .to_string(), + ); + } + Some(diff) => { + if diff > NearToken::from_yoctonear(0) { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "refund excess deposit {0} to {1}", + diff, + predecessor, + ), + ); + res + }) + .as_str(), + ); + Promise::new(predecessor.clone()).transfer(diff).detach(); + } + } + } + let mpc_contract = self; + if !mpc_contract.accept_requests { + env::panic_str(&TeeError::TeeValidationFailed.to_string()) + } + let account_id = env::predecessor_account_id().as_v2_account_id(); + let request = CKDRequest::new( + request.app_public_key, + request.domain_id, + &account_id, + &request.derivation_path, + ); + let callback_gas = Gas::from_tgas( + mpc_contract.config.return_ck_and_clean_state_on_success_call_tera_gas, + ); + let promise_index = env::promise_yield_create( + "return_ck_and_clean_state_on_success", + serde_json::to_vec(&(&request,)).unwrap(), + callback_gas, + GasWeight(0), + DATA_ID_REGISTER, + ); + let return_ck_id: CryptoHash = env::read_register(DATA_ID_REGISTER) + .expect("read_register failed") + .try_into() + .expect("conversion to CryptoHash failed"); + if mpc_contract.add_ckd_request(&request, return_ck_id) { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("request already present, overriding callback."), + ); + res + }) + .as_str(), + ) + } + env::promise_return(promise_index); + } +} +impl MpcContractExt { + pub fn respond( + self, + request: SignatureRequest, + response: SignatureResponse, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput SignatureRequest, + response: &'nearinput SignatureResponse, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "response", + &self.response, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + request: &request, + response: &response, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("respond"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn respond_ckd( + self, + request: CKDRequest, + response: CKDResponse, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput CKDRequest, + response: &'nearinput CKDResponse, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "response", + &self.response, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + request: &request, + response: &response, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("respond_ckd"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn submit_participant_info( + self, + proposed_participant_attestation: dtos::Attestation, + tls_public_key: dtos::Ed25519PublicKey, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + proposed_participant_attestation: &'nearinput dtos::Attestation, + tls_public_key: &'nearinput dtos::Ed25519PublicKey, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "proposed_participant_attestation", + &self.proposed_participant_attestation, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "tls_public_key", + &self.tls_public_key, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + proposed_participant_attestation: &proposed_participant_attestation, + tls_public_key: &tls_public_key, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("submit_participant_info"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn get_attestation( + self, + tls_public_key: dtos::Ed25519PublicKey, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + tls_public_key: &'nearinput dtos::Ed25519PublicKey, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "tls_public_key", + &self.tls_public_key, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + tls_public_key: &tls_public_key, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("get_attestation"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_new_parameters( + self, + prospective_epoch_id: EpochId, + proposal: ThresholdParameters, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + prospective_epoch_id: &'nearinput EpochId, + proposal: &'nearinput ThresholdParameters, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "prospective_epoch_id", + &self.prospective_epoch_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "proposal", + &self.proposal, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + prospective_epoch_id: &prospective_epoch_id, + proposal: &proposal, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_new_parameters"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_add_domains(self, domains: Vec) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + domains: &'nearinput Vec, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domains", + &self.domains, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { domains: &domains }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_add_domains"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn start_keygen_instance(self, key_event_id: KeyEventId) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + key_event_id: &'nearinput KeyEventId, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key_event_id", + &self.key_event_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + key_event_id: &key_event_id, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("start_keygen_instance"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_pk( + self, + key_event_id: KeyEventId, + public_key: dtos::PublicKey, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + key_event_id: &'nearinput KeyEventId, + public_key: &'nearinput dtos::PublicKey, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key_event_id", + &self.key_event_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "public_key", + &self.public_key, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + key_event_id: &key_event_id, + public_key: &public_key, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_pk"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn start_reshare_instance( + self, + key_event_id: KeyEventId, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + key_event_id: &'nearinput KeyEventId, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key_event_id", + &self.key_event_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + key_event_id: &key_event_id, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("start_reshare_instance"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_reshared(self, key_event_id: KeyEventId) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + key_event_id: &'nearinput KeyEventId, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key_event_id", + &self.key_event_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + key_event_id: &key_event_id, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_reshared"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_cancel_resharing(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_cancel_resharing"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_cancel_keygen(self, next_domain_id: u64) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + next_domain_id: &'nearinput u64, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "next_domain_id", + &self.next_domain_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + next_domain_id: &next_domain_id, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_cancel_keygen"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_abort_key_event_instance( + self, + key_event_id: KeyEventId, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + key_event_id: &'nearinput KeyEventId, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key_event_id", + &self.key_event_id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + key_event_id: &key_event_id, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_abort_key_event_instance"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn propose_update(self, args: ProposeUpdateArgs) -> ::near_sdk::Promise { + let __args = { + #[borsh(crate = "::near_sdk::borsh")] + struct Input<'nearinput> { + args: &'nearinput ProposeUpdateArgs, + } + impl<'nearinput> ::near_sdk::borsh::ser::BorshSerialize + for Input<'nearinput> { + fn serialize<__W: ::near_sdk::borsh::io::Write>( + &self, + writer: &mut __W, + ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { + ::near_sdk::borsh::BorshSerialize::serialize(&self.args, writer)?; + Ok(()) + } + } + let __args = Input { args: &args }; + match near_sdk::borsh::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using Borsh.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("propose_update"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_update(self, id: UpdateId) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + id: &'nearinput UpdateId, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "id", + &self.id, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { id: &id }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_update"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn proposed_updates(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("proposed_updates"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn remove_update_vote(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("remove_update_vote"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn vote_code_hash(self, code_hash: MpcDockerImageHash) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + code_hash: &'nearinput MpcDockerImageHash, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "code_hash", + &self.code_hash, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { code_hash: &code_hash }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("vote_code_hash"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn get_tee_accounts(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("get_tee_accounts"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn verify_tee(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("verify_tee"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn remove_non_participant_update_votes(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("remove_non_participant_update_votes"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn clean_tee_status(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("clean_tee_status"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } +} +impl MpcContract { + pub fn respond( + &mut self, + request: SignatureRequest, + response: SignatureResponse, + ) -> Result<(), Error> { + let signer = Self::assert_caller_is_signer(); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "respond: signer={0}, request={1:?}", + &signer, + &request, + ), + ); + res + }) + .as_str(), + ); + self.assert_caller_is_attested_participant_and_protocol_active(); + if !self.protocol_state.is_running_or_resharing() { + return Err(InvalidState::ProtocolStateNotRunning.into()); + } + if !self.accept_requests { + return Err(TeeError::TeeValidationFailed.into()); + } + let domain = request.domain_id; + let public_key = self.public_key_extended(domain)?; + let signature_is_valid = match (&response, public_key) { + ( + SignatureResponse::Secp256k1(signature_response), + PublicKeyExtended::Secp256k1 { near_public_key }, + ) => { + let expected_public_key = derive_key_secp256k1( + &near_public_key_to_affine_point(near_public_key), + &request.tweak, + ) + .map_err(RespondError::from)?; + let payload_hash = request + .payload + .as_ecdsa() + .expect("Payload is not ECDSA"); + check_ec_signature( + &expected_public_key, + &signature_response.big_r.affine_point, + &signature_response.s.scalar, + payload_hash, + signature_response.recovery_id, + ) + .is_ok() + } + ( + SignatureResponse::Ed25519 { signature }, + PublicKeyExtended::Ed25519 { + edwards_point: public_key_edwards_point, + .. + }, + ) => { + let derived_public_key_edwards_point = derive_public_key_edwards_point_ed25519( + &public_key_edwards_point, + &request.tweak, + ); + let derived_public_key_32_bytes = *derived_public_key_edwards_point + .compress() + .as_bytes(); + let message = request.payload.as_eddsa().expect("Payload is not EdDSA"); + ed25519_verify( + signature.as_bytes(), + message, + &derived_public_key_32_bytes, + ) + } + (signature_response, public_key_requested) => { + return Err( + RespondError::SignatureSchemeMismatch + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Signature response from MPC: {0:?}. Key requested by user {1:?}", + signature_response, + public_key_requested, + ), + ); + res + }), + ), + ); + } + }; + if !signature_is_valid { + return Err(RespondError::InvalidSignature.into()); + } + if let Some(YieldIndex { data_id }) = self + .pending_signature_requests + .remove(&request) + { + env::promise_yield_resume(&data_id, serde_json::to_vec(&response).unwrap()); + Ok(()) + } else { + Err(InvalidParameters::RequestNotFound.into()) + } + } + pub fn respond_ckd( + &mut self, + request: CKDRequest, + response: CKDResponse, + ) -> Result<(), Error> { + let signer = Self::assert_caller_is_signer(); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "respond_ckd: signer={0}, request={1:?}", + &signer, + &request, + ), + ); + res + }) + .as_str(), + ); + if !self.protocol_state.is_running_or_resharing() { + return Err(InvalidState::ProtocolStateNotRunning.into()); + } + if !self.accept_requests { + return Err(TeeError::TeeValidationFailed.into()); + } + self.assert_caller_is_attested_participant_and_protocol_active(); + if let Some(YieldIndex { data_id }) = self.pending_ckd_requests.remove(&request) + { + env::promise_yield_resume(&data_id, serde_json::to_vec(&response).unwrap()); + Ok(()) + } else { + Err(InvalidParameters::RequestNotFound.into()) + } + } + /// (Prospective) Participants can submit their tee participant information through this + /// endpoint. + pub fn submit_participant_info( + &mut self, + proposed_participant_attestation: dtos::Attestation, + tls_public_key: dtos::Ed25519PublicKey, + ) -> Result<(), Error> { + let proposed_participant_attestation = proposed_participant_attestation + .into_contract_type(); + let account_key = env::signer_account_pk(); + let account_id = Self::assert_caller_is_signer(); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "submit_participant_info: signer={0}, proposed_participant_attestation={1:?}, account_key={2:?}", + account_id, + proposed_participant_attestation, + account_key, + ), + ); + res + }) + .as_str(), + ); + let initial_storage = env::storage_usage(); + let tee_upgrade_deadline_duration = Duration::from_secs( + self.config.tee_upgrade_deadline_duration_seconds, + ); + let attestation_insertion_result = self + .tee_state + .add_participant( + NodeId { + account_id: account_id.clone(), + tls_public_key: tls_public_key.into_contract_type(), + account_public_key: Some(account_key), + }, + proposed_participant_attestation, + tee_upgrade_deadline_duration, + ) + .map_err(|err| { + InvalidParameters::InvalidTeeRemoteAttestation + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("TeeQuoteStatus is invalid: {0}", err), + ); + res + }), + ) + })?; + let caller_is_not_participant = self.voter_account().is_err(); + let is_new_attestation = match attestation_insertion_result { + ParticipantInsertion::NewlyInsertedParticipant => true, + _ => false, + }; + let attestation_storage_must_be_paid_by_caller = is_new_attestation + || caller_is_not_participant; + if attestation_storage_must_be_paid_by_caller { + let storage_used = env::storage_usage() - initial_storage; + let cost = env::storage_byte_cost().saturating_mul(storage_used as u128); + let attached = env::attached_deposit(); + if attached < cost { + return Err( + InvalidParameters::InsufficientDeposit + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Attached {0}, Required {1}", + attached.as_yoctonear(), + cost.as_yoctonear(), + ), + ); + res + }), + ), + ); + } + if let Some(diff) = attached.checked_sub(cost) { + if diff > NearToken::from_yoctonear(0) { + Promise::new(account_id.as_v1_account_id()).transfer(diff).detach(); + } + } + } + Ok(()) + } + pub fn get_attestation( + &self, + tls_public_key: dtos::Ed25519PublicKey, + ) -> Result, Error> { + let tls_public_key = tls_public_key.into_contract_type(); + Ok( + self + .tee_state + .stored_attestations + .get(&tls_public_key) + .map(|node_attestation| { + node_attestation.verified_attestation.clone().into_dto_type() + }), + ) + } + /// Propose a new set of parameters (participants and threshold) for the MPC network. + /// If a threshold number of votes are reached on the exact same proposal, this will transition + /// the contract into the Resharing state. + /// + /// The epoch_id must be equal to 1 plus the current epoch ID (if Running) or prospective epoch + /// ID (if Resharing). Otherwise the vote is ignored. This is to prevent late transactions from + /// accidentally voting on outdated proposals. + pub fn vote_new_parameters( + &mut self, + prospective_epoch_id: EpochId, + proposal: ThresholdParameters, + ) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_new_parameters: signer={0}, proposal={1:?}", + env::signer_account_id(), + proposal, + ), + ); + res + }) + .as_str(), + ); + let tee_upgrade_deadline_duration = Duration::from_secs( + self.config.tee_upgrade_deadline_duration_seconds, + ); + let validation_result = self + .tee_state + .reverify_and_cleanup_participants( + proposal.participants(), + tee_upgrade_deadline_duration, + ); + let proposed_participants = proposal.participants(); + match validation_result { + TeeValidationResult::Full => { + if let Some(new_state) = self + .protocol_state + .vote_new_parameters(prospective_epoch_id, &proposal)? + { + self.protocol_state = new_state; + } + Ok(()) + } + TeeValidationResult::Partial { participants_with_valid_attestation } => { + let invalid_participants: Vec<_> = proposed_participants + .participants() + .iter() + .filter(|(account_id, _, _)| { + !participants_with_valid_attestation.is_participant(account_id) + }) + .collect(); + Err( + InvalidParameters::InvalidTeeRemoteAttestation + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "The following participants have invalid TEE status: {0:?}", + invalid_participants, + ), + ); + res + }), + ), + ) + } + } + } + /// Propose adding a new set of domains for the MPC network. + /// If a threshold number of votes are reached on the exact same proposal, this will transition + /// the contract into the Initializing state to generate keys for the new domains. + /// + /// The specified list of domains must have increasing and contiguous IDs, and the first ID + /// must be the same as the `next_domain_id` returned by state(). + pub fn vote_add_domains(&mut self, domains: Vec) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_add_domains: signer={0}, domains={1:?}", + env::signer_account_id(), + domains, + ), + ); + res + }) + .as_str(), + ); + if let Some(new_state) = self.protocol_state.vote_add_domains(domains)? { + self.protocol_state = new_state; + } + Ok(()) + } + /// Starts a new attempt to generate a key for the current domain. + /// This only succeeds if the signer is the leader (the participant with the lowest ID). + pub fn start_keygen_instance( + &mut self, + key_event_id: KeyEventId, + ) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "start_keygen_instance: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + self.assert_caller_is_attested_participant_and_protocol_active(); + self.protocol_state + .start_keygen_instance(key_event_id, self.config.key_event_timeout_blocks) + } + /// Casts a vote for `public_key` for the attempt identified by `key_event_id`. + /// + /// The effect of this method is either: + /// - Returns error (which aborts with no changes), if there is no active key generation + /// attempt (including if the attempt timed out), if the signer is not a participant, or if + /// the key_event_id corresponds to a different domain, different epoch, or different attempt + /// from the current key generation attempt. + /// - Returns Ok(()), with one of the following changes: + /// - A vote has been collected but we don't have enough votes yet. + /// - This vote is for a public key that disagrees from an earlier voted public key, causing + /// the attempt to abort; another call to `start` is then necessary. + /// - Everyone has now voted for the same public key; the state transitions into generating a + /// key for the next domain. + /// - Same as the last case, except that all domains have a generated key now, and the state + /// transitions into Running with the newly generated keys. + pub fn vote_pk( + &mut self, + key_event_id: KeyEventId, + public_key: dtos::PublicKey, + ) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_pk: signer={0}, key_event_id={1:?}, public_key={2:?}", + env::signer_account_id(), + key_event_id, + public_key, + ), + ); + res + }) + .as_str(), + ); + self.assert_caller_is_attested_participant_and_protocol_active(); + let extended_key = public_key + .try_into() + .map_err(|err: PublicKeyExtendedConversionError| { + InvalidParameters::MalformedPayload.message(err.to_string()) + })?; + if let Some(new_state) = self.protocol_state.vote_pk(key_event_id, extended_key)? + { + self.protocol_state = new_state; + } + Ok(()) + } + /// Starts a new attempt to reshare the key for the current domain. + /// This only succeeds if the signer is the leader (the participant with the lowest ID). + pub fn start_reshare_instance( + &mut self, + key_event_id: KeyEventId, + ) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "start_reshare_instance: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + self.assert_caller_is_attested_participant_and_protocol_active(); + self.protocol_state + .start_reshare_instance(key_event_id, self.config.key_event_timeout_blocks) + } + /// Casts a vote for the successful resharing of the attempt identified by `key_event_id`. + /// + /// The effect of this method is either: + /// - Returns error (which aborts with no changes), if there is no active key resharing attempt + /// (including if the attempt timed out), if the signer is not a participant, or if the + /// key_event_id corresponds to a different domain, different epoch, or different attempt + /// from the current key resharing attempt. + /// - Returns Ok(()), with one of the following changes: + /// - A vote has been collected but we don't have enough votes yet. + /// - Everyone has now voted; the state transitions into resharing the key for the next + /// domain. + /// - Same as the last case, except that all domains' keys have been reshared now, and the + /// state transitions into Running with the newly reshared keys. + pub fn vote_reshared(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_reshared: signer={0}, resharing_id={1:?}", + env::signer_account_id(), + key_event_id, + ), + ); + res + }) + .as_str(), + ); + self.assert_caller_is_attested_participant_and_protocol_active(); + if let Some(new_state) = self.protocol_state.vote_reshared(key_event_id)? { + self.protocol_state = new_state; + Promise::new(env::current_account_id()) + .function_call( + "remove_non_participant_update_votes".to_string(), + ::alloc::vec::Vec::new(), + NearToken::from_yoctonear(0), + Gas::from_tgas( + self.config.remove_non_participant_update_votes_tera_gas, + ), + ) + .detach(); + Promise::new(env::current_account_id()) + .function_call( + "clean_tee_status".to_string(), + ::alloc::vec::Vec::new(), + NearToken::from_yoctonear(0), + Gas::from_tgas(self.config.clean_tee_status_tera_gas), + ) + .detach(); + Promise::new(env::current_account_id()) + .function_call( + "cleanup_orphaned_node_migrations".to_string(), + ::alloc::vec::Vec::new(), + NearToken::from_yoctonear(0), + Gas::from_tgas(self.config.cleanup_orphaned_node_migrations_tera_gas), + ) + .detach(); + } + Ok(()) + } + /// Casts a vote to cancel the current key resharing. If a threshold number of unique + /// votes are collected to cancel the resharing, the contract state will revert back to the + /// previous running state. + /// + /// - This method is idempotent, meaning a single account can not make more than one vote. + /// - Only nodes from the previous running state are allowed to vote. + /// + /// Return value: + /// - [Ok] if the vote was successfully collected. + /// - [Err] if: + /// - The signer is not a participant in the previous running state. + /// - The contract is not in a resharing state. + pub fn vote_cancel_resharing(&mut self) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_cancel_resharing: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + if let Some(new_state) = self.protocol_state.vote_cancel_resharing()? { + self.protocol_state = new_state; + } + Ok(()) + } + /// Casts a vote to cancel key generation. Any keys that have already been generated + /// are kept and we transition into Running state; remaining domains are permanently deleted. + /// Deleted domain IDs cannot be reused again in future calls to vote_add_domains. + /// + /// A next_domain_id that matches that in the state's domains struct must be passed in. This is + /// to prevent stale requests from accidentally cancelling a future key generation state. + pub fn vote_cancel_keygen(&mut self, next_domain_id: u64) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_cancel_keygen: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + if let Some(new_state) = self.protocol_state.vote_cancel_keygen(next_domain_id)? + { + self.protocol_state = new_state; + } + Ok(()) + } + /// Casts a vote to abort the current key event instance. If succesful, the contract aborts the + /// instance and a new instance with the next attempt_id can be started. + pub fn vote_abort_key_event_instance( + &mut self, + key_event_id: KeyEventId, + ) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_abort_key_event_instance: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + self.assert_caller_is_attested_participant_and_protocol_active(); + self.protocol_state.vote_abort_key_event_instance(key_event_id) + } + /// Propose update to either code or config, but not both of them at the same time. + pub fn propose_update( + &mut self, + args: ProposeUpdateArgs, + ) -> Result { + let proposer = self.voter_or_panic().as_v1_account_id(); + let update: Update = args.try_into()?; + let attached = env::attached_deposit(); + let required = ProposedUpdates::required_deposit(&update); + if attached < required { + return Err( + InvalidParameters::InsufficientDeposit + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Attached {0}, Required {1}", + attached.as_yoctonear(), + required.as_yoctonear(), + ), + ); + res + }), + ), + ); + } + let id = self.proposed_updates.propose(update); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "propose_update: signer={0}, id={1:?}", + env::signer_account_id(), + id, + ), + ); + res + }) + .as_str(), + ); + if let Some(diff) = attached.checked_sub(required) { + if diff > NearToken::from_yoctonear(0) { + Promise::new(proposer).transfer(diff).detach(); + } + } + Ok(id) + } + /// Vote for a proposed update given the [`UpdateId`] of the update. + /// + /// Returns `Ok(true)` if the amount of voters surpassed the threshold and the update was + /// executed. Returns `Ok(false)` if the amount of voters did not surpass the threshold. + /// Returns [`Error`] if the update was not found or if the voter is not a participant + /// in the protocol. + pub fn vote_update(&mut self, id: UpdateId) -> Result { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_update: signer={0}, id={1:?}", + env::signer_account_id(), + id, + ), + ); + res + }) + .as_str(), + ); + let ProtocolContractState::Running(running_state) = &self.protocol_state else { + env::panic_str("protocol must be in running state"); + }; + let threshold = self.threshold()?; + let voter = self.voter_or_panic(); + if self.proposed_updates.vote(&id, voter).is_none() { + return Err(InvalidParameters::UpdateNotFound.into()); + } + let valid_votes_count = running_state + .parameters + .participants() + .participants() + .iter() + .filter(|(account_id, _, _)| { + self.proposed_updates + .vote_by_participant + .get(account_id) + .is_some_and(|voted_id| *voted_id == id) + }) + .count(); + if (valid_votes_count as u64) < threshold.value() { + return Ok(false); + } + let update_gas_deposit = Gas::from_tgas( + self.config.contract_upgrade_deposit_tera_gas, + ); + let Some(_promise) = self.proposed_updates.do_update(&id, update_gas_deposit) + else { + return Err(InvalidParameters::UpdateNotFound.into()); + }; + Ok(true) + } + /// returns all proposed updates + pub fn proposed_updates(&self) -> dtos::ProposedUpdates { + self.proposed_updates.into_dto_type() + } + /// Removes an update vote by the caller + /// panics if the contract is not in a running state or if the caller is not a participant + pub fn remove_update_vote(&mut self) { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "remove_update_vote: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + let ProtocolContractState::Running(_running_state) = &self.protocol_state else { + env::panic_str("protocol must be in running state"); + }; + let voter = self.voter_or_panic(); + self.proposed_updates.remove_vote(&voter); + } + pub fn vote_code_hash( + &mut self, + code_hash: MpcDockerImageHash, + ) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "vote_code_hash: signer={0}, code_hash={1:?}", + env::signer_account_id(), + code_hash, + ), + ); + res + }) + .as_str(), + ); + self.voter_or_panic(); + let threshold_parameters = match self.state().threshold_parameters() { + Ok(threshold_parameters) => threshold_parameters, + Err(ContractNotInitialized) => { + env::panic_str( + "Contract is not initialized. Can not vote for a new image hash before initialization.", + ) + } + }; + let participant = AuthenticatedParticipantId::new( + threshold_parameters.participants(), + )?; + let votes = self.tee_state.vote(code_hash.clone(), &participant); + let tee_upgrade_deadline_duration = Duration::from_secs( + self.config.tee_upgrade_deadline_duration_seconds, + ); + if votes >= self.threshold()?.value() { + self.tee_state + .whitelist_tee_proposal(code_hash, tee_upgrade_deadline_duration); + } + Ok(()) + } + /// Returns all accounts that have TEE attestations stored in the contract. + /// Note: This includes both current protocol participants and accounts that may have + /// submitted TEE information but are not currently part of the active participant set. + pub fn get_tee_accounts(&self) -> Vec { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format(format_args!("get_tee_accounts")); + res + }) + .as_str(), + ); + self.tee_state.get_tee_accounts() + } + /// Verifies if all current participants have an accepted TEE state. + /// Automatically enters a resharing, in case one or more participants do not have an accepted + /// TEE state. + /// Returns `false` and stops the contract from accepting new signature requests or responses, + /// in case less than `threshold` participants run in an accepted TEE State. + pub fn verify_tee(&mut self) -> Result { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("verify_tee: signer={0}", env::signer_account_id()), + ); + res + }) + .as_str(), + ); + self.voter_or_panic(); + let ProtocolContractState::Running(running_state) = &mut self.protocol_state + else { + return Err(InvalidState::ProtocolStateNotRunning.into()); + }; + let current_params = running_state.parameters.clone(); + let tee_upgrade_deadline_duration = Duration::from_secs( + self.config.tee_upgrade_deadline_duration_seconds, + ); + match self + .tee_state + .reverify_and_cleanup_participants( + current_params.participants(), + tee_upgrade_deadline_duration, + ) + { + TeeValidationResult::Full => { + self.accept_requests = true; + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("All participants have an accepted Tee status"), + ); + res + }) + .as_str(), + ); + Ok(true) + } + TeeValidationResult::Partial { participants_with_valid_attestation } => { + let threshold = current_params.threshold().value() as usize; + let remaining = participants_with_valid_attestation.len(); + if threshold > remaining { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Less than `threshold` participants are left with a valid TEE status. This requires manual intervention. We will not accept new signature requests as a safety precaution.", + ), + ); + res + }) + .as_str(), + ); + self.accept_requests = false; + return Ok(false); + } + self.accept_requests = true; + let new_threshold = threshold; + let threshold_parameters = ThresholdParameters::new( + participants_with_valid_attestation, + Threshold::new(new_threshold as u64), + ) + .expect("Require valid threshold parameters"); + current_params.validate_incoming_proposal(&threshold_parameters)?; + let res = running_state + .transition_to_resharing_no_checks(&threshold_parameters); + if let Some(resharing) = res { + self.protocol_state = ProtocolContractState::Resharing(resharing); + } + Ok(true) + } + } + } + /// Cleans update votes from non-participants after resharing. + /// Can be called by any participant or triggered automatically via promise. + pub fn remove_non_participant_update_votes(&mut self) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "remove_non_participant_update_votes: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + let participants = match &self.protocol_state { + ProtocolContractState::Running(state) => state.parameters.participants(), + _ => { + return Err(InvalidState::ProtocolStateNotRunning.into()); + } + }; + self.proposed_updates.remove_non_participant_votes(participants); + Ok(()) + } + /// Private endpoint to clean up TEE information for non-participants after resharing. + /// This can only be called by the contract itself via a promise. + pub fn clean_tee_status(&mut self) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "clean_tee_status: signer={0}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + let participants = match &self.protocol_state { + ProtocolContractState::Running(state) => state.parameters.participants(), + _ => { + return Err(InvalidState::ProtocolStateNotRunning.into()); + } + }; + self.tee_state.clean_non_participants(participants); + Ok(()) + } +} +impl MpcContractExt { + pub fn init( + self, + parameters: ThresholdParameters, + init_config: Option, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + parameters: &'nearinput ThresholdParameters, + init_config: &'nearinput Option, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "parameters", + &self.parameters, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "init_config", + &self.init_config, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + parameters: ¶meters, + init_config: &init_config, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("init"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn init_running( + self, + domains: Vec, + next_domain_id: u64, + keyset: Keyset, + parameters: ThresholdParameters, + init_config: Option, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + domains: &'nearinput Vec, + next_domain_id: &'nearinput u64, + keyset: &'nearinput Keyset, + parameters: &'nearinput ThresholdParameters, + init_config: &'nearinput Option, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "domains", + &self.domains, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "next_domain_id", + &self.next_domain_id, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "keyset", + &self.keyset, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "parameters", + &self.parameters, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "init_config", + &self.init_config, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + domains: &domains, + next_domain_id: &next_domain_id, + keyset: &keyset, + parameters: ¶meters, + init_config: &init_config, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("init_running"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn migrate(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("migrate"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn migrate_cleanup(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("migrate_cleanup"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn state(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("state"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn allowed_docker_image_hashes(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("allowed_docker_image_hashes"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn allowed_launcher_compose_hashes(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("allowed_launcher_compose_hashes"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn get_pending_request(self, request: &SignatureRequest) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput SignatureRequest, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { request: &request }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("get_pending_request"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn get_pending_ckd_request(self, request: &CKDRequest) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput CKDRequest, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { request: &request }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("get_pending_ckd_request"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn config(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("config"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn version(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("version"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn return_signature_and_clean_state_on_success( + self, + request: SignatureRequest, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput SignatureRequest, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { request: &request }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from( + "return_signature_and_clean_state_on_success", + ), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn return_ck_and_clean_state_on_success( + self, + request: CKDRequest, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + request: &'nearinput CKDRequest, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "request", + &self.request, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { request: &request }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("return_ck_and_clean_state_on_success"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn fail_on_timeout(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("fail_on_timeout"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn update_config(self, config: dtos::Config) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + config: &'nearinput dtos::Config, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "config", + &self.config, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { config: &config }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("update_config"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } +} +impl MpcContract { + pub fn init( + parameters: ThresholdParameters, + init_config: Option, + ) -> Result { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "init: signer={0}, parameters={1:?}, init_config={2:?}", + env::signer_account_id(), + parameters, + init_config, + ), + ); + res + }) + .as_str(), + ); + parameters.validate()?; + parameters.validate().unwrap(); + let initial_participants = parameters.participants(); + let tee_state = TeeState::with_mocked_participant_attestations( + initial_participants, + ); + Ok(Self { + protocol_state: ProtocolContractState::Running( + RunningContractState::new( + DomainRegistry::default(), + Keyset::new(EpochId::new(0), Vec::new()), + parameters, + ), + ), + pending_signature_requests: LookupMap::new( + StorageKey::PendingSignatureRequestsV2, + ), + pending_ckd_requests: LookupMap::new(StorageKey::PendingCKDRequests), + proposed_updates: ProposedUpdates::default(), + config: init_config.map(Into::into).unwrap_or_default(), + tee_state, + accept_requests: true, + node_migrations: NodeMigrations::default(), + }) + } + pub fn init_running( + domains: Vec, + next_domain_id: u64, + keyset: Keyset, + parameters: ThresholdParameters, + init_config: Option, + ) -> Result { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "init_running: signer={0}, domains={1:?}, keyset={2:?}, parameters={3:?}, init_config={4:?}", + env::signer_account_id(), + domains, + keyset, + parameters, + init_config, + ), + ); + res + }) + .as_str(), + ); + parameters.validate()?; + let domains = DomainRegistry::from_raw_validated(domains, next_domain_id)?; + let domain_ids_from_domains = domains + .domains() + .iter() + .map(|d| d.id) + .collect::>(); + let domain_ids_from_keyset = keyset + .domains + .iter() + .map(|k| k.domain_id) + .collect::>(); + if domain_ids_from_domains != domain_ids_from_keyset { + return Err(DomainError::DomainsMismatch.into()); + } + let initial_participants = parameters.participants(); + let tee_state = TeeState::with_mocked_participant_attestations( + initial_participants, + ); + Ok(MpcContract { + config: init_config.map(Into::into).unwrap_or_default(), + protocol_state: ProtocolContractState::Running( + RunningContractState::new(domains, keyset, parameters), + ), + pending_signature_requests: LookupMap::new( + StorageKey::PendingSignatureRequestsV2, + ), + pending_ckd_requests: LookupMap::new(StorageKey::PendingCKDRequests), + proposed_updates: Default::default(), + tee_state, + accept_requests: true, + node_migrations: NodeMigrations::default(), + }) + } + /// This will be called internally by the contract to migrate the state when a new contract + /// is deployed. This function should be changed every time state is changed to do the proper + /// migrate flow. + /// + /// If nothing is changed, then this function will just return the current state. If it fails + /// to read the state, then it will return an error. + pub fn migrate() -> Result { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format(format_args!("migrating contract")); + res + }) + .as_str(), + ); + Self::migrate_cleanup(); + match try_state_read::() { + Ok(Some(state)) => return Ok(state.into()), + Ok(None) => return Err(InvalidState::ContractStateIsMissing.into()), + Err(err) => { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "failed to deserialize state into 3_0_2 state: {0:?}", + err, + ), + ); + res + }) + .as_str(), + ); + } + }; + match try_state_read::() { + Ok(Some(state)) => return Ok(state.into()), + Ok(None) => return Err(InvalidState::ContractStateIsMissing.into()), + Err(err) => { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "failed to deserialize state into 3_2_0 state: {0:?}", + err, + ), + ); + res + }) + .as_str(), + ); + } + }; + match try_state_read::() { + Ok(Some(state)) => Ok(state), + Ok(None) => Err(InvalidState::ContractStateIsMissing.into()), + Err(err) => { + env::panic_str( + &::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "could not deserialize contract state: {0}", + err, + ), + ); + res + }), + ) + } + } + } + /// `Self::migrate` often runs out of the 300Tgas max gas limit, due to expensive cleanups + /// that are performed during the upgrade. + /// + /// Expensive operations that + pub fn migrate_cleanup() { + let mut participants_attestations: IterableMap< + near_sdk::PublicKey, + (NodeId, Attestation), + > = IterableMap::new(StorageKey::_DeprecatedTeeParticipantAttestation); + let mut entries = 0; + for k in participants_attestations.values() { + entries += 1; + } + match (&entries, &0) { + (left_val, right_val) => { + if *left_val == *right_val { + let kind = ::core::panicking::AssertKind::Ne; + ::core::panicking::assert_failed( + kind, + &*left_val, + &*right_val, + ::core::option::Option::None, + ); + } + } + }; + participants_attestations.clear(); + } + pub fn state(&self) -> &ProtocolContractState { + &self.protocol_state + } + /// Returns all allowed code hashes in order from most recent to least recent allowed code hashes. The first element is the most recent allowed code hash. + pub fn allowed_docker_image_hashes(&self) -> Vec { + let tee_upgrade_deadline_duration = Duration::from_secs( + self.config.tee_upgrade_deadline_duration_seconds, + ); + let mut hashes: Vec = self + .tee_state + .get_allowed_mpc_docker_images(tee_upgrade_deadline_duration) + .into_iter() + .map(|allowed_image_hash| allowed_image_hash.image_hash) + .collect(); + hashes.reverse(); + hashes + } + pub fn allowed_launcher_compose_hashes(&self) -> Vec { + self.tee_state.allowed_launcher_compose_hashes.clone() + } + pub fn get_pending_request(&self, request: &SignatureRequest) -> Option { + self.pending_signature_requests.get(request).cloned() + } + pub fn get_pending_ckd_request(&self, request: &CKDRequest) -> Option { + self.pending_ckd_requests.get(request).cloned() + } + pub fn config(&self) -> dtos::Config { + dtos::Config::from(&self.config) + } + pub fn version() -> String { + "3.2.0".to_string() + } + /// Upon success, removes the signature from state and returns it. + /// If the signature request times out, removes the signature request from state and panics to + /// fail the original transaction + pub fn return_signature_and_clean_state_on_success( + &mut self, + request: SignatureRequest, + signature: Result, + ) -> PromiseOrValue { + match signature { + Ok(signature) => PromiseOrValue::Value(signature), + Err(_) => { + self.pending_signature_requests.remove(&request); + let fail_on_timeout_gas = Gas::from_tgas( + self.config.fail_on_timeout_tera_gas, + ); + let promise = Promise::new(env::current_account_id()) + .function_call( + "fail_on_timeout".to_string(), + ::alloc::vec::Vec::new(), + NearToken::from_near(0), + fail_on_timeout_gas, + ); + near_sdk::PromiseOrValue::Promise(promise.as_return()) + } + } + } + /// Upon success, removes the confidential key from state and returns it. + /// If the ckd request times out, removes the ckd request from state and panics to fail the + /// original transaction + pub fn return_ck_and_clean_state_on_success( + &mut self, + request: CKDRequest, + ck: Result, + ) -> PromiseOrValue { + match ck { + Ok(ck) => PromiseOrValue::Value(ck), + Err(_) => { + self.pending_ckd_requests.remove(&request); + let fail_on_timeout_gas = Gas::from_tgas( + self.config.fail_on_timeout_tera_gas, + ); + let promise = Promise::new(env::current_account_id()) + .function_call( + "fail_on_timeout".to_string(), + ::alloc::vec::Vec::new(), + NearToken::from_near(0), + fail_on_timeout_gas, + ); + near_sdk::PromiseOrValue::Promise(promise.as_return()) + } + } + } + pub fn fail_on_timeout() { + env::panic_str(&RequestError::Timeout.to_string()); + } + pub fn update_config(&mut self, config: dtos::Config) { + self.config = config.into(); + } + /// Get our own account id as a voter. Returns an error if we are not a participant. + fn voter_account(&self) -> Result { + if !Self::caller_is_signer() { + return Err(InvalidParameters::CallerNotSigner.into()); + } + let voter = env::signer_account_id().as_v2_account_id(); + self.protocol_state.authenticate_update_vote()?; + Ok(voter) + } + /// Returns true if the caller is the signer account. + fn caller_is_signer() -> bool { + let signer = env::signer_account_id(); + let predecessor = env::predecessor_account_id(); + signer == predecessor + } + /// Get our own account id as a voter. If we are not a participant, panic. + /// also ensures that the caller is the signer account. + fn voter_or_panic(&self) -> AccountId { + Self::assert_caller_is_signer(); + match self.voter_account() { + Ok(voter) => voter, + Err(err) => { + env::panic_str( + &::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!("not a voter, {0:?}", err), + ); + res + }), + ) + } + } + } + /// Ensures that the caller is an attested participant + /// in the currently active protocol phase. + /// + /// Active phases: + /// - `Initializing` → uses proposed participants from generating_key + /// - `Running` → uses current active participants + /// - `Resharing` → uses new participants from resharing proposal + /// + /// Panics if: + /// - The protocol is not active (e.g., NotInitialized) + /// - The caller is not attested or not in the relevant participants set + /// - The caller is not the signer account + fn assert_caller_is_attested_participant_and_protocol_active(&self) { + let participants = self.protocol_state.active_participants(); + Self::assert_caller_is_signer(); + let attestation_check = self + .tee_state + .is_caller_an_attested_participant(participants); + match attestation_check { + Ok(()) => {} + ref e => { + ::std::rt::panic_fmt( + format_args!( + "assertion failed: `{0:?}` does not match `{1}`: {2}", + e, + "Ok(())", + format_args!("Caller must be an attested participant"), + ), + ); + } + }; + } + /// Ensures the current call originates from the signer account itself. + /// Panics if `signer_account_id` and `predecessor_account_id` differ. + fn assert_caller_is_signer() -> AccountId { + let signer_id = env::signer_account_id(); + let predecessor_id = env::predecessor_account_id(); + match (&signer_id, &predecessor_id) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + let kind = ::core::panicking::AssertKind::Eq; + ::core::panicking::assert_failed( + kind, + &*left_val, + &*right_val, + ::core::option::Option::Some( + format_args!( + "Caller must be the signer account (signer: {0}, predecessor: {1})", + signer_id, + predecessor_id, + ), + ), + ); + } + } + }; + signer_id.as_v2_account_id() + } +} +impl MpcContractExt { + pub fn migration_info(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("migration_info"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn register_backup_service( + self, + backup_service_info: BackupServiceInfo, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + backup_service_info: &'nearinput BackupServiceInfo, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "backup_service_info", + &self.backup_service_info, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + backup_service_info: &backup_service_info, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("register_backup_service"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn start_node_migration( + self, + destination_node_info: DestinationNodeInfo, + ) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + destination_node_info: &'nearinput DestinationNodeInfo, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "destination_node_info", + &self.destination_node_info, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { + destination_node_info: &destination_node_info, + }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("start_node_migration"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn conclude_node_migration(self, keyset: &Keyset) -> ::near_sdk::Promise { + let __args = { + #[serde(crate = "::near_sdk::serde")] + struct Input<'nearinput> { + keyset: &'nearinput Keyset, + } + #[doc(hidden)] + #[allow( + non_upper_case_globals, + unused_attributes, + unused_qualifications, + clippy::absolute_paths, + )] + const _: () = { + use ::near_sdk::serde as _serde; + #[automatically_derived] + impl<'nearinput> _serde::Serialize for Input<'nearinput> { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private228::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Input", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "keyset", + &self.keyset, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + let __args = Input { keyset: &keyset }; + match near_sdk::serde_json::to_vec(&__args) { + Ok(serialized) => serialized, + Err(_) => { + ::near_sdk::env::panic_str( + "Failed to serialize the cross contract args using JSON.", + ) + } + } + }; + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("conclude_node_migration"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } + pub fn cleanup_orphaned_node_migrations(self) -> ::near_sdk::Promise { + let __args = ::alloc::vec::Vec::new(); + match self.promise_or_create_on { + ::near_sdk::PromiseOrValue::Promise(p) => p, + ::near_sdk::PromiseOrValue::Value(account_id) => { + ::near_sdk::Promise::new(account_id) + } + } + .function_call_weight( + ::std::string::String::from("cleanup_orphaned_node_migrations"), + __args, + self.deposit, + self.static_gas, + self.gas_weight, + ) + } +} +/// Methods for Migration service +impl MpcContract { + pub fn migration_info( + &self, + ) -> BTreeMap, Option)> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format(format_args!("migration_info")); + res + }) + .as_str(), + ); + self.node_migrations.get_all() + } + /// Registers or updates the backup service information for the caller account. + /// + /// The caller (`signer_account_id`) must be an existing or prospective participant. + /// Otherwise, the transaction will fail. + /// + /// # Notes + /// - A deposit requirement may be added in the future. + pub fn register_backup_service( + &mut self, + backup_service_info: BackupServiceInfo, + ) -> Result<(), Error> { + let account_id = Self::assert_caller_is_signer(); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "register_backup_service: signer={0:?}, backup_service_info={1:?}", + account_id, + backup_service_info, + ), + ); + res + }) + .as_str(), + ); + if !self.protocol_state.is_existing_or_prospective_participant(&account_id)? { + return Err( + errors::InvalidState::NotParticipant + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "account: {0} is not in the set of curent or prospective participants and not eligible to store backup service information", + account_id, + ), + ); + res + }), + ), + ); + } + self.node_migrations.set_backup_service_info(account_id, backup_service_info); + Ok(()) + } + /// Sets the destination node for the calling account. + /// + /// This function can only be called while the protocol is in a `Running` state. + /// The signer must be a current participant of the current epoch, otherwise an error is returned. + /// On success, the provided [`DestinationNodeInfo`] is stored in the contract state + /// under the signer’s account ID. + /// + /// # Errors + /// - [`InvalidState::ProtocolStateNotRunning`] if the protocol is not in the `Running` state. + /// - [`InvalidState::NotParticipant`] if the signer is not a current participant. + /// # Note: + /// - might require a deposit + pub fn start_node_migration( + &mut self, + destination_node_info: DestinationNodeInfo, + ) -> Result<(), Error> { + let account_id = Self::assert_caller_is_signer(); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "start_node_migration: signer={0:?}, destination_node_info={1:?}", + account_id, + destination_node_info, + ), + ); + res + }) + .as_str(), + ); + let ProtocolContractState::Running(running_state) = &self.protocol_state else { + return Err( + errors::InvalidState::ProtocolStateNotRunning + .message( + "migration of nodes is only possible while the protocol is in `Running` state." + .to_string(), + ), + ); + }; + if !running_state.is_participant(&account_id) { + return Err( + errors::InvalidState::NotParticipant + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "account: {0} is not in the set of curent participants and thus not eligible to initiate a node migration.", + account_id, + ), + ); + res + }), + ), + ); + } + self.node_migrations + .set_destination_node_info(account_id, destination_node_info); + Ok(()) + } + /// Finalizes a node migration for the calling account. + /// + /// This method can only be called while the protocol is in a `Running` state + /// and by an existing participant. On success, the participant’s information is + /// updated to the new destination node. + /// + /// # Errors + /// Returns the following errors: + /// - `InvalidState::ProtocolStateNotRunning`: if protocol is not in `Running` state + /// - `InvalidState::NotParticipant`: if caller is not a current participant + /// - `NodeMigrationError::KeysetMismatch`: if provided keyset does not match the expected keyset + /// - `NodeMigrationError::MigrationNotFound`: if no migration record exists for the caller + /// - `NodeMigrationError::AccountPublicKeyMismatch`: if caller’s public key does not match the expected destination node + /// - `InvalidParameters::InvalidTeeRemoteAttestation`: if destination node’s TEE quote is invalid + pub fn conclude_node_migration(&mut self, keyset: &Keyset) -> Result<(), Error> { + let account_id = Self::assert_caller_is_signer(); + let signer_pk = env::signer_account_pk(); + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "conclude_node_migration: signer={0:?}, signer_pk={1:?} keyset={2:?}", + account_id, + signer_pk, + keyset, + ), + ); + res + }) + .as_str(), + ); + let ProtocolContractState::Running(running_state) = &mut self.protocol_state + else { + return Err( + errors::InvalidState::ProtocolStateNotRunning + .message( + "migration of nodes is only possible while the protocol is in `Running` state." + .to_string(), + ), + ); + }; + if !running_state.is_participant(&account_id) { + return Err( + errors::InvalidState::NotParticipant + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "account: {0} is not in the set of curent participants and thus eligible to initiate a node migration.", + account_id, + ), + ); + res + }), + ), + ); + } + let expected_keyset = &running_state.keyset; + if expected_keyset != keyset { + return Err( + errors::NodeMigrationError::KeysetMismatch + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "keyset={0:?}, expected_keyset={1:?}", + keyset, + expected_keyset, + ), + ); + res + }), + ), + ); + } + let Some(expected_destination_node) = self + .node_migrations + .remove_migration(&account_id) else { + return Err(errors::NodeMigrationError::MigrationNotFound.into()); + }; + if expected_destination_node.signer_account_pk != signer_pk { + return Err( + errors::NodeMigrationError::AccountPublicKeyMismatch + .message( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "found {0:?}, expected {1:?}", + signer_pk, + expected_destination_node.signer_account_pk, + ), + ); + res + }), + ), + ); + } + let node_id = NodeId { + account_id: account_id.clone(), + account_public_key: Some( + expected_destination_node.signer_account_pk.clone(), + ), + tls_public_key: expected_destination_node + .destination_node_info + .sign_pk + .clone(), + }; + if !(match self + .tee_state + .reverify_participants( + &node_id, + Duration::from_secs(self.config.tee_upgrade_deadline_duration_seconds), + ) + { + TeeQuoteStatus::Valid => true, + _ => false, + }) { + return Err(errors::InvalidParameters::InvalidTeeRemoteAttestation.into()); + } + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "Moving Account {0:?} to {1:?}", + account_id, + expected_destination_node.destination_node_info, + ), + ); + res + }) + .as_str(), + ); + running_state + .parameters + .update_info(account_id, expected_destination_node.destination_node_info)?; + Ok(()) + } + pub fn cleanup_orphaned_node_migrations(&mut self) -> Result<(), Error> { + ::near_sdk::env::log_str( + ::alloc::__export::must_use({ + let res = ::alloc::fmt::format( + format_args!( + "cleanup_orphaned_node_migrations signer={0:?}", + env::signer_account_id(), + ), + ); + res + }) + .as_str(), + ); + let backup_services: Vec = self + .node_migrations + .backup_services_info() + .keys() + .cloned() + .collect(); + for account_id in &backup_services { + if !self.protocol_state.is_existing_or_prospective_participant(account_id)? { + self.node_migrations.remove_account_data(account_id); + } + } + Ok(()) + } +} +fn try_state_read() -> Result, std::io::Error> { + env::storage_read(b"STATE").map(|data| T::try_from_slice(&data)).transpose() +} From cdba907fcbfe0005002a32c89c2e1845fc8fd9df Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 11:15:20 +0100 Subject: [PATCH 3/8] gas can be lowered --- crates/contract/tests/sandbox/utils/consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/contract/tests/sandbox/utils/consts.rs b/crates/contract/tests/sandbox/utils/consts.rs index 16173eeb5..49412b731 100644 --- a/crates/contract/tests/sandbox/utils/consts.rs +++ b/crates/contract/tests/sandbox/utils/consts.rs @@ -30,7 +30,7 @@ pub const GAS_FOR_VOTE_NEW_PARAMETERS: Gas = Gas::from_tgas(22); /// TODO(#1571): Gas cost for voting on contract updates. Reduced somewhat after /// optimization (#1617) by avoiding full contract code deserialization; there’s likely still /// room for further optimization. -pub const GAS_FOR_VOTE_UPDATE: Gas = Gas::from_tgas(241); +pub const GAS_FOR_VOTE_UPDATE: Gas = Gas::from_tgas(232); /// Gas required for votes cast before the threshold is reached (votes 1 through N-1). /// These votes are cheap because they only record the vote without triggering the actual /// contract update deployment and migration. From 609350f07fbb94842d1d763bd2489a1ace7b60b7 Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 11:41:20 +0100 Subject: [PATCH 4/8] remove default call --- crates/contract/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/contract/src/lib.rs b/crates/contract/src/lib.rs index e4329eddb..92ec2aa65 100644 --- a/crates/contract/src/lib.rs +++ b/crates/contract/src/lib.rs @@ -2456,7 +2456,11 @@ mod tests { pending_signature_requests: LookupMap::new(StorageKey::PendingSignatureRequestsV2), pending_ckd_requests: LookupMap::new(StorageKey::PendingCKDRequests), accept_requests: true, - ..Default::default() + proposed_updates: Default::default(), + config: Default::default(), + tee_state: Default::default(), + node_migrations: Default::default(), + stale_data: Default::default(), } } } From 7c991848a6cce4994e1eaa019ae670b36a46228f Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 11:42:02 +0100 Subject: [PATCH 5/8] clippy for v_3_20 --- crates/contract/src/v3_2_0_state.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/contract/src/v3_2_0_state.rs b/crates/contract/src/v3_2_0_state.rs index bc4c9e1a2..d307eab33 100644 --- a/crates/contract/src/v3_2_0_state.rs +++ b/crates/contract/src/v3_2_0_state.rs @@ -70,8 +70,8 @@ impl From for crate::MpcContract { protocol_state, pending_signature_requests: value.pending_signature_requests, pending_ckd_requests: value.pending_ckd_requests, - proposed_updates: value.proposed_updates.into(), - config: value.config.into(), + proposed_updates: value.proposed_updates, + config: value.config, tee_state, accept_requests: value.accept_requests, node_migrations: value.node_migrations, From ac89b9c13c3e35f447ad930c44afba2cb7236272 Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 12:32:14 +0100 Subject: [PATCH 6/8] update snapshot --- crates/contract/tests/snapshots/abi__abi_has_not_changed.snap | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap b/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap index 208f60f25..a054b0869 100644 --- a/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap +++ b/crates/contract/tests/snapshots/abi__abi_has_not_changed.snap @@ -395,6 +395,10 @@ expression: abi "private" ] }, + { + "name": "migrate_clear_tee", + "kind": "call" + }, { "name": "migration_info", "kind": "view", From 0a074ead58cdd11012e760dea70b1bc0e7ed9342 Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 12:35:36 +0100 Subject: [PATCH 7/8] remove tracking expanded.rs --- expanded.rs | 30223 -------------------------------------------------- 1 file changed, 30223 deletions(-) delete mode 100644 expanded.rs diff --git a/expanded.rs b/expanded.rs deleted file mode 100644 index c50cb9247..000000000 --- a/expanded.rs +++ /dev/null @@ -1,30223 +0,0 @@ - Checking mpc-contract v3.2.0 (/Users/dsharifi/Dev/mpc/crates/contract) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s - -#![feature(prelude_import)] -/*!# MPC Contract - -This crate defines the **MPC Contract**, which governs the MPC network and allows any NEAR account to request signatures. - -```text - ┌───────┐ ┌─────────────┐ ┌───────────┐ - │ User │ │ Participant │ │ MPC Node │ - └───────┘ └─────────────┘ └───────────┘ - │ │ │ -Request signature. │ │ - │ Vote on changes. │ - │ │ │ - └────────┐ │ ┌──Respond to signature requests. - │ │ │ - ▼ ▼ ▼ - ┌──────────────┐ - │ MPC Contract │ - └──────────────┘ - -``` - -## Live deployments - -The MPC contract is deployed on the [NEAR blockchain](https://nearblocks.io/address/v1.signer) -and on the [NEAR testnet](https://testnet.nearblocks.io/address/v1.signer-prod.testnet). - -## Role of the contract in Chain Signatures - -This contract serves as an interface to the MPC network. -Users and contracts can submit signature requests via this contract, -and MPC Participants can vote on changes to the MPC network, such as: - -- Changing the set of MPC participants. -- Adjusting the cryptographic threshold. -- Generating new distributed keys. -- Updating the contract code. - -## Contract State - -The contract tracks the following information: - -- Pending signature requests. -- Current participant set of the MPC network. -- Node migrations. -- Current set of keys managed by the MPC network (each key is associated to a unique `domain_id`). -- Metadata related to trusted execution environments. -- Current protocol state of the MPC network (see [Protocol State and Lifecycle](#protocol-state)). - -## Contract Updates - -Participants can propose and vote on contract updates (code or configuration changes). When an update receives sufficient votes and is executed (via the `vote_update` endpoint which calls `do_update` internally), all pending update proposals and votes are cleared as they are no longer be valid after the contract migration. The update ID counter is preserved across migrations as part of the contract state to avoid race conditions where multiple participants might propose updates with colliding IDs immediately after an upgrade. - -## Usage - -### Submitting a signature Request - -Users can submit a signature request to the MPC network via the `sign` endpoint of this contract. Note that a **deposit is required to cover storage costs** (minimum 1 yoctoNEAR) to prevent abuse by malicious frontends. Any excess deposit is automatically refunded to the user. - -The sign request takes the following arguments: - -- `path` (String): the derivation path (used for key-derivation). -- `payload_v2`: either - - `{"Ecdsa": ""}` or - - `{"Eddsa": ""}` -- `domain_id` (integer): identifies the key to use for generating the signature. Note that the payload type must match the associated signature scheme. - -Submitting a signature request costs approximately 7 Tgas, but the contract requires that at least 10 Tgas are attached to the transaction. - -#### Example - -_ECDSA Signature Request_ - -```Json -{ - "request": { - "payload_v2": { - "Ecdsa": "521da91dc9bddb625bd0679d9e735def558761a34653624f5954f44bce6443a9" - }, - "path": "sepolia-1", - "domain_id": 0 - } -} -``` - -_EDDSA Signature Request_ - -```Json -{ - "request": { - "payload_v2": { - "Eddsa": "521da91dc9bddb625bd0679d9e735def558761a34653624f5954f44bce6443a9" - }, - "path": "solana-1", - "domain_id": 1 - } -} -``` - -#### Ecdsa payload restrictions - -Note that an Ecdsa payload is subsequently represented as a Scalar on curve Secp256k1. This means that the payload must be strictly less than the field size `p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F` (see also [curve parameters](https://www.secg.org/sec2-v2.pdf#subsubsection.2.4.1) and [k256 implementation details](https://docs.rs/k256/latest/k256/struct.Scalar.html#method.from_repr)). - -### Submitting a confidential key derivation (ckd) request - -Users can submit a ckd request to the MPC network via the -`request_app_private_key` endpoint of this contract. Note that a **deposit is required to cover storage costs** (minimum 1 yoctoNEAR) to prevent abuse by malicious frontends. Any excess deposit is automatically refunded to the user. - -The ckd request takes the following arguments: - -- `derivation_path` (String): the derivation path (used to derive different keys from the same account). -- `"app_public_key": "bls12381g1:"` -- `domain_id` (integer): identifies the master key to use for deriving the ckd, and must correspond to bls12381. - -Note that `app_public_key` represents a valid point on curve BLS12381 (G1). - -Submitting a ckd request costs approximately 7 Tgas, but the contract requires -that at least 10 Tgas are attached to the transaction. - -#### Example - -_ckd request_ - -```Json -{ - "request": { - "derivation_path": "mykey", - "app_public_key": "bls12381g1:6KtVVcAAGacrjNGePN8bp3KV6fYGrw1rFsyc7cVJCqR16Zc2ZFg3HX3hSZxSfv1oH6", - "domain_id": 2 - } -} -``` - -### Changing the participant set - -The set of MPC participants can be changed, subject to following restrictions: - -- There must at least be `threshold` (the current threshold) number of current participants in the prospective participant set. -- The prospective threshold must be at least 60% of the number of participants (rounded upwards). -- The set of participants must have at least two participants. - -In order for a change to be accepted by the contract, all prospective participants must vote for it using the `vote_new_parameters` endpoint. Note that any new participants vote will only be accepted after at least `threshold` (the current threshold) old participants voted for the same participant set. - -#### Example - -```Json -{ - "prospective_epoch_id":1, - "proposal":{ - "threshold":3, - "participants":{ - "next_id":2, - "participants":[ - [ - "mpc-participant0.near", - 0, - { - "sign_pk":"ed25519:2XPuwqhg71RXRiTUMKGapd8FYWgXnxVvydYBK9tS1ex2", - "url":"http://mpc-service0.com" - } - ], - [ - "mpc-participant1.near", - 1, - { - "sign_pk":"ed25519:2XPuwqhg71RXRiTUMKGapd8FYWgXnxVvydYBK9tS1ex2", - "url":"http://mpc-service1.com" - } - ] - ] - } - } -} -``` - -### Adding a Key - -To generate a new threshold signature key, all participants must vote for it to be added via `vote_new_domain`. Only votes from existing participants will be accepted. - -```Json -{ - "domains":[ - { - "id":2, - "scheme":"Secp256k1" - }, - { - "id":3, - "scheme":"Ed25519" - }, - { - "id":4, - "scheme":"Bls12381" - } - ] -} -``` - -### Deployment - -After deploying the contract, it will first be in an uninitialized state. The owner will need to initialize it via `init`, providing the set of participants and threshold parameters. - -The contract will then switch to running state, where further operations (like initializing keys, or changing the participant set), can be taken. - -### Protocol State - -The following protocol state transitions are allowed. - -```mermaid -stateDiagram-v2 - direction LR - [*] --> NotInitialized : deploy - NotInitialized --> Running : init - Running --> Initializing : vote_add_domains - Running --> Resharing : vote_new_parameters - Initializing --> Running : vote_pk - Initializing --> Running : vote_cancel_keygen - Resharing --> Running : vote_reshared - Resharing --> Resharing : vote_new_parameters -``` - -## Contract API - -### User API - -| Function | Behavior | Return Value | Gas requirement | Effective Gas Cost | -| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------- | --------------- | ------------------ | -| `sign(request: SignRequestArgs)` | Submits a signature request to the contract. Requires a deposit to cover storage costs (minimum 1 yoctoNEAR). Excess deposit is refunded. Re-submitting the same request before the original request timed out or has been responded to may cause both requests to fail. | deferred to promise | `15 Tgas` | `~7 Tgas` | -| `request_app_private_key(request: CKDRequestArgs)` | Submits a confidential key derivation (CKD) request to the contract. Requires a deposit to cover storage costs (minimum 1 yoctoNEAR). Excess deposit is refunded. Re-submitting the same request before the original request timed out or has been responded to may cause both requests to fail. | deferred to promise | `15 Tgas` | `~7 Tgas` | -| `public_key(domain: Option)` | Read-only function; returns the public key used for the given domain (defaulting to first). | `Result` | | | -| `derived_public_key(path: String, predecessor: Option, domain: Option)` | Generates a derived public key for a given path and account, for the given domain (defaulting to first). | `Result` | | | - -#### SignRequestArgs (Latest version) - -The `sign` request takes the following arguments: - -- `path` (String): the derivation path. -- `payload_v2`: either `{"Ecdsa": ""}` or `{"Eddsa": ""}` -- `domain_id` (integer): the domain ID that identifies the key and signature scheme to use for signing. - -#### CKDRequestArgs (Latest version) - -The `request_app_private_key` request takes the following arguments: - -- `derivation_path` (String): the derivation path. -- `app_public_key` (String): the ephemeral public key to encrypt the generated confidential key -- `domain_id` (integer): the domain ID that identifies the key and signature scheme to use to generate the confidential key - -#### SignRequestArgs (Legacy version for backwards compatibility with V1) - -- The legacy argument `payload` can be used in place of `payload_v2`; the format for that is an array of 32 integer bytes. This argument can only be used - to pass in an ECDSA payload. -- The legacy argument `key_version` can be used in place of `domain_id` and means the same thing. - -### Participants API - -These functions require the caller to be a participant or candidate. - -| Function | Behavior | Return Value | Gas Requirement | Effective Gas Cost | -| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | --------------- | ------------------ | -| `respond(request: SignatureRequest, response: SignatureResponse)` | Processes a response to a signature request, verifying its validity and ensuring proper state cleanup. | `Result<(), Error>` | 10Tgas | ~6Tgas | -| `respond_ckd(request: CKDRequest, response: CKDResponse)` | Processes a response to a ckd request, ensuring proper state cleanup. | `Result<(), Error>` | 10Tgas | ~6Tgas | -| `vote_add_domains(domains: Vec)` | Votes to add new domains (new keys) to the MPC network; newly proposed domain IDs must start from next_domain_id and be contiguous. | `Result<(), Error>` | TBD | TBD | -| `vote_new_parameters(prospective_epoch_id: EpochId, proposal: ThresholdParameters)` | Votes to change the set of participants as well as the new threshold for the network. (Prospective epoch ID must be 1 plus current) | `Result<(), Error>` | TBD | TBD | -| `vote_code_hash(code_hash: CodeHash)` | Votes to add new whitelisted TEE Docker image code hashes. | `Result<(), Error>` | TBD | TBD | -| `start_keygen_instance(key_event_id: KeyEventId)` | For Initializing state only. Starts a new attempt to generate a key (key_event_id must be the expected one) | `Result<(), Error>` | TBD | TBD | -| `start_resharing_instance(key_event_id: KeyEventId)` | For Resharing state only. Starts a new attempt to reshare a key (key_event_id must be the expected one) | `Result<(), Error>` | TBD | TBD | -| `vote_pk(key_event_id: KeyEventId, public_key: PublicKey)` | For Initializing state only. Votes for the public key for the given generation attempt; if enough votes are collected, transitions to the next domain to generate a key for, or if all domains are completed, transitions into Running. | `Result<(), Error>` | TBD | TBD | -| `vote_reshared(key_event_id: KeyEventId)` | For Resharing state only. Votes for the success of the given resharing attempt; if enough votes are collected, transitions to the next domain to reshare for, or if all domains are completed, transitions into Running. | `Result<(), Error>` | TBD | TBD | -| `vote_cancel_keygen(next_domain_id: u64)` | For Initializing state only. Votes to cancel the key generation (identified by the next_domain_id) and revert to the Running state. | `Result<(), Error>` | TBD | TBD | -| `propose_update(args: ProposeUpdateArgs)` | Proposes an update to the contract, requiring an attached deposit. | `Result` | TBD | TBD | -| `vote_update(id: UpdateId)` | Votes on a proposed update. If the threshold is met, the update is executed. | `Result` | TBD | TBD | -| `propose_join(proposed_tee_participant: DstackAttestation, signer_pk: PublicKey)` | Submits the tee participant info for a potential candidate. c.f. TEE section | `Result<(), Error>` | TBD | TBD | - -### Developer API - -| Function | Behavior | Return Value | Gas Requirement | Effective Gas Cost | -| -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | --------------- | ------------------ | -| `init(parameters: ThresholdParameters, init_config: Option)` | Initializes the contract with a threshold, candidate participants, and config values. Can only be called once. This sets the contract state to `Running` with zero domains. vote_add_domains can be called to initialize key generation. | `Result` | TBD | TBD | -| `state()` | Returns the current state of the contract. | `&ProtocolContractState` | TBD | TBD | -| `get_pending_request(request: &SignatureRequest)` | Retrieves pending signature requests. | `Option` | TBD | TBD | -| `get_pending_ckd_request(request: &CKDRequest)` | Retrieves pending confidential key derivation requests. | `Option` | TBD | TBD | -| `config()` | Returns the contract configuration. | `&ConfigV1` | TBD | TBD | -| `version()` | Returns the contract version. | `String` | TBD | TBD | -| `update_config(config: ConfigV1)` | Updates the contract configuration for `V1`. | `()` | TBD | TBD | -| `clean_tee_status()` | Private endpoint. Cleans up TEE information for non-participants after resharing. Only callable by the contract itself via a promise. | `Result<(), Error>` | TBD | TBD | - -## Building the contract - -During development, it's recommended to build non-deterministically using [cargo-near](https://github.com/near/cargo-near). - -```bash -cargo near build non-reproducible-wasm --features abi --manifest-path crates/contract/Cargo.toml --locked -``` - -The contract can also be built deterministically. This requires `docker` to be installed. - -```bash -cargo near build reproducible-wasm --features abi --manifest-path crates/contract/Cargo.toml -``` - -## TEE Specific information - -The MPC nodes will eventually run inside a Trusted Execution Environments (TEE). The network is currently in a transitioning period, where both operation modes (TEE and non-TEE) are supported, however, the TEE support is at least as of June 2025, highly experimental and not stable. - -Participants that run their node inside a TEE will have to submit the following TEE related data to the contract: - -```rust -pub struct DstackAttestation { - /// TEE Remote Attestation Quote that proves the participant's identity. - pub quote: Quote, - /// Supplemental data for the TEE quote, including Intel certificates to verify it came from - /// genuine Intel hardware, along with details about the Trusted Computing Base (TCB) - /// versioning, status, and other relevant info. - pub collateral: Collateral, - /// Dstack event log. - pub tcb_info: TcbInfo, - /// Expected measurements for the TEE quote. - pub expected_measurements: ExpectedMeasurements, -} -``` - -The prospective node operator can retrieve that data from the web endpoint (`:8080/get_public_data`). - -The process of doing so is as follows: - -1. The prospective participants set up their MPC inside their TEE environment (todo: [#550](https://github.com/near/mpc/issues/550), documentation to follow). -2. The prospective participants fetch their TEE related information from their logs. -3. The prospective participants add the `near_signer_public_key` from the web endpoint (`:8080/get_public_data`) as an access key to their node operator account, eligible for calling the MPC contract (`v1.signer` on mainnet or `v1.signer-prod.testnet` on testnet). Participants should provide sufficient funding to this key. -4. The prospective participants add the `near_responder_public_keys` from the web endpoint to a different account and provide sufficient funding to it. -5. The participants submit their data to the contract via `propose_join`. -*/ -#![deny(clippy::mod_module_files)] -#![allow(clippy::disallowed_types)] -#[prelude_import] -use std::prelude::rust_2021::*; -#[macro_use] -extern crate std; -pub mod config { - use near_sdk::near; - /// Default for `key_event_timeout_blocks`. - const DEFAULT_KEY_EVENT_TIMEOUT_BLOCKS: u64 = 30; - /// Maximum time after which TEE MPC nodes must be upgraded to the latest version - const DEFAULT_TEE_UPGRADE_DEADLINE_DURATION_SECONDS: u64 = 7 * 24 * 60 * 60; - /// Amount of gas to deposit when creating an internal upgrade transaction promise. - /// Note this deposit must be less than 300, as the total gas usage including the - /// initial call itself to vote for the update can not exceed 300 Tgas. - const DEFAULT_CONTRACT_UPGRADE_DEPOSIT_TERA_GAS: u64 = 50; - /// Gas required for a sign request - const DEFAULT_SIGN_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS: u64 = 15; - /// Gas required for a CKD request - const DEFAULT_CKD_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS: u64 = 15; - /// Prepaid gas for a `return_signature_and_clean_state_on_success` call - const DEFAULT_RETURN_SIGNATURE_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS: u64 = 7; - /// Prepaid gas for a `return_ck_and_clean_state_on_success` call - const DEFAULT_RETURN_CK_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS: u64 = 7; - /// Prepaid gas for a `fail_on_timeout` call - const DEFAULT_FAIL_ON_TIMEOUT_TERA_GAS: u64 = 2; - /// Prepaid gas for a `clean_tee_status` call - const DEFAULT_CLEAN_TEE_STATUS_TERA_GAS: u64 = 10; - /// Prepaid gas for a `cleanup_orphaned_node_migrations` call - /// todo: benchmark [#1164](https://github.com/near/mpc/issues/1164) - const DEFAULT_CLEANUP_ORPHANED_NODE_MIGRATIONS_TERA_GAS: u64 = 3; - /// Prepaid gas for a `remove_non_participant_update_votes` call - const DEFAULT_REMOVE_NON_PARTICIPANT_UPDATE_VOTES_TERA_GAS: u64 = 5; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Config for V2 of the contract. - pub(crate) struct Config { - /// If a key event attempt has not successfully completed within this many blocks, - /// it is considered failed. - pub(crate) key_event_timeout_blocks: u64, - /// The grace period duration for expiry of old mpc image hashes once a new one is added. - pub(crate) tee_upgrade_deadline_duration_seconds: u64, - /// Amount of gas to deposit for contract and config updates. - pub(crate) contract_upgrade_deposit_tera_gas: u64, - /// Gas required for a sign request. - pub(crate) sign_call_gas_attachment_requirement_tera_gas: u64, - /// Gas required for a CKD request. - pub(crate) ckd_call_gas_attachment_requirement_tera_gas: u64, - /// Prepaid gas for a `return_signature_and_clean_state_on_success` call. - pub(crate) return_signature_and_clean_state_on_success_call_tera_gas: u64, - /// Prepaid gas for a `return_ck_and_clean_state_on_success` call. - pub(crate) return_ck_and_clean_state_on_success_call_tera_gas: u64, - /// Prepaid gas for a `fail_on_timeout` call. - pub(crate) fail_on_timeout_tera_gas: u64, - /// Prepaid gas for a `clean_tee_status` call. - pub(crate) clean_tee_status_tera_gas: u64, - /// Prepaid gas for a `cleanup_orphaned_node_migrations` call. - pub(crate) cleanup_orphaned_node_migrations_tera_gas: u64, - /// Prepaid gas for a `remove_non_participant_update_votes` call. - pub(crate) remove_non_participant_update_votes_tera_gas: u64, - } - #[automatically_derived] - impl ::core::clone::Clone for Config { - #[inline] - fn clone(&self) -> Config { - Config { - key_event_timeout_blocks: ::core::clone::Clone::clone( - &self.key_event_timeout_blocks, - ), - tee_upgrade_deadline_duration_seconds: ::core::clone::Clone::clone( - &self.tee_upgrade_deadline_duration_seconds, - ), - contract_upgrade_deposit_tera_gas: ::core::clone::Clone::clone( - &self.contract_upgrade_deposit_tera_gas, - ), - sign_call_gas_attachment_requirement_tera_gas: ::core::clone::Clone::clone( - &self.sign_call_gas_attachment_requirement_tera_gas, - ), - ckd_call_gas_attachment_requirement_tera_gas: ::core::clone::Clone::clone( - &self.ckd_call_gas_attachment_requirement_tera_gas, - ), - return_signature_and_clean_state_on_success_call_tera_gas: ::core::clone::Clone::clone( - &self.return_signature_and_clean_state_on_success_call_tera_gas, - ), - return_ck_and_clean_state_on_success_call_tera_gas: ::core::clone::Clone::clone( - &self.return_ck_and_clean_state_on_success_call_tera_gas, - ), - fail_on_timeout_tera_gas: ::core::clone::Clone::clone( - &self.fail_on_timeout_tera_gas, - ), - clean_tee_status_tera_gas: ::core::clone::Clone::clone( - &self.clean_tee_status_tera_gas, - ), - cleanup_orphaned_node_migrations_tera_gas: ::core::clone::Clone::clone( - &self.cleanup_orphaned_node_migrations_tera_gas, - ), - remove_non_participant_update_votes_tera_gas: ::core::clone::Clone::clone( - &self.remove_non_participant_update_votes_tera_gas, - ), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Config { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "key_event_timeout_blocks", - "tee_upgrade_deadline_duration_seconds", - "contract_upgrade_deposit_tera_gas", - "sign_call_gas_attachment_requirement_tera_gas", - "ckd_call_gas_attachment_requirement_tera_gas", - "return_signature_and_clean_state_on_success_call_tera_gas", - "return_ck_and_clean_state_on_success_call_tera_gas", - "fail_on_timeout_tera_gas", - "clean_tee_status_tera_gas", - "cleanup_orphaned_node_migrations_tera_gas", - "remove_non_participant_update_votes_tera_gas", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.key_event_timeout_blocks, - &self.tee_upgrade_deadline_duration_seconds, - &self.contract_upgrade_deposit_tera_gas, - &self.sign_call_gas_attachment_requirement_tera_gas, - &self.ckd_call_gas_attachment_requirement_tera_gas, - &self.return_signature_and_clean_state_on_success_call_tera_gas, - &self.return_ck_and_clean_state_on_success_call_tera_gas, - &self.fail_on_timeout_tera_gas, - &self.clean_tee_status_tera_gas, - &self.cleanup_orphaned_node_migrations_tera_gas, - &&self.remove_non_participant_update_votes_tera_gas, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "Config", - names, - values, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Config {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Config { - #[inline] - fn eq(&self, other: &Config) -> bool { - self.key_event_timeout_blocks == other.key_event_timeout_blocks - && self.tee_upgrade_deadline_duration_seconds - == other.tee_upgrade_deadline_duration_seconds - && self.contract_upgrade_deposit_tera_gas - == other.contract_upgrade_deposit_tera_gas - && self.sign_call_gas_attachment_requirement_tera_gas - == other.sign_call_gas_attachment_requirement_tera_gas - && self.ckd_call_gas_attachment_requirement_tera_gas - == other.ckd_call_gas_attachment_requirement_tera_gas - && self.return_signature_and_clean_state_on_success_call_tera_gas - == other.return_signature_and_clean_state_on_success_call_tera_gas - && self.return_ck_and_clean_state_on_success_call_tera_gas - == other.return_ck_and_clean_state_on_success_call_tera_gas - && self.fail_on_timeout_tera_gas == other.fail_on_timeout_tera_gas - && self.clean_tee_status_tera_gas == other.clean_tee_status_tera_gas - && self.cleanup_orphaned_node_migrations_tera_gas - == other.cleanup_orphaned_node_migrations_tera_gas - && self.remove_non_participant_update_votes_tera_gas - == other.remove_non_participant_update_votes_tera_gas - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Config { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for Config { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.key_event_timeout_blocks, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.tee_upgrade_deadline_duration_seconds, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.contract_upgrade_deposit_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.sign_call_gas_attachment_requirement_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.ckd_call_gas_attachment_requirement_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.return_signature_and_clean_state_on_success_call_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.return_ck_and_clean_state_on_success_call_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.fail_on_timeout_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.clean_tee_status_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.cleanup_orphaned_node_migrations_tera_gas, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.remove_non_participant_update_votes_tera_gas, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for Config { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - key_event_timeout_blocks: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - tee_upgrade_deadline_duration_seconds: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - contract_upgrade_deposit_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - sign_call_gas_attachment_requirement_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - ckd_call_gas_attachment_requirement_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - return_signature_and_clean_state_on_success_call_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - return_ck_and_clean_state_on_success_call_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - fail_on_timeout_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - clean_tee_status_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - cleanup_orphaned_node_migrations_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - remove_non_participant_update_votes_tera_gas: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Config { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Config", - false as usize + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key_event_timeout_blocks", - &self.key_event_timeout_blocks, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "tee_upgrade_deadline_duration_seconds", - &self.tee_upgrade_deadline_duration_seconds, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "contract_upgrade_deposit_tera_gas", - &self.contract_upgrade_deposit_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "sign_call_gas_attachment_requirement_tera_gas", - &self.sign_call_gas_attachment_requirement_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "ckd_call_gas_attachment_requirement_tera_gas", - &self.ckd_call_gas_attachment_requirement_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "return_signature_and_clean_state_on_success_call_tera_gas", - &self.return_signature_and_clean_state_on_success_call_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "return_ck_and_clean_state_on_success_call_tera_gas", - &self.return_ck_and_clean_state_on_success_call_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "fail_on_timeout_tera_gas", - &self.fail_on_timeout_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "clean_tee_status_tera_gas", - &self.clean_tee_status_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "cleanup_orphaned_node_migrations_tera_gas", - &self.cleanup_orphaned_node_migrations_tera_gas, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "remove_non_participant_update_votes_tera_gas", - &self.remove_non_participant_update_votes_tera_gas, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Config { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __field6, - __field7, - __field8, - __field9, - __field10, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - 4u64 => _serde::__private228::Ok(__Field::__field4), - 5u64 => _serde::__private228::Ok(__Field::__field5), - 6u64 => _serde::__private228::Ok(__Field::__field6), - 7u64 => _serde::__private228::Ok(__Field::__field7), - 8u64 => _serde::__private228::Ok(__Field::__field8), - 9u64 => _serde::__private228::Ok(__Field::__field9), - 10u64 => _serde::__private228::Ok(__Field::__field10), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "key_event_timeout_blocks" => { - _serde::__private228::Ok(__Field::__field0) - } - "tee_upgrade_deadline_duration_seconds" => { - _serde::__private228::Ok(__Field::__field1) - } - "contract_upgrade_deposit_tera_gas" => { - _serde::__private228::Ok(__Field::__field2) - } - "sign_call_gas_attachment_requirement_tera_gas" => { - _serde::__private228::Ok(__Field::__field3) - } - "ckd_call_gas_attachment_requirement_tera_gas" => { - _serde::__private228::Ok(__Field::__field4) - } - "return_signature_and_clean_state_on_success_call_tera_gas" => { - _serde::__private228::Ok(__Field::__field5) - } - "return_ck_and_clean_state_on_success_call_tera_gas" => { - _serde::__private228::Ok(__Field::__field6) - } - "fail_on_timeout_tera_gas" => { - _serde::__private228::Ok(__Field::__field7) - } - "clean_tee_status_tera_gas" => { - _serde::__private228::Ok(__Field::__field8) - } - "cleanup_orphaned_node_migrations_tera_gas" => { - _serde::__private228::Ok(__Field::__field9) - } - "remove_non_participant_update_votes_tera_gas" => { - _serde::__private228::Ok(__Field::__field10) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"key_event_timeout_blocks" => { - _serde::__private228::Ok(__Field::__field0) - } - b"tee_upgrade_deadline_duration_seconds" => { - _serde::__private228::Ok(__Field::__field1) - } - b"contract_upgrade_deposit_tera_gas" => { - _serde::__private228::Ok(__Field::__field2) - } - b"sign_call_gas_attachment_requirement_tera_gas" => { - _serde::__private228::Ok(__Field::__field3) - } - b"ckd_call_gas_attachment_requirement_tera_gas" => { - _serde::__private228::Ok(__Field::__field4) - } - b"return_signature_and_clean_state_on_success_call_tera_gas" => { - _serde::__private228::Ok(__Field::__field5) - } - b"return_ck_and_clean_state_on_success_call_tera_gas" => { - _serde::__private228::Ok(__Field::__field6) - } - b"fail_on_timeout_tera_gas" => { - _serde::__private228::Ok(__Field::__field7) - } - b"clean_tee_status_tera_gas" => { - _serde::__private228::Ok(__Field::__field8) - } - b"cleanup_orphaned_node_migrations_tera_gas" => { - _serde::__private228::Ok(__Field::__field9) - } - b"remove_non_participant_update_votes_tera_gas" => { - _serde::__private228::Ok(__Field::__field10) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Config; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct Config", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field5 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 5usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field6 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 6usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field7 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 7usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field8 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 8usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field9 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 9usize, - &"struct Config with 11 elements", - ), - ); - } - }; - let __field10 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 10usize, - &"struct Config with 11 elements", - ), - ); - } - }; - _serde::__private228::Ok(Config { - key_event_timeout_blocks: __field0, - tee_upgrade_deadline_duration_seconds: __field1, - contract_upgrade_deposit_tera_gas: __field2, - sign_call_gas_attachment_requirement_tera_gas: __field3, - ckd_call_gas_attachment_requirement_tera_gas: __field4, - return_signature_and_clean_state_on_success_call_tera_gas: __field5, - return_ck_and_clean_state_on_success_call_tera_gas: __field6, - fail_on_timeout_tera_gas: __field7, - clean_tee_status_tera_gas: __field8, - cleanup_orphaned_node_migrations_tera_gas: __field9, - remove_non_participant_update_votes_tera_gas: __field10, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - let mut __field3: _serde::__private228::Option = _serde::__private228::None; - let mut __field4: _serde::__private228::Option = _serde::__private228::None; - let mut __field5: _serde::__private228::Option = _serde::__private228::None; - let mut __field6: _serde::__private228::Option = _serde::__private228::None; - let mut __field7: _serde::__private228::Option = _serde::__private228::None; - let mut __field8: _serde::__private228::Option = _serde::__private228::None; - let mut __field9: _serde::__private228::Option = _serde::__private228::None; - let mut __field10: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "key_event_timeout_blocks", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "tee_upgrade_deadline_duration_seconds", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "contract_upgrade_deposit_tera_gas", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private228::Option::is_some(&__field3) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "sign_call_gas_attachment_requirement_tera_gas", - ), - ); - } - __field3 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private228::Option::is_some(&__field4) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "ckd_call_gas_attachment_requirement_tera_gas", - ), - ); - } - __field4 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field5 => { - if _serde::__private228::Option::is_some(&__field5) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "return_signature_and_clean_state_on_success_call_tera_gas", - ), - ); - } - __field5 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field6 => { - if _serde::__private228::Option::is_some(&__field6) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "return_ck_and_clean_state_on_success_call_tera_gas", - ), - ); - } - __field6 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field7 => { - if _serde::__private228::Option::is_some(&__field7) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "fail_on_timeout_tera_gas", - ), - ); - } - __field7 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field8 => { - if _serde::__private228::Option::is_some(&__field8) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "clean_tee_status_tera_gas", - ), - ); - } - __field8 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field9 => { - if _serde::__private228::Option::is_some(&__field9) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "cleanup_orphaned_node_migrations_tera_gas", - ), - ); - } - __field9 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field10 => { - if _serde::__private228::Option::is_some(&__field10) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "remove_non_participant_update_votes_tera_gas", - ), - ); - } - __field10 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "key_event_timeout_blocks", - )? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "tee_upgrade_deadline_duration_seconds", - )? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "contract_upgrade_deposit_tera_gas", - )? - } - }; - let __field3 = match __field3 { - _serde::__private228::Some(__field3) => __field3, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "sign_call_gas_attachment_requirement_tera_gas", - )? - } - }; - let __field4 = match __field4 { - _serde::__private228::Some(__field4) => __field4, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "ckd_call_gas_attachment_requirement_tera_gas", - )? - } - }; - let __field5 = match __field5 { - _serde::__private228::Some(__field5) => __field5, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "return_signature_and_clean_state_on_success_call_tera_gas", - )? - } - }; - let __field6 = match __field6 { - _serde::__private228::Some(__field6) => __field6, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "return_ck_and_clean_state_on_success_call_tera_gas", - )? - } - }; - let __field7 = match __field7 { - _serde::__private228::Some(__field7) => __field7, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "fail_on_timeout_tera_gas", - )? - } - }; - let __field8 = match __field8 { - _serde::__private228::Some(__field8) => __field8, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "clean_tee_status_tera_gas", - )? - } - }; - let __field9 = match __field9 { - _serde::__private228::Some(__field9) => __field9, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "cleanup_orphaned_node_migrations_tera_gas", - )? - } - }; - let __field10 = match __field10 { - _serde::__private228::Some(__field10) => __field10, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "remove_non_participant_update_votes_tera_gas", - )? - } - }; - _serde::__private228::Ok(Config { - key_event_timeout_blocks: __field0, - tee_upgrade_deadline_duration_seconds: __field1, - contract_upgrade_deposit_tera_gas: __field2, - sign_call_gas_attachment_requirement_tera_gas: __field3, - ckd_call_gas_attachment_requirement_tera_gas: __field4, - return_signature_and_clean_state_on_success_call_tera_gas: __field5, - return_ck_and_clean_state_on_success_call_tera_gas: __field6, - fail_on_timeout_tera_gas: __field7, - clean_tee_status_tera_gas: __field8, - cleanup_orphaned_node_migrations_tera_gas: __field9, - remove_non_participant_update_votes_tera_gas: __field10, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "key_event_timeout_blocks", - "tee_upgrade_deadline_duration_seconds", - "contract_upgrade_deposit_tera_gas", - "sign_call_gas_attachment_requirement_tera_gas", - "ckd_call_gas_attachment_requirement_tera_gas", - "return_signature_and_clean_state_on_success_call_tera_gas", - "return_ck_and_clean_state_on_success_call_tera_gas", - "fail_on_timeout_tera_gas", - "clean_tee_status_tera_gas", - "cleanup_orphaned_node_migrations_tera_gas", - "remove_non_participant_update_votes_tera_gas", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Config", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl Default for Config { - fn default() -> Self { - Self { - key_event_timeout_blocks: DEFAULT_KEY_EVENT_TIMEOUT_BLOCKS, - tee_upgrade_deadline_duration_seconds: DEFAULT_TEE_UPGRADE_DEADLINE_DURATION_SECONDS, - contract_upgrade_deposit_tera_gas: DEFAULT_CONTRACT_UPGRADE_DEPOSIT_TERA_GAS, - sign_call_gas_attachment_requirement_tera_gas: DEFAULT_SIGN_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS, - ckd_call_gas_attachment_requirement_tera_gas: DEFAULT_CKD_CALL_GAS_ATTACHMENT_REQUIREMENT_TERA_GAS, - return_signature_and_clean_state_on_success_call_tera_gas: DEFAULT_RETURN_SIGNATURE_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS, - return_ck_and_clean_state_on_success_call_tera_gas: DEFAULT_RETURN_CK_AND_CLEAN_STATE_ON_SUCCESS_CALL_TERA_GAS, - fail_on_timeout_tera_gas: DEFAULT_FAIL_ON_TIMEOUT_TERA_GAS, - clean_tee_status_tera_gas: DEFAULT_CLEAN_TEE_STATUS_TERA_GAS, - cleanup_orphaned_node_migrations_tera_gas: DEFAULT_CLEANUP_ORPHANED_NODE_MIGRATIONS_TERA_GAS, - remove_non_participant_update_votes_tera_gas: DEFAULT_REMOVE_NON_PARTICIPANT_UPDATE_VOTES_TERA_GAS, - } - } - } -} -pub mod crypto_shared { - pub mod kdf { - use crate::{crypto_shared::types::k256_types, primitives::signature::Tweak}; - use anyhow::Context; - use curve25519_dalek::constants::ED25519_BASEPOINT_POINT; - use k256::{ - ecdsa::{RecoveryId, Signature}, - elliptic_curve::{ - point::AffineCoordinates, sec1::ToEncodedPoint, CurveArithmetic, - PrimeField, - }, - Secp256k1, - }; - use near_account_id::AccountId; - use sha3::{Digest, Sha3_256}; - use contract_interface::types as dtos; - const TWEAK_DERIVATION_PREFIX: &str = "near-mpc-recovery v0.1.0 epsilon derivation:"; - pub fn derive_tweak(predecessor_id: &AccountId, path: &str) -> Tweak { - let hash: [u8; 32] = derive_from_path( - TWEAK_DERIVATION_PREFIX, - predecessor_id, - path, - ); - Tweak::new(hash) - } - const APP_ID_DERIVATION_PREFIX: &str = "near-mpc v0.1.0 app_id derivation:"; - pub fn derive_app_id( - predecessor_id: &AccountId, - derivation_path: &str, - ) -> dtos::CkdAppId { - let hash: [u8; 32] = derive_from_path( - APP_ID_DERIVATION_PREFIX, - predecessor_id, - derivation_path, - ); - hash.into() - } - fn derive_from_path( - derivation_prefix: &str, - predecessor_id: &AccountId, - path: &str, - ) -> [u8; 32] { - let derivation_path = ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("{2}{0},{1}", predecessor_id, path, derivation_prefix), - ); - res - }); - let mut hasher = Sha3_256::new(); - hasher.update(derivation_path); - let hash: [u8; 32] = hasher.finalize().into(); - hash - } - pub struct TweakNotOnCurve; - #[automatically_derived] - impl ::core::fmt::Debug for TweakNotOnCurve { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "TweakNotOnCurve") - } - } - #[automatically_derived] - impl ::core::clone::Clone for TweakNotOnCurve { - #[inline] - fn clone(&self) -> TweakNotOnCurve { - TweakNotOnCurve - } - } - pub fn derive_key_secp256k1( - public_key: &k256_types::PublicKey, - tweak: &Tweak, - ) -> Result { - let tweak = k256::Scalar::from_repr(tweak.as_bytes().into()) - .into_option() - .ok_or(TweakNotOnCurve)?; - Ok( - (::ProjectivePoint::GENERATOR * tweak - + public_key) - .to_affine(), - ) - } - pub fn derive_public_key_edwards_point_ed25519( - public_key_edwards_point: &curve25519_dalek::EdwardsPoint, - tweak: &Tweak, - ) -> curve25519_dalek::EdwardsPoint { - let tweak = curve25519_dalek::Scalar::from_bytes_mod_order(tweak.as_bytes()); - public_key_edwards_point + ED25519_BASEPOINT_POINT * tweak - } - /// Get the x coordinate of a point, as a scalar - pub fn x_coordinate( - point: &::AffinePoint, - ) -> ::Scalar { - <::Scalar as k256::elliptic_curve::ops::Reduce< - ::Uint, - >>::reduce_bytes(&point.x()) - } - pub fn check_ec_signature( - expected_pk: &k256::AffinePoint, - big_r: &k256::AffinePoint, - s: &k256::Scalar, - msg_hash: &[u8; 32], - recovery_id: u8, - ) -> anyhow::Result<()> { - let public_key = expected_pk.to_encoded_point(false); - let signature = k256::ecdsa::Signature::from_scalars(x_coordinate(big_r), s) - .context("cannot create signature from cait_sith signature")?; - let found_pk = recover( - msg_hash, - &signature, - RecoveryId::try_from(recovery_id).context("invalid recovery ID")?, - )? - .to_encoded_point(false); - if public_key == found_pk { - return Ok(()); - } - return ::anyhow::__private::Err({ - let error = ::anyhow::__private::format_err( - format_args!( - "cannot use either recovery id={0} to recover pubic key", - recovery_id, - ), - ); - error - }); - } - #[cfg(not(target_arch = "wasm32"))] - pub fn recover( - prehash: &[u8], - signature: &Signature, - recovery_id: RecoveryId, - ) -> anyhow::Result { - k256::ecdsa::VerifyingKey::recover_from_prehash( - prehash, - signature, - recovery_id, - ) - .context("Unable to recover public key") - } - } - pub mod types { - pub mod serializable { - //! Module that adds implementation of [`BorshSerialize`] and [`BorshDeserialize`] for - //! [`PublicKeyExtended`]. - use borsh::{BorshDeserialize, BorshSerialize}; - use curve25519_dalek::EdwardsPoint; - use k256::elliptic_curve::{group::GroupEncoding, subtle::CtOption}; - use serde::{Deserialize, Serialize}; - pub struct SerializableEdwardsPoint(EdwardsPoint); - #[automatically_derived] - impl ::core::fmt::Debug for SerializableEdwardsPoint { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "SerializableEdwardsPoint", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SerializableEdwardsPoint {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SerializableEdwardsPoint { - #[inline] - fn eq(&self, other: &SerializableEdwardsPoint) -> bool { - self.0 == other.0 - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SerializableEdwardsPoint { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "SerializableEdwardsPoint", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SerializableEdwardsPoint { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - SerializableEdwardsPoint, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SerializableEdwardsPoint; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct SerializableEdwardsPoint", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: EdwardsPoint = ::deserialize( - __e, - )?; - _serde::__private228::Ok(SerializableEdwardsPoint(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - EdwardsPoint, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct SerializableEdwardsPoint with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(SerializableEdwardsPoint(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "SerializableEdwardsPoint", - __Visitor { - marker: _serde::__private228::PhantomData::< - SerializableEdwardsPoint, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::cmp::Eq for SerializableEdwardsPoint { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for SerializableEdwardsPoint { - #[inline] - fn clone(&self) -> SerializableEdwardsPoint { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for SerializableEdwardsPoint {} - #[allow(unreachable_code)] - #[automatically_derived] - impl derive_more::core::convert::From<(EdwardsPoint)> - for SerializableEdwardsPoint { - #[inline] - fn from(value: (EdwardsPoint)) -> Self { - SerializableEdwardsPoint(value) - } - } - #[allow(unreachable_code)] - #[automatically_derived] - impl derive_more::core::convert::AsRef - for SerializableEdwardsPoint { - #[inline] - fn as_ref(&self) -> &EdwardsPoint { - &self.0 - } - } - #[allow(unreachable_code)] - #[automatically_derived] - impl derive_more::with_trait::Deref for SerializableEdwardsPoint { - type Target = EdwardsPoint; - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl GroupEncoding for SerializableEdwardsPoint { - type Repr = [u8; 32]; - fn from_bytes(bytes: &Self::Repr) -> CtOption { - EdwardsPoint::from_bytes(bytes).map(Into::into) - } - fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption { - Self::from_bytes(bytes) - } - fn to_bytes(&self) -> Self::Repr { - self.compress().to_bytes() - } - } - impl BorshSerialize for SerializableEdwardsPoint { - fn serialize( - &self, - writer: &mut W, - ) -> std::io::Result<()> { - let bytes = self.0.to_bytes(); - BorshSerialize::serialize(&bytes, writer) - } - } - impl BorshDeserialize for SerializableEdwardsPoint { - fn deserialize_reader( - reader: &mut R, - ) -> std::io::Result { - let bytes: [u8; 32] = BorshDeserialize::deserialize_reader(reader)?; - SerializableEdwardsPoint::from_bytes(&bytes) - .into_option() - .ok_or( - std::io::Error::new( - std::io::ErrorKind::InvalidData, - "The provided bytes is not a valid edwards point.", - ), - ) - } - } - } - use std::fmt::Display; - use borsh::{BorshDeserialize, BorshSerialize}; - use k256::{ - elliptic_curve::{group::GroupEncoding, CurveArithmetic, PrimeField}, - AffinePoint, Secp256k1, - }; - use serde::{Deserialize, Serialize}; - use serde_with::serde_as; - use serializable::SerializableEdwardsPoint; - use crate::{errors, IntoContractType, IntoInterfaceType}; - use contract_interface::types as dtos; - #[serde(tag = "scheme")] - pub enum SignatureResponse { - Secp256k1(k256_types::Signature), - Ed25519 { signature: ed25519_types::Signature }, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SignatureResponse { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - SignatureResponse::Secp256k1(ref __field0) => { - _serde::__private228::ser::serialize_tagged_newtype( - __serializer, - "SignatureResponse", - "Secp256k1", - "scheme", - "Secp256k1", - __field0, - ) - } - SignatureResponse::Ed25519 { ref signature } => { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SignatureResponse", - 0 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "scheme", - "Ed25519", - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "signature", - signature, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SignatureResponse { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => { - _serde::__private228::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "Secp256k1" => _serde::__private228::Ok(__Field::__field0), - "Ed25519" => _serde::__private228::Ok(__Field::__field1), - _ => { - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"Secp256k1" => _serde::__private228::Ok(__Field::__field0), - b"Ed25519" => _serde::__private228::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private228::from_utf8_lossy( - __value, - ); - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &["Secp256k1", "Ed25519"]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private228::de::TaggedContentVisitor::< - __Field, - >::new("scheme", "internally tagged enum SignatureResponse"), - )?; - let __deserializer = _serde::__private228::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::__private228::Result::map( - ::deserialize( - __deserializer, - ), - SignatureResponse::Secp256k1, - ) - } - __Field::__field1 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "signature" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"signature" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - SignatureResponse, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SignatureResponse; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct variant SignatureResponse::Ed25519", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - ed25519_types::Signature, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant SignatureResponse::Ed25519 with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(SignatureResponse::Ed25519 { - signature: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - ed25519_types::Signature, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "signature", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - ed25519_types::Signature, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("signature")? - } - }; - _serde::__private228::Ok(SignatureResponse::Ed25519 { - signature: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["signature"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private228::PhantomData::< - SignatureResponse, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for SignatureResponse { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - SignatureResponse::Secp256k1(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Secp256k1", - &__self_0, - ) - } - SignatureResponse::Ed25519 { signature: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Ed25519", - "signature", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for SignatureResponse { - #[inline] - fn clone(&self) -> SignatureResponse { - match self { - SignatureResponse::Secp256k1(__self_0) => { - SignatureResponse::Secp256k1( - ::core::clone::Clone::clone(__self_0), - ) - } - SignatureResponse::Ed25519 { signature: __self_0 } => { - SignatureResponse::Ed25519 { - signature: ::core::clone::Clone::clone(__self_0), - } - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SignatureResponse {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SignatureResponse { - #[inline] - fn eq(&self, other: &SignatureResponse) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - ( - SignatureResponse::Secp256k1(__self_0), - SignatureResponse::Secp256k1(__arg1_0), - ) => __self_0 == __arg1_0, - ( - SignatureResponse::Ed25519 { signature: __self_0 }, - SignatureResponse::Ed25519 { signature: __arg1_0 }, - ) => __self_0 == __arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for SignatureResponse { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - pub struct CKDResponse { - pub big_y: dtos::Bls12381G1PublicKey, - pub big_c: dtos::Bls12381G1PublicKey, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for CKDResponse { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "CKDResponse", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "big_y", - &self.big_y, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "big_c", - &self.big_c, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for CKDResponse { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "big_y" => _serde::__private228::Ok(__Field::__field0), - "big_c" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"big_y" => _serde::__private228::Ok(__Field::__field0), - b"big_c" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = CKDResponse; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct CKDResponse", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - dtos::Bls12381G1PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct CKDResponse with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - dtos::Bls12381G1PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct CKDResponse with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(CKDResponse { - big_y: __field0, - big_c: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - dtos::Bls12381G1PublicKey, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - dtos::Bls12381G1PublicKey, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("big_y"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - dtos::Bls12381G1PublicKey, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("big_c"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - dtos::Bls12381G1PublicKey, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("big_y")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("big_c")? - } - }; - _serde::__private228::Ok(CKDResponse { - big_y: __field0, - big_c: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["big_y", "big_c"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "CKDResponse", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for CKDResponse { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "CKDResponse", - "big_y", - &self.big_y, - "big_c", - &&self.big_c, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for CKDResponse { - #[inline] - fn clone(&self) -> CKDResponse { - CKDResponse { - big_y: ::core::clone::Clone::clone(&self.big_y), - big_c: ::core::clone::Clone::clone(&self.big_c), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for CKDResponse {} - #[automatically_derived] - impl ::core::cmp::PartialEq for CKDResponse { - #[inline] - fn eq(&self, other: &CKDResponse) -> bool { - self.big_y == other.big_y && self.big_c == other.big_c - } - } - #[automatically_derived] - impl ::core::cmp::Eq for CKDResponse { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - pub enum PublicKeyExtended { - Secp256k1 { near_public_key: near_sdk::PublicKey }, - Ed25519 { - /// Serialized compressed Edwards-y point. - near_public_key_compressed: near_sdk::PublicKey, - /// Decompressed Edwards point used for curve arithmetic operations. - edwards_point: SerializableEdwardsPoint, - }, - Bls12381 { public_key: dtos::PublicKey }, - } - #[automatically_derived] - impl ::core::fmt::Debug for PublicKeyExtended { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - PublicKeyExtended::Secp256k1 { near_public_key: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Secp256k1", - "near_public_key", - &__self_0, - ) - } - PublicKeyExtended::Ed25519 { - near_public_key_compressed: __self_0, - edwards_point: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Ed25519", - "near_public_key_compressed", - __self_0, - "edwards_point", - &__self_1, - ) - } - PublicKeyExtended::Bls12381 { public_key: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Bls12381", - "public_key", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for PublicKeyExtended {} - #[automatically_derived] - impl ::core::cmp::PartialEq for PublicKeyExtended { - #[inline] - fn eq(&self, other: &PublicKeyExtended) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - ( - PublicKeyExtended::Secp256k1 { near_public_key: __self_0 }, - PublicKeyExtended::Secp256k1 { near_public_key: __arg1_0 }, - ) => __self_0 == __arg1_0, - ( - PublicKeyExtended::Ed25519 { - near_public_key_compressed: __self_0, - edwards_point: __self_1, - }, - PublicKeyExtended::Ed25519 { - near_public_key_compressed: __arg1_0, - edwards_point: __arg1_1, - }, - ) => __self_0 == __arg1_0 && __self_1 == __arg1_1, - ( - PublicKeyExtended::Bls12381 { public_key: __self_0 }, - PublicKeyExtended::Bls12381 { public_key: __arg1_0 }, - ) => __self_0 == __arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for PublicKeyExtended { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for PublicKeyExtended { - #[inline] - fn clone(&self) -> PublicKeyExtended { - match self { - PublicKeyExtended::Secp256k1 { near_public_key: __self_0 } => { - PublicKeyExtended::Secp256k1 { - near_public_key: ::core::clone::Clone::clone(__self_0), - } - } - PublicKeyExtended::Ed25519 { - near_public_key_compressed: __self_0, - edwards_point: __self_1, - } => { - PublicKeyExtended::Ed25519 { - near_public_key_compressed: ::core::clone::Clone::clone( - __self_0, - ), - edwards_point: ::core::clone::Clone::clone(__self_1), - } - } - PublicKeyExtended::Bls12381 { public_key: __self_0 } => { - PublicKeyExtended::Bls12381 { - public_key: ::core::clone::Clone::clone(__self_0), - } - } - } - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for PublicKeyExtended { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - PublicKeyExtended::Secp256k1 { ref near_public_key } => { - let mut __serde_state = _serde::Serializer::serialize_struct_variant( - __serializer, - "PublicKeyExtended", - 0u32, - "Secp256k1", - 0 + 1, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "near_public_key", - near_public_key, - )?; - _serde::ser::SerializeStructVariant::end(__serde_state) - } - PublicKeyExtended::Ed25519 { - ref near_public_key_compressed, - ref edwards_point, - } => { - let mut __serde_state = _serde::Serializer::serialize_struct_variant( - __serializer, - "PublicKeyExtended", - 1u32, - "Ed25519", - 0 + 1 + 1, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "near_public_key_compressed", - near_public_key_compressed, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "edwards_point", - edwards_point, - )?; - _serde::ser::SerializeStructVariant::end(__serde_state) - } - PublicKeyExtended::Bls12381 { ref public_key } => { - let mut __serde_state = _serde::Serializer::serialize_struct_variant( - __serializer, - "PublicKeyExtended", - 2u32, - "Bls12381", - 0 + 1, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "public_key", - public_key, - )?; - _serde::ser::SerializeStructVariant::end(__serde_state) - } - } - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for PublicKeyExtended { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => { - _serde::__private228::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 3", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "Secp256k1" => _serde::__private228::Ok(__Field::__field0), - "Ed25519" => _serde::__private228::Ok(__Field::__field1), - "Bls12381" => _serde::__private228::Ok(__Field::__field2), - _ => { - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"Secp256k1" => _serde::__private228::Ok(__Field::__field0), - b"Ed25519" => _serde::__private228::Ok(__Field::__field1), - b"Bls12381" => _serde::__private228::Ok(__Field::__field2), - _ => { - let __value = &_serde::__private228::from_utf8_lossy( - __value, - ); - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = PublicKeyExtended; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "enum PublicKeyExtended", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "near_public_key" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"near_public_key" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - PublicKeyExtended, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = PublicKeyExtended; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct variant PublicKeyExtended::Secp256k1", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - near_sdk::PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant PublicKeyExtended::Secp256k1 with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(PublicKeyExtended::Secp256k1 { - near_public_key: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - near_sdk::PublicKey, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "near_public_key", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - near_sdk::PublicKey, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("near_public_key")? - } - }; - _serde::__private228::Ok(PublicKeyExtended::Secp256k1 { - near_public_key: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "near_public_key", - ]; - _serde::de::VariantAccess::struct_variant( - __variant, - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - PublicKeyExtended, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - (__Field::__field1, __variant) => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "near_public_key_compressed" => { - _serde::__private228::Ok(__Field::__field0) - } - "edwards_point" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"near_public_key_compressed" => { - _serde::__private228::Ok(__Field::__field0) - } - b"edwards_point" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - PublicKeyExtended, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = PublicKeyExtended; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct variant PublicKeyExtended::Ed25519", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - near_sdk::PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant PublicKeyExtended::Ed25519 with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - SerializableEdwardsPoint, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct variant PublicKeyExtended::Ed25519 with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(PublicKeyExtended::Ed25519 { - near_public_key_compressed: __field0, - edwards_point: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - near_sdk::PublicKey, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - SerializableEdwardsPoint, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "near_public_key_compressed", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - near_sdk::PublicKey, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "edwards_point", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - SerializableEdwardsPoint, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "near_public_key_compressed", - )? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("edwards_point")? - } - }; - _serde::__private228::Ok(PublicKeyExtended::Ed25519 { - near_public_key_compressed: __field0, - edwards_point: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "near_public_key_compressed", - "edwards_point", - ]; - _serde::de::VariantAccess::struct_variant( - __variant, - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - PublicKeyExtended, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - (__Field::__field2, __variant) => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "public_key" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"public_key" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - PublicKeyExtended, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = PublicKeyExtended; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct variant PublicKeyExtended::Bls12381", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - dtos::PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant PublicKeyExtended::Bls12381 with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(PublicKeyExtended::Bls12381 { - public_key: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - dtos::PublicKey, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "public_key", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - dtos::PublicKey, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("public_key")? - } - }; - _serde::__private228::Ok(PublicKeyExtended::Bls12381 { - public_key: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["public_key"]; - _serde::de::VariantAccess::struct_variant( - __variant, - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - PublicKeyExtended, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "Secp256k1", - "Ed25519", - "Bls12381", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "PublicKeyExtended", - VARIANTS, - __Visitor { - marker: _serde::__private228::PhantomData::< - PublicKeyExtended, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl borsh::ser::BorshSerialize for PublicKeyExtended { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - let variant_idx: u8 = match self { - PublicKeyExtended::Secp256k1 { .. } => 0u8, - PublicKeyExtended::Ed25519 { .. } => 1u8, - PublicKeyExtended::Bls12381 { .. } => 2u8, - }; - writer.write_all(&variant_idx.to_le_bytes())?; - match self { - PublicKeyExtended::Secp256k1 { near_public_key, .. } => { - borsh::BorshSerialize::serialize(near_public_key, writer)?; - } - PublicKeyExtended::Ed25519 { - near_public_key_compressed, - edwards_point, - .. - } => { - borsh::BorshSerialize::serialize( - near_public_key_compressed, - writer, - )?; - borsh::BorshSerialize::serialize(edwards_point, writer)?; - } - PublicKeyExtended::Bls12381 { public_key, .. } => { - borsh::BorshSerialize::serialize(public_key, writer)?; - } - } - Ok(()) - } - } - impl borsh::de::BorshDeserialize for PublicKeyExtended { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - let tag = ::deserialize_reader( - reader, - )?; - ::deserialize_variant(reader, tag) - } - } - impl borsh::de::EnumExt for PublicKeyExtended { - fn deserialize_variant<__R: borsh::io::Read>( - reader: &mut __R, - variant_tag: u8, - ) -> ::core::result::Result { - let mut return_value = if variant_tag == 0u8 { - PublicKeyExtended::Secp256k1 { - near_public_key: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - } - } else if variant_tag == 1u8 { - PublicKeyExtended::Ed25519 { - near_public_key_compressed: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - edwards_point: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - } - } else if variant_tag == 2u8 { - PublicKeyExtended::Bls12381 { - public_key: borsh::BorshDeserialize::deserialize_reader(reader)?, - } - } else { - return Err( - borsh::io::Error::new( - borsh::io::ErrorKind::InvalidData, - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Unexpected variant tag: {0:?}", variant_tag), - ); - res - }), - ), - ) - }; - Ok(return_value) - } - } - pub enum PublicKeyExtendedConversionError { - PublicKeyLengthMalformed, - FailedDecompressingToEdwardsPoint, - } - #[automatically_derived] - impl ::core::clone::Clone for PublicKeyExtendedConversionError { - #[inline] - fn clone(&self) -> PublicKeyExtendedConversionError { - match self { - PublicKeyExtendedConversionError::PublicKeyLengthMalformed => { - PublicKeyExtendedConversionError::PublicKeyLengthMalformed - } - PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint => { - PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for PublicKeyExtendedConversionError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - PublicKeyExtendedConversionError::PublicKeyLengthMalformed => { - "PublicKeyLengthMalformed" - } - PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint => { - "FailedDecompressingToEdwardsPoint" - } - }, - ) - } - } - impl Display for PublicKeyExtendedConversionError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let message = match self { - Self::PublicKeyLengthMalformed => { - "Provided public key has malformed length." - } - Self::FailedDecompressingToEdwardsPoint => { - "The provided compressed key can not be decompressed to an edwards point." - } - }; - f.write_str(message) - } - } - impl TryFrom for near_sdk::PublicKey { - type Error = errors::Error; - fn try_from( - public_key_extended: PublicKeyExtended, - ) -> Result { - match public_key_extended { - PublicKeyExtended::Secp256k1 { near_public_key } => { - Ok(near_public_key) - } - PublicKeyExtended::Ed25519 { near_public_key_compressed, .. } => { - Ok(near_public_key_compressed) - } - PublicKeyExtended::Bls12381 { public_key: _ } => { - Err( - errors::ConversionError::DataConversion - .message( - "Cannot convert Bls12381 key to near_sdk::PublicKey", - ), - )? - } - } - } - } - impl From for dtos::PublicKey { - fn from(public_key_extended: PublicKeyExtended) -> Self { - match public_key_extended { - PublicKeyExtended::Secp256k1 { near_public_key } => { - near_public_key.into_dto_type() - } - PublicKeyExtended::Ed25519 { near_public_key_compressed, .. } => { - near_public_key_compressed.into_dto_type() - } - PublicKeyExtended::Bls12381 { public_key } => public_key, - } - } - } - impl TryFrom for PublicKeyExtended { - type Error = PublicKeyExtendedConversionError; - fn try_from( - near_public_key: near_sdk::PublicKey, - ) -> Result { - let extended_key = match near_public_key.curve_type() { - near_sdk::CurveType::ED25519 => { - let public_key_bytes: &[u8; 32] = near_public_key - .as_bytes() - .get(1..) - .map(TryInto::try_into) - .ok_or( - PublicKeyExtendedConversionError::PublicKeyLengthMalformed, - )? - .map_err(|_| { - PublicKeyExtendedConversionError::PublicKeyLengthMalformed - })?; - let edwards_point = SerializableEdwardsPoint::from_bytes( - public_key_bytes, - ) - .into_option() - .ok_or( - PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint, - )?; - Self::Ed25519 { - near_public_key_compressed: near_public_key, - edwards_point, - } - } - near_sdk::CurveType::SECP256K1 => Self::Secp256k1 { near_public_key }, - }; - Ok(extended_key) - } - } - impl TryFrom for PublicKeyExtended { - type Error = PublicKeyExtendedConversionError; - fn try_from(public_key: dtos::PublicKey) -> Result { - let extended_key = match public_key { - dtos::PublicKey::Ed25519(inner_public_key) => { - let near_public_key = inner_public_key.into_contract_type(); - let public_key_bytes: &[u8; 32] = near_public_key - .as_bytes() - .get(1..) - .map(TryInto::try_into) - .ok_or( - PublicKeyExtendedConversionError::PublicKeyLengthMalformed, - )? - .map_err(|_| { - PublicKeyExtendedConversionError::PublicKeyLengthMalformed - })?; - let edwards_point = SerializableEdwardsPoint::from_bytes( - public_key_bytes, - ) - .into_option() - .ok_or( - PublicKeyExtendedConversionError::FailedDecompressingToEdwardsPoint, - )?; - Self::Ed25519 { - near_public_key_compressed: near_public_key, - edwards_point, - } - } - dtos::PublicKey::Secp256k1(inner_public_key) => { - let near_public_key = inner_public_key.into_contract_type(); - Self::Secp256k1 { near_public_key } - } - dtos::PublicKey::Bls12381(inner_public_key) => { - Self::Bls12381 { - public_key: dtos::PublicKey::from(inner_public_key), - } - } - }; - Ok(extended_key) - } - } - pub mod k256_types { - use super::*; - use k256::Scalar; - pub type PublicKey = ::AffinePoint; - pub struct SerializableScalar { - pub scalar: Scalar, - } - #[automatically_derived] - impl ::core::fmt::Debug for SerializableScalar { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "SerializableScalar", - "scalar", - &&self.scalar, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SerializableScalar {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SerializableScalar { - #[inline] - fn eq(&self, other: &SerializableScalar) -> bool { - self.scalar == other.scalar - } - } - #[automatically_derived] - impl ::core::cmp::Eq for SerializableScalar { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SerializableScalar { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SerializableScalar", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "scalar", - &self.scalar, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SerializableScalar { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "scalar" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"scalar" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - SerializableScalar, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SerializableScalar; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct SerializableScalar", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Scalar, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SerializableScalar with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(SerializableScalar { - scalar: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("scalar"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("scalar")? - } - }; - _serde::__private228::Ok(SerializableScalar { - scalar: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["scalar"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SerializableScalar", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - SerializableScalar, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for SerializableScalar { - #[inline] - fn clone(&self) -> SerializableScalar { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for SerializableScalar {} - #[automatically_derived] - impl ::core::cmp::Ord for SerializableScalar { - #[inline] - fn cmp(&self, other: &SerializableScalar) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.scalar, &other.scalar) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for SerializableScalar { - #[inline] - fn partial_cmp( - &self, - other: &SerializableScalar, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.scalar, &other.scalar) - } - } - impl SerializableScalar { - pub fn new(scalar: Scalar) -> Self { - Self { scalar } - } - } - impl From for SerializableScalar { - fn from(scalar: Scalar) -> Self { - Self { scalar } - } - } - impl BorshSerialize for SerializableScalar { - fn serialize( - &self, - writer: &mut W, - ) -> std::io::Result<()> { - let to_ser: [u8; 32] = self.scalar.to_bytes().into(); - BorshSerialize::serialize(&to_ser, writer) - } - } - impl BorshDeserialize for SerializableScalar { - fn deserialize_reader( - reader: &mut R, - ) -> std::io::Result { - let from_ser: [u8; 32] = BorshDeserialize::deserialize_reader( - reader, - )?; - let scalar = Scalar::from_repr(from_ser.into()) - .into_option() - .ok_or( - std::io::Error::new( - std::io::ErrorKind::InvalidData, - "The given scalar is not in the field of Secp256k1", - ), - )?; - Ok(SerializableScalar { scalar }) - } - } - pub struct SerializableAffinePoint { - pub affine_point: AffinePoint, - } - #[automatically_derived] - impl ::core::fmt::Debug for SerializableAffinePoint { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "SerializableAffinePoint", - "affine_point", - &&self.affine_point, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SerializableAffinePoint {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SerializableAffinePoint { - #[inline] - fn eq(&self, other: &SerializableAffinePoint) -> bool { - self.affine_point == other.affine_point - } - } - #[automatically_derived] - impl ::core::cmp::Eq for SerializableAffinePoint { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SerializableAffinePoint { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SerializableAffinePoint", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "affine_point", - &self.affine_point, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SerializableAffinePoint { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "affine_point" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"affine_point" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - SerializableAffinePoint, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SerializableAffinePoint; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct SerializableAffinePoint", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - AffinePoint, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SerializableAffinePoint with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(SerializableAffinePoint { - affine_point: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - AffinePoint, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "affine_point", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - AffinePoint, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("affine_point")? - } - }; - _serde::__private228::Ok(SerializableAffinePoint { - affine_point: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["affine_point"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SerializableAffinePoint", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - SerializableAffinePoint, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for SerializableAffinePoint { - #[inline] - fn clone(&self) -> SerializableAffinePoint { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for SerializableAffinePoint {} - pub struct Signature { - pub big_r: SerializableAffinePoint, - pub s: SerializableScalar, - pub recovery_id: u8, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Signature { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Signature", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "big_r", - &self.big_r, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "s", - &self.s, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "recovery_id", - &self.recovery_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Signature { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "big_r" => _serde::__private228::Ok(__Field::__field0), - "s" => _serde::__private228::Ok(__Field::__field1), - "recovery_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"big_r" => _serde::__private228::Ok(__Field::__field0), - b"s" => _serde::__private228::Ok(__Field::__field1), - b"recovery_id" => { - _serde::__private228::Ok(__Field::__field2) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Signature; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct Signature", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - SerializableAffinePoint, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Signature with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - SerializableScalar, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Signature with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - u8, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct Signature with 3 elements", - ), - ); - } - }; - _serde::__private228::Ok(Signature { - big_r: __field0, - s: __field1, - recovery_id: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - SerializableAffinePoint, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - SerializableScalar, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("big_r"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - SerializableAffinePoint, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("s"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - SerializableScalar, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "recovery_id", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("big_r")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("s")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("recovery_id")? - } - }; - _serde::__private228::Ok(Signature { - big_r: __field0, - s: __field1, - recovery_id: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "big_r", - "s", - "recovery_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Signature", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for Signature { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "Signature", - "big_r", - &self.big_r, - "s", - &self.s, - "recovery_id", - &&self.recovery_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Signature { - #[inline] - fn clone(&self) -> Signature { - Signature { - big_r: ::core::clone::Clone::clone(&self.big_r), - s: ::core::clone::Clone::clone(&self.s), - recovery_id: ::core::clone::Clone::clone(&self.recovery_id), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Signature {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Signature { - #[inline] - fn eq(&self, other: &Signature) -> bool { - self.big_r == other.big_r && self.s == other.s - && self.recovery_id == other.recovery_id - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Signature { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - impl Signature { - pub fn new( - big_r: AffinePoint, - s: k256::Scalar, - recovery_id: u8, - ) -> Self { - Signature { - big_r: SerializableAffinePoint { - affine_point: big_r, - }, - s: s.into(), - recovery_id, - } - } - } - } - pub mod ed25519_types { - use super::*; - use curve25519_dalek::Scalar; - pub struct SerializableScalar { - scalar: Scalar, - } - #[automatically_derived] - impl ::core::fmt::Debug for SerializableScalar { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "SerializableScalar", - "scalar", - &&self.scalar, - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SerializableScalar { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SerializableScalar", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "scalar", - &self.scalar, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SerializableScalar { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "scalar" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"scalar" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - SerializableScalar, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SerializableScalar; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct SerializableScalar", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Scalar, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SerializableScalar with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(SerializableScalar { - scalar: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("scalar"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("scalar")? - } - }; - _serde::__private228::Ok(SerializableScalar { - scalar: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["scalar"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SerializableScalar", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - SerializableScalar, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SerializableScalar {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SerializableScalar { - #[inline] - fn eq(&self, other: &SerializableScalar) -> bool { - self.scalar == other.scalar - } - } - #[automatically_derived] - impl ::core::cmp::Eq for SerializableScalar { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for SerializableScalar { - #[inline] - fn clone(&self) -> SerializableScalar { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for SerializableScalar {} - impl SerializableScalar { - pub fn new(scalar: Scalar) -> Self { - Self { scalar } - } - } - impl From for SerializableScalar { - fn from(scalar: Scalar) -> Self { - Self { scalar } - } - } - impl BorshSerialize for SerializableScalar { - fn serialize( - &self, - writer: &mut W, - ) -> std::io::Result<()> { - let to_ser: [u8; 32] = self.scalar.to_bytes(); - BorshSerialize::serialize(&to_ser, writer) - } - } - impl BorshDeserialize for SerializableScalar { - fn deserialize_reader( - reader: &mut R, - ) -> std::io::Result { - let from_ser: [u8; 32] = BorshDeserialize::deserialize_reader( - reader, - )?; - let scalar = Scalar::from_repr(from_ser) - .into_option() - .ok_or( - std::io::Error::new( - std::io::ErrorKind::InvalidData, - "The given scalar is not in the field of ed25519", - ), - )?; - Ok(SerializableScalar { scalar }) - } - } - impl Ord for SerializableScalar { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.scalar.as_bytes().cmp(other.scalar.as_bytes()) - } - } - impl PartialOrd for SerializableScalar { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - pub struct Signature( - #[serde_as(r#as = "[_; 64]")] - #[serde(with = ":: serde_with :: As :: < [:: serde_with :: Same; 64] >")] - [u8; 64], - ); - impl borsh::de::BorshDeserialize for Signature { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self(borsh::BorshDeserialize::deserialize_reader(reader)?)) - } - } - impl borsh::ser::BorshSerialize for Signature { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Signature { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "Signature", - &{ - #[doc(hidden)] - struct __SerializeWith<'__a> { - values: (&'__a [u8; 64],), - phantom: _serde::__private228::PhantomData, - } - #[automatically_derived] - impl<'__a> _serde::Serialize for __SerializeWith<'__a> { - fn serialize<__S>( - &self, - __s: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - ::serde_with::As::< - [::serde_with::Same; 64], - >::serialize(self.values.0, __s) - } - } - __SerializeWith { - values: (&self.0,), - phantom: _serde::__private228::PhantomData::, - } - }, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Signature { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Signature; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct Signature", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: [u8; 64] = ::serde_with::As::< - [::serde_with::Same; 64], - >::deserialize(__e)?; - _serde::__private228::Ok(Signature(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match { - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: [u8; 64], - phantom: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private228::Ok(__DeserializeWith { - value: ::serde_with::As::< - [::serde_with::Same; 64], - >::deserialize(__deserializer)?, - phantom: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData, - }) - } - } - _serde::__private228::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct Signature with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(Signature(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "Signature", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for Signature { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Signature", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Signature { - #[inline] - fn clone(&self) -> Signature { - Signature(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Signature {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Signature { - #[inline] - fn eq(&self, other: &Signature) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Signature { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; - } - } - impl Signature { - pub fn as_bytes(&self) -> &[u8; 64] { - &self.0 - } - pub fn new(bytes: [u8; 64]) -> Self { - Self(bytes) - } - } - } - } - use k256::{elliptic_curve::sec1::FromEncodedPoint, EncodedPoint}; - pub use kdf::{derive_key_secp256k1, derive_tweak, x_coordinate}; - pub use types::{ - ed25519_types, k256_types::{self, SerializableScalar}, - CKDResponse, SignatureResponse, - }; - pub fn near_public_key_to_affine_point( - pk: near_sdk::PublicKey, - ) -> k256_types::PublicKey { - match (&pk.curve_type(), &near_sdk::CurveType::SECP256K1) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!("Expected a key on the SECP256K1 curve"), - ), - ); - } - } - }; - let mut bytes = pk.into_bytes(); - bytes[0] = 0x04; - let point = EncodedPoint::from_bytes(bytes).unwrap(); - k256_types::PublicKey::from_encoded_point(&point).unwrap() - } -} -pub mod errors { - use std::borrow::Cow; - use crate::primitives::{domain::DomainId, key_state::EpochId}; - mod impls { - use std::borrow::Cow; - use std::fmt; - use crate::crypto_shared::kdf::TweakNotOnCurve; - use super::{ - ConversionError, DomainError, Error, ErrorKind, ErrorRepr, - InvalidCandidateSet, InvalidParameters, InvalidState, InvalidThreshold, - KeyEventError, NodeMigrationError, PublicKeyError, RespondError, SignError, - TeeError, VoteError, - }; - impl Error { - /// Construct a contract [`Error`] with the details of an error which includes - /// the custom error message with further context and the [`ErrorKind`] that - /// represents the category of error. - pub fn message(kind: ErrorKind, msg: T) -> Self - where - T: Into>, - { - Self { - repr: ErrorRepr::Message { - kind, - message: msg.into(), - }, - } - } - /// Construct a contract [`Error`] with the details of an error which only - /// includes the [`ErrorKind`] that represents the category of error. - pub fn simple(kind: ErrorKind) -> Self { - Self { - repr: ErrorRepr::Simple(kind), - } - } - /// Returns the corresponding [`ErrorKind`] for this error. - pub fn kind(&self) -> &ErrorKind { - match &self.repr { - ErrorRepr::Simple(kind) => kind, - ErrorRepr::Message { kind, .. } => kind, - } - } - } - impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match &self.repr { - ErrorRepr::Simple(kind) => f.write_fmt(format_args!("{0}", kind)), - ErrorRepr::Message { kind, message } => { - f.write_fmt(format_args!("{0}: {1}", kind, message)) - } - } - } - } - impl From for Error { - fn from(code: SignError) -> Self { - Self::simple(ErrorKind::Sign(code)) - } - } - impl From for Error { - fn from(code: RespondError) -> Self { - Self::simple(ErrorKind::Respond(code)) - } - } - impl From for Error { - fn from(code: PublicKeyError) -> Self { - Self::simple(ErrorKind::PublicKey(code)) - } - } - impl From for Error { - fn from(code: VoteError) -> Self { - Self::simple(ErrorKind::Vote(code)) - } - } - impl From for Error { - fn from(code: InvalidParameters) -> Self { - Self::simple(ErrorKind::InvalidParameters(code)) - } - } - impl From for Error { - fn from(code: NodeMigrationError) -> Self { - Self::simple(ErrorKind::NodeMigrationError(code)) - } - } - impl NodeMigrationError { - pub(crate) fn message(self, msg: T) -> Error - where - T: Into>, - { - Error::message(ErrorKind::NodeMigrationError(self), msg) - } - } - impl InvalidParameters { - pub(crate) fn message(self, msg: T) -> Error - where - T: Into>, - { - Error::message(ErrorKind::InvalidParameters(self), msg) - } - } - impl RespondError { - pub(crate) fn message(self, msg: T) -> Error - where - T: Into>, - { - Error::message(ErrorKind::Respond(self), msg) - } - } - impl From for Error { - fn from(code: InvalidState) -> Self { - Self::simple(ErrorKind::InvalidState(code)) - } - } - impl InvalidState { - pub(crate) fn message(self, msg: T) -> Error - where - T: Into>, - { - Error::message(ErrorKind::InvalidState(self), msg) - } - } - impl From for Error { - fn from(code: ConversionError) -> Self { - Self::simple(ErrorKind::ConversionError(code)) - } - } - impl ConversionError { - pub(crate) fn message(self, msg: T) -> Error - where - T: Into>, - { - Error::message(ErrorKind::ConversionError(self), msg) - } - } - impl From for Error { - fn from(code: KeyEventError) -> Self { - Self::simple(ErrorKind::KeyEventError(code)) - } - } - impl From for Error { - fn from(code: TeeError) -> Self { - Self::simple(ErrorKind::TeeError(code)) - } - } - impl InvalidThreshold { - pub(crate) fn message(self, msg: T) -> Error - where - T: Into>, - { - Error::message(ErrorKind::InvalidThreshold(self), msg) - } - } - impl From for Error { - fn from(code: InvalidThreshold) -> Self { - Self::simple(ErrorKind::InvalidThreshold(code)) - } - } - impl From for Error { - fn from(code: InvalidCandidateSet) -> Self { - Self::simple(ErrorKind::InvalidCandidateSet(code)) - } - } - impl From for Error { - fn from(code: DomainError) -> Self { - Self::simple(ErrorKind::DomainError(code)) - } - } - impl From for PublicKeyError { - fn from(_: TweakNotOnCurve) -> Self { - Self::TweakNotOnCurve - } - } - impl From for RespondError { - fn from(_: TweakNotOnCurve) -> Self { - Self::TweakNotOnCurve - } - } - } - pub enum NodeMigrationError { - #[error("Node dose not have an ongoing recovery")] - MigrationNotFound, - #[error( - "The transaction was submitted by a different public key than expected." - )] - AccountPublicKeyMismatch, - #[error("The submitted keyset differs from the expected keyset.")] - KeysetMismatch, - } - #[automatically_derived] - impl ::core::fmt::Debug for NodeMigrationError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - NodeMigrationError::MigrationNotFound => "MigrationNotFound", - NodeMigrationError::AccountPublicKeyMismatch => { - "AccountPublicKeyMismatch" - } - NodeMigrationError::KeysetMismatch => "KeysetMismatch", - }, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for NodeMigrationError { - #[inline] - fn clone(&self) -> NodeMigrationError { - match self { - NodeMigrationError::MigrationNotFound => { - NodeMigrationError::MigrationNotFound - } - NodeMigrationError::AccountPublicKeyMismatch => { - NodeMigrationError::AccountPublicKeyMismatch - } - NodeMigrationError::KeysetMismatch => NodeMigrationError::KeysetMismatch, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for NodeMigrationError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for NodeMigrationError { - #[inline] - fn eq(&self, other: &NodeMigrationError) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for NodeMigrationError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for NodeMigrationError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for NodeMigrationError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - NodeMigrationError::MigrationNotFound {} => { - __formatter.write_str("Node dose not have an ongoing recovery") - } - NodeMigrationError::AccountPublicKeyMismatch {} => { - __formatter - .write_str( - "The transaction was submitted by a different public key than expected.", - ) - } - NodeMigrationError::KeysetMismatch {} => { - __formatter - .write_str( - "The submitted keyset differs from the expected keyset.", - ) - } - } - } - } - pub enum TeeError { - #[error( - "Due to previously failed TEE validation, the network is not accepting new requests at this point in time. Try again later." - )] - TeeValidationFailed, - } - #[automatically_derived] - impl ::core::fmt::Debug for TeeError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "TeeValidationFailed") - } - } - #[automatically_derived] - impl ::core::clone::Clone for TeeError { - #[inline] - fn clone(&self) -> TeeError { - TeeError::TeeValidationFailed - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TeeError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TeeError { - #[inline] - fn eq(&self, other: &TeeError) -> bool { - true - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TeeError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for TeeError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for TeeError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - TeeError::TeeValidationFailed {} => { - __formatter - .write_str( - "Due to previously failed TEE validation, the network is not accepting new requests at this point in time. Try again later.", - ) - } - } - } - } - pub enum RequestError { - #[error("Request has timed out.")] - Timeout, - } - #[automatically_derived] - impl ::core::fmt::Debug for RequestError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "Timeout") - } - } - #[automatically_derived] - impl ::core::clone::Clone for RequestError { - #[inline] - fn clone(&self) -> RequestError { - RequestError::Timeout - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RequestError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RequestError { - #[inline] - fn eq(&self, other: &RequestError) -> bool { - true - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RequestError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for RequestError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for RequestError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - RequestError::Timeout {} => { - __formatter.write_str("Request has timed out.") - } - } - } - } - pub enum SignError { - #[error("Signature request has already been submitted. Please try again later.")] - PayloadCollision, - #[error( - "This key version is not supported. Call latest_key_version() to get the latest supported version." - )] - UnsupportedKeyVersion, - } - #[automatically_derived] - impl ::core::fmt::Debug for SignError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - SignError::PayloadCollision => "PayloadCollision", - SignError::UnsupportedKeyVersion => "UnsupportedKeyVersion", - }, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for SignError { - #[inline] - fn clone(&self) -> SignError { - match self { - SignError::PayloadCollision => SignError::PayloadCollision, - SignError::UnsupportedKeyVersion => SignError::UnsupportedKeyVersion, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SignError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SignError { - #[inline] - fn eq(&self, other: &SignError) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for SignError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for SignError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for SignError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - SignError::PayloadCollision {} => { - __formatter - .write_str( - "Signature request has already been submitted. Please try again later.", - ) - } - SignError::UnsupportedKeyVersion {} => { - __formatter - .write_str( - "This key version is not supported. Call latest_key_version() to get the latest supported version.", - ) - } - } - } - } - pub enum RespondError { - #[error("The provided signature is invalid.")] - InvalidSignature, - #[error( - "The provided signature scheme does not match the requestued key's scheme" - )] - SignatureSchemeMismatch, - #[error("The provided domain was not found.")] - DomainNotFound, - #[error("The provided tweak is not on the curve of the public key.")] - TweakNotOnCurve, - } - #[automatically_derived] - impl ::core::fmt::Debug for RespondError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - RespondError::InvalidSignature => "InvalidSignature", - RespondError::SignatureSchemeMismatch => "SignatureSchemeMismatch", - RespondError::DomainNotFound => "DomainNotFound", - RespondError::TweakNotOnCurve => "TweakNotOnCurve", - }, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RespondError { - #[inline] - fn clone(&self) -> RespondError { - match self { - RespondError::InvalidSignature => RespondError::InvalidSignature, - RespondError::SignatureSchemeMismatch => { - RespondError::SignatureSchemeMismatch - } - RespondError::DomainNotFound => RespondError::DomainNotFound, - RespondError::TweakNotOnCurve => RespondError::TweakNotOnCurve, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RespondError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RespondError { - #[inline] - fn eq(&self, other: &RespondError) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RespondError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for RespondError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for RespondError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - RespondError::InvalidSignature {} => { - __formatter.write_str("The provided signature is invalid.") - } - RespondError::SignatureSchemeMismatch {} => { - __formatter - .write_str( - "The provided signature scheme does not match the requestued key's scheme", - ) - } - RespondError::DomainNotFound {} => { - __formatter.write_str("The provided domain was not found.") - } - RespondError::TweakNotOnCurve {} => { - __formatter - .write_str( - "The provided tweak is not on the curve of the public key.", - ) - } - } - } - } - pub enum PublicKeyError { - #[error("Derived key conversion failed.")] - DerivedKeyConversionFailed, - #[error("The provided domain was not found.")] - DomainNotFound, - #[error("The provided tweak is not on the curve of the public key.")] - TweakNotOnCurve, - } - #[automatically_derived] - impl ::core::fmt::Debug for PublicKeyError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - PublicKeyError::DerivedKeyConversionFailed => { - "DerivedKeyConversionFailed" - } - PublicKeyError::DomainNotFound => "DomainNotFound", - PublicKeyError::TweakNotOnCurve => "TweakNotOnCurve", - }, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for PublicKeyError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for PublicKeyError { - #[inline] - fn eq(&self, other: &PublicKeyError) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for PublicKeyError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - impl ::core::clone::Clone for PublicKeyError { - #[inline] - fn clone(&self) -> PublicKeyError { - match self { - PublicKeyError::DerivedKeyConversionFailed => { - PublicKeyError::DerivedKeyConversionFailed - } - PublicKeyError::DomainNotFound => PublicKeyError::DomainNotFound, - PublicKeyError::TweakNotOnCurve => PublicKeyError::TweakNotOnCurve, - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for PublicKeyError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for PublicKeyError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - PublicKeyError::DerivedKeyConversionFailed {} => { - __formatter.write_str("Derived key conversion failed.") - } - PublicKeyError::DomainNotFound {} => { - __formatter.write_str("The provided domain was not found.") - } - PublicKeyError::TweakNotOnCurve {} => { - __formatter - .write_str( - "The provided tweak is not on the curve of the public key.", - ) - } - } - } - } - pub enum KeyEventError { - #[error("Key event Id mismatch")] - KeyEventIdMismatch, - #[error( - "Can not start a new reshare or keygen instance while the current instance is still active." - )] - ActiveKeyEvent, - #[error("Expected ongoing reshare")] - NoActiveKeyEvent, - } - #[automatically_derived] - impl ::core::fmt::Debug for KeyEventError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - KeyEventError::KeyEventIdMismatch => "KeyEventIdMismatch", - KeyEventError::ActiveKeyEvent => "ActiveKeyEvent", - KeyEventError::NoActiveKeyEvent => "NoActiveKeyEvent", - }, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for KeyEventError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for KeyEventError { - #[inline] - fn eq(&self, other: &KeyEventError) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for KeyEventError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - impl ::core::clone::Clone for KeyEventError { - #[inline] - fn clone(&self) -> KeyEventError { - match self { - KeyEventError::KeyEventIdMismatch => KeyEventError::KeyEventIdMismatch, - KeyEventError::ActiveKeyEvent => KeyEventError::ActiveKeyEvent, - KeyEventError::NoActiveKeyEvent => KeyEventError::NoActiveKeyEvent, - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for KeyEventError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for KeyEventError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - KeyEventError::KeyEventIdMismatch {} => { - __formatter.write_str("Key event Id mismatch") - } - KeyEventError::ActiveKeyEvent {} => { - __formatter - .write_str( - "Can not start a new reshare or keygen instance while the current instance is still active.", - ) - } - KeyEventError::NoActiveKeyEvent {} => { - __formatter.write_str("Expected ongoing reshare") - } - } - } - } - pub enum VoteError { - #[error("Voting account is not a participant.")] - VoterNotParticipant, - #[error("Voting account is neither a participant, nor a proposed participant.")] - VoterNotParticipantNorProposedParticipant, - #[error("This participant already registered a vote.")] - ParticipantVoteAlreadyRegistered, - #[error( - "Voting account is not the leader of the current reshare or keygen instance." - )] - VoterNotLeader, - #[error("Inconsistent voting state")] - InconsistentVotingState, - #[error("Voter already aborted the current key event.")] - VoterAlreadyAborted, - #[error("Vote already casted.")] - VoteAlreadySubmitted, - #[error( - "Candidates can only cast a vote after `threshold` participants casted one to admit them" - )] - VoterPending, - } - #[automatically_derived] - impl ::core::fmt::Debug for VoteError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - VoteError::VoterNotParticipant => "VoterNotParticipant", - VoteError::VoterNotParticipantNorProposedParticipant => { - "VoterNotParticipantNorProposedParticipant" - } - VoteError::ParticipantVoteAlreadyRegistered => { - "ParticipantVoteAlreadyRegistered" - } - VoteError::VoterNotLeader => "VoterNotLeader", - VoteError::InconsistentVotingState => "InconsistentVotingState", - VoteError::VoterAlreadyAborted => "VoterAlreadyAborted", - VoteError::VoteAlreadySubmitted => "VoteAlreadySubmitted", - VoteError::VoterPending => "VoterPending", - }, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for VoteError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for VoteError { - #[inline] - fn eq(&self, other: &VoteError) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for VoteError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - impl ::core::clone::Clone for VoteError { - #[inline] - fn clone(&self) -> VoteError { - match self { - VoteError::VoterNotParticipant => VoteError::VoterNotParticipant, - VoteError::VoterNotParticipantNorProposedParticipant => { - VoteError::VoterNotParticipantNorProposedParticipant - } - VoteError::ParticipantVoteAlreadyRegistered => { - VoteError::ParticipantVoteAlreadyRegistered - } - VoteError::VoterNotLeader => VoteError::VoterNotLeader, - VoteError::InconsistentVotingState => VoteError::InconsistentVotingState, - VoteError::VoterAlreadyAborted => VoteError::VoterAlreadyAborted, - VoteError::VoteAlreadySubmitted => VoteError::VoteAlreadySubmitted, - VoteError::VoterPending => VoteError::VoterPending, - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for VoteError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for VoteError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - VoteError::VoterNotParticipant {} => { - __formatter.write_str("Voting account is not a participant.") - } - VoteError::VoterNotParticipantNorProposedParticipant {} => { - __formatter - .write_str( - "Voting account is neither a participant, nor a proposed participant.", - ) - } - VoteError::ParticipantVoteAlreadyRegistered {} => { - __formatter.write_str("This participant already registered a vote.") - } - VoteError::VoterNotLeader {} => { - __formatter - .write_str( - "Voting account is not the leader of the current reshare or keygen instance.", - ) - } - VoteError::InconsistentVotingState {} => { - __formatter.write_str("Inconsistent voting state") - } - VoteError::VoterAlreadyAborted {} => { - __formatter.write_str("Voter already aborted the current key event.") - } - VoteError::VoteAlreadySubmitted {} => { - __formatter.write_str("Vote already casted.") - } - VoteError::VoterPending {} => { - __formatter - .write_str( - "Candidates can only cast a vote after `threshold` participants casted one to admit them", - ) - } - } - } - } - pub enum InvalidParameters { - #[error("Malformed payload.")] - MalformedPayload, - #[error("Attached deposit is lower than required.")] - InsufficientDeposit, - #[error("Provided gas is lower than required.")] - InsufficientGas, - #[error("This sign request has timed out, was completed, or never existed.")] - RequestNotFound, - #[error("Update not found.")] - UpdateNotFound, - #[error("Participant already in set.")] - ParticipantAlreadyInSet, - #[error("Participant id already used.")] - ParticipantAlreadyUsed, - #[error("The provided domain ID, {provided}, was not found.")] - DomainNotFound { provided: DomainId }, - #[error("Provided Epoch Id, {provided}, does not match expected, {expected}.")] - EpochMismatch { provided: EpochId, expected: EpochId }, - #[error("Next domain ID mismatch")] - NextDomainIdMismatch, - #[error("Invalid domain ID.")] - InvalidDomainId, - #[error("Invalid TEE Remote Attestation.")] - InvalidTeeRemoteAttestation, - #[error("Invalid app public key.")] - InvalidAppPublicKey, - #[error("The provided TLS key is not valid.")] - InvalidTlsPublicKey, - #[error("Caller is not the signer account.")] - CallerNotSigner, - } - #[automatically_derived] - impl ::core::fmt::Debug for InvalidParameters { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - InvalidParameters::MalformedPayload => { - ::core::fmt::Formatter::write_str(f, "MalformedPayload") - } - InvalidParameters::InsufficientDeposit => { - ::core::fmt::Formatter::write_str(f, "InsufficientDeposit") - } - InvalidParameters::InsufficientGas => { - ::core::fmt::Formatter::write_str(f, "InsufficientGas") - } - InvalidParameters::RequestNotFound => { - ::core::fmt::Formatter::write_str(f, "RequestNotFound") - } - InvalidParameters::UpdateNotFound => { - ::core::fmt::Formatter::write_str(f, "UpdateNotFound") - } - InvalidParameters::ParticipantAlreadyInSet => { - ::core::fmt::Formatter::write_str(f, "ParticipantAlreadyInSet") - } - InvalidParameters::ParticipantAlreadyUsed => { - ::core::fmt::Formatter::write_str(f, "ParticipantAlreadyUsed") - } - InvalidParameters::DomainNotFound { provided: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "DomainNotFound", - "provided", - &__self_0, - ) - } - InvalidParameters::EpochMismatch { - provided: __self_0, - expected: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "EpochMismatch", - "provided", - __self_0, - "expected", - &__self_1, - ) - } - InvalidParameters::NextDomainIdMismatch => { - ::core::fmt::Formatter::write_str(f, "NextDomainIdMismatch") - } - InvalidParameters::InvalidDomainId => { - ::core::fmt::Formatter::write_str(f, "InvalidDomainId") - } - InvalidParameters::InvalidTeeRemoteAttestation => { - ::core::fmt::Formatter::write_str(f, "InvalidTeeRemoteAttestation") - } - InvalidParameters::InvalidAppPublicKey => { - ::core::fmt::Formatter::write_str(f, "InvalidAppPublicKey") - } - InvalidParameters::InvalidTlsPublicKey => { - ::core::fmt::Formatter::write_str(f, "InvalidTlsPublicKey") - } - InvalidParameters::CallerNotSigner => { - ::core::fmt::Formatter::write_str(f, "CallerNotSigner") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for InvalidParameters {} - #[automatically_derived] - impl ::core::cmp::PartialEq for InvalidParameters { - #[inline] - fn eq(&self, other: &InvalidParameters) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - ( - InvalidParameters::DomainNotFound { provided: __self_0 }, - InvalidParameters::DomainNotFound { provided: __arg1_0 }, - ) => __self_0 == __arg1_0, - ( - InvalidParameters::EpochMismatch { - provided: __self_0, - expected: __self_1, - }, - InvalidParameters::EpochMismatch { - provided: __arg1_0, - expected: __arg1_1, - }, - ) => __self_0 == __arg1_0 && __self_1 == __arg1_1, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for InvalidParameters { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for InvalidParameters { - #[inline] - fn clone(&self) -> InvalidParameters { - match self { - InvalidParameters::MalformedPayload => { - InvalidParameters::MalformedPayload - } - InvalidParameters::InsufficientDeposit => { - InvalidParameters::InsufficientDeposit - } - InvalidParameters::InsufficientGas => InvalidParameters::InsufficientGas, - InvalidParameters::RequestNotFound => InvalidParameters::RequestNotFound, - InvalidParameters::UpdateNotFound => InvalidParameters::UpdateNotFound, - InvalidParameters::ParticipantAlreadyInSet => { - InvalidParameters::ParticipantAlreadyInSet - } - InvalidParameters::ParticipantAlreadyUsed => { - InvalidParameters::ParticipantAlreadyUsed - } - InvalidParameters::DomainNotFound { provided: __self_0 } => { - InvalidParameters::DomainNotFound { - provided: ::core::clone::Clone::clone(__self_0), - } - } - InvalidParameters::EpochMismatch { - provided: __self_0, - expected: __self_1, - } => { - InvalidParameters::EpochMismatch { - provided: ::core::clone::Clone::clone(__self_0), - expected: ::core::clone::Clone::clone(__self_1), - } - } - InvalidParameters::NextDomainIdMismatch => { - InvalidParameters::NextDomainIdMismatch - } - InvalidParameters::InvalidDomainId => InvalidParameters::InvalidDomainId, - InvalidParameters::InvalidTeeRemoteAttestation => { - InvalidParameters::InvalidTeeRemoteAttestation - } - InvalidParameters::InvalidAppPublicKey => { - InvalidParameters::InvalidAppPublicKey - } - InvalidParameters::InvalidTlsPublicKey => { - InvalidParameters::InvalidTlsPublicKey - } - InvalidParameters::CallerNotSigner => InvalidParameters::CallerNotSigner, - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for InvalidParameters {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for InvalidParameters { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use ::thiserror::__private17::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - InvalidParameters::MalformedPayload {} => { - __formatter.write_str("Malformed payload.") - } - InvalidParameters::InsufficientDeposit {} => { - __formatter.write_str("Attached deposit is lower than required.") - } - InvalidParameters::InsufficientGas {} => { - __formatter.write_str("Provided gas is lower than required.") - } - InvalidParameters::RequestNotFound {} => { - __formatter - .write_str( - "This sign request has timed out, was completed, or never existed.", - ) - } - InvalidParameters::UpdateNotFound {} => { - __formatter.write_str("Update not found.") - } - InvalidParameters::ParticipantAlreadyInSet {} => { - __formatter.write_str("Participant already in set.") - } - InvalidParameters::ParticipantAlreadyUsed {} => { - __formatter.write_str("Participant id already used.") - } - InvalidParameters::DomainNotFound { provided } => { - match (provided.as_display(),) { - (__display_provided,) => { - __formatter - .write_fmt( - format_args!( - "The provided domain ID, {0}, was not found.", - __display_provided, - ), - ) - } - } - } - InvalidParameters::EpochMismatch { provided, expected } => { - match (provided.as_display(), expected.as_display()) { - (__display_provided, __display_expected) => { - __formatter - .write_fmt( - format_args!( - "Provided Epoch Id, {0}, does not match expected, {1}.", - __display_provided, - __display_expected, - ), - ) - } - } - } - InvalidParameters::NextDomainIdMismatch {} => { - __formatter.write_str("Next domain ID mismatch") - } - InvalidParameters::InvalidDomainId {} => { - __formatter.write_str("Invalid domain ID.") - } - InvalidParameters::InvalidTeeRemoteAttestation {} => { - __formatter.write_str("Invalid TEE Remote Attestation.") - } - InvalidParameters::InvalidAppPublicKey {} => { - __formatter.write_str("Invalid app public key.") - } - InvalidParameters::InvalidTlsPublicKey {} => { - __formatter.write_str("The provided TLS key is not valid.") - } - InvalidParameters::CallerNotSigner {} => { - __formatter.write_str("Caller is not the signer account.") - } - } - } - } - pub enum InvalidState { - #[error("The protocol is not Running.")] - ProtocolStateNotRunning, - #[error("Protocol state is not resharing.")] - ProtocolStateNotResharing, - #[error("Protocol state is not initializing.")] - ProtocolStateNotInitializing, - #[error("Protocol state is not running, nor resharing.")] - ProtocolStateNotRunningNorResharing, - #[error("Unexpected protocol state.")] - UnexpectedProtocolState, - #[error("Cannot load in contract due to missing state")] - ContractStateIsMissing, - #[error("Participant index out of range")] - ParticipantIndexOutOfRange, - #[error("Not a participant")] - NotParticipant, - } - #[automatically_derived] - impl ::core::fmt::Debug for InvalidState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - InvalidState::ProtocolStateNotRunning => "ProtocolStateNotRunning", - InvalidState::ProtocolStateNotResharing => { - "ProtocolStateNotResharing" - } - InvalidState::ProtocolStateNotInitializing => { - "ProtocolStateNotInitializing" - } - InvalidState::ProtocolStateNotRunningNorResharing => { - "ProtocolStateNotRunningNorResharing" - } - InvalidState::UnexpectedProtocolState => "UnexpectedProtocolState", - InvalidState::ContractStateIsMissing => "ContractStateIsMissing", - InvalidState::ParticipantIndexOutOfRange => { - "ParticipantIndexOutOfRange" - } - InvalidState::NotParticipant => "NotParticipant", - }, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for InvalidState {} - #[automatically_derived] - impl ::core::cmp::PartialEq for InvalidState { - #[inline] - fn eq(&self, other: &InvalidState) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for InvalidState { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - impl ::core::clone::Clone for InvalidState { - #[inline] - fn clone(&self) -> InvalidState { - match self { - InvalidState::ProtocolStateNotRunning => { - InvalidState::ProtocolStateNotRunning - } - InvalidState::ProtocolStateNotResharing => { - InvalidState::ProtocolStateNotResharing - } - InvalidState::ProtocolStateNotInitializing => { - InvalidState::ProtocolStateNotInitializing - } - InvalidState::ProtocolStateNotRunningNorResharing => { - InvalidState::ProtocolStateNotRunningNorResharing - } - InvalidState::UnexpectedProtocolState => { - InvalidState::UnexpectedProtocolState - } - InvalidState::ContractStateIsMissing => { - InvalidState::ContractStateIsMissing - } - InvalidState::ParticipantIndexOutOfRange => { - InvalidState::ParticipantIndexOutOfRange - } - InvalidState::NotParticipant => InvalidState::NotParticipant, - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for InvalidState {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for InvalidState { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - InvalidState::ProtocolStateNotRunning {} => { - __formatter.write_str("The protocol is not Running.") - } - InvalidState::ProtocolStateNotResharing {} => { - __formatter.write_str("Protocol state is not resharing.") - } - InvalidState::ProtocolStateNotInitializing {} => { - __formatter.write_str("Protocol state is not initializing.") - } - InvalidState::ProtocolStateNotRunningNorResharing {} => { - __formatter - .write_str("Protocol state is not running, nor resharing.") - } - InvalidState::UnexpectedProtocolState {} => { - __formatter.write_str("Unexpected protocol state.") - } - InvalidState::ContractStateIsMissing {} => { - __formatter.write_str("Cannot load in contract due to missing state") - } - InvalidState::ParticipantIndexOutOfRange {} => { - __formatter.write_str("Participant index out of range") - } - InvalidState::NotParticipant {} => { - __formatter.write_str("Not a participant") - } - } - } - } - pub enum InvalidThreshold { - #[error("Threshold does not meet the minimum absolute requirement")] - MinAbsRequirementFailed, - #[error("Threshold does not meet the minimum relative requirement")] - MinRelRequirementFailed, - #[error("Threshold must not exceed number of participants")] - MaxRequirementFailed, - #[error("Key event threshold must match the number of participants")] - DKGThresholdFailed, - } - #[automatically_derived] - impl ::core::fmt::Debug for InvalidThreshold { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - InvalidThreshold::MinAbsRequirementFailed => { - "MinAbsRequirementFailed" - } - InvalidThreshold::MinRelRequirementFailed => { - "MinRelRequirementFailed" - } - InvalidThreshold::MaxRequirementFailed => "MaxRequirementFailed", - InvalidThreshold::DKGThresholdFailed => "DKGThresholdFailed", - }, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for InvalidThreshold {} - #[automatically_derived] - impl ::core::cmp::PartialEq for InvalidThreshold { - #[inline] - fn eq(&self, other: &InvalidThreshold) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for InvalidThreshold { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - impl ::core::clone::Clone for InvalidThreshold { - #[inline] - fn clone(&self) -> InvalidThreshold { - match self { - InvalidThreshold::MinAbsRequirementFailed => { - InvalidThreshold::MinAbsRequirementFailed - } - InvalidThreshold::MinRelRequirementFailed => { - InvalidThreshold::MinRelRequirementFailed - } - InvalidThreshold::MaxRequirementFailed => { - InvalidThreshold::MaxRequirementFailed - } - InvalidThreshold::DKGThresholdFailed => { - InvalidThreshold::DKGThresholdFailed - } - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for InvalidThreshold {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for InvalidThreshold { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - InvalidThreshold::MinAbsRequirementFailed {} => { - __formatter - .write_str( - "Threshold does not meet the minimum absolute requirement", - ) - } - InvalidThreshold::MinRelRequirementFailed {} => { - __formatter - .write_str( - "Threshold does not meet the minimum relative requirement", - ) - } - InvalidThreshold::MaxRequirementFailed {} => { - __formatter - .write_str("Threshold must not exceed number of participants") - } - InvalidThreshold::DKGThresholdFailed {} => { - __formatter - .write_str( - "Key event threshold must match the number of participants", - ) - } - } - } - } - pub enum InvalidCandidateSet { - #[error( - "Set of proposed participants must contain at least `threshold` old participants." - )] - InsufficientOldParticipants, - #[error("Participant ids are not coherent.")] - IncoherentParticipantIds, - #[error("New Participant ids need to be unique and contiguous.")] - NewParticipantIdsNotContiguous, - #[error("New Participant ids need to not skip any unused participant ids.")] - NewParticipantIdsTooHigh, - #[error("Invalid participants TEE Remote Attestation Quote.")] - InvalidParticipantsTeeQuote, - } - #[automatically_derived] - impl ::core::fmt::Debug for InvalidCandidateSet { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - InvalidCandidateSet::InsufficientOldParticipants => { - "InsufficientOldParticipants" - } - InvalidCandidateSet::IncoherentParticipantIds => { - "IncoherentParticipantIds" - } - InvalidCandidateSet::NewParticipantIdsNotContiguous => { - "NewParticipantIdsNotContiguous" - } - InvalidCandidateSet::NewParticipantIdsTooHigh => { - "NewParticipantIdsTooHigh" - } - InvalidCandidateSet::InvalidParticipantsTeeQuote => { - "InvalidParticipantsTeeQuote" - } - }, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for InvalidCandidateSet {} - #[automatically_derived] - impl ::core::cmp::PartialEq for InvalidCandidateSet { - #[inline] - fn eq(&self, other: &InvalidCandidateSet) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for InvalidCandidateSet { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - impl ::core::clone::Clone for InvalidCandidateSet { - #[inline] - fn clone(&self) -> InvalidCandidateSet { - match self { - InvalidCandidateSet::InsufficientOldParticipants => { - InvalidCandidateSet::InsufficientOldParticipants - } - InvalidCandidateSet::IncoherentParticipantIds => { - InvalidCandidateSet::IncoherentParticipantIds - } - InvalidCandidateSet::NewParticipantIdsNotContiguous => { - InvalidCandidateSet::NewParticipantIdsNotContiguous - } - InvalidCandidateSet::NewParticipantIdsTooHigh => { - InvalidCandidateSet::NewParticipantIdsTooHigh - } - InvalidCandidateSet::InvalidParticipantsTeeQuote => { - InvalidCandidateSet::InvalidParticipantsTeeQuote - } - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for InvalidCandidateSet {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for InvalidCandidateSet { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - InvalidCandidateSet::InsufficientOldParticipants {} => { - __formatter - .write_str( - "Set of proposed participants must contain at least `threshold` old participants.", - ) - } - InvalidCandidateSet::IncoherentParticipantIds {} => { - __formatter.write_str("Participant ids are not coherent.") - } - InvalidCandidateSet::NewParticipantIdsNotContiguous {} => { - __formatter - .write_str( - "New Participant ids need to be unique and contiguous.", - ) - } - InvalidCandidateSet::NewParticipantIdsTooHigh {} => { - __formatter - .write_str( - "New Participant ids need to not skip any unused participant ids.", - ) - } - InvalidCandidateSet::InvalidParticipantsTeeQuote {} => { - __formatter - .write_str("Invalid participants TEE Remote Attestation Quote.") - } - } - } - } - pub enum ConversionError { - #[error("Data conversion error.")] - DataConversion, - } - #[automatically_derived] - impl ::core::fmt::Debug for ConversionError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "DataConversion") - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ConversionError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ConversionError { - #[inline] - fn eq(&self, other: &ConversionError) -> bool { - true - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ConversionError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - impl ::core::clone::Clone for ConversionError { - #[inline] - fn clone(&self) -> ConversionError { - ConversionError::DataConversion - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for ConversionError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for ConversionError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - ConversionError::DataConversion {} => { - __formatter.write_str("Data conversion error.") - } - } - } - } - pub enum DomainError { - #[error("No such domain.")] - NoSuchDomain, - #[error( - "Newly proposed domain IDs are not contiguous. Expected id: {expected_id}" - )] - NewDomainIdsNotContiguous { expected_id: DomainId }, - #[error("vote_add_domains must add at least one domain")] - AddDomainsMustAddAtLeastOneDomain, - #[error("Invalid list of domains provided")] - InvalidDomains, - #[error("Domains from keyset do not match the provided domains")] - DomainsMismatch, - } - #[automatically_derived] - impl ::core::fmt::Debug for DomainError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - DomainError::NoSuchDomain => { - ::core::fmt::Formatter::write_str(f, "NoSuchDomain") - } - DomainError::NewDomainIdsNotContiguous { expected_id: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "NewDomainIdsNotContiguous", - "expected_id", - &__self_0, - ) - } - DomainError::AddDomainsMustAddAtLeastOneDomain => { - ::core::fmt::Formatter::write_str( - f, - "AddDomainsMustAddAtLeastOneDomain", - ) - } - DomainError::InvalidDomains => { - ::core::fmt::Formatter::write_str(f, "InvalidDomains") - } - DomainError::DomainsMismatch => { - ::core::fmt::Formatter::write_str(f, "DomainsMismatch") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DomainError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DomainError { - #[inline] - fn eq(&self, other: &DomainError) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - ( - DomainError::NewDomainIdsNotContiguous { expected_id: __self_0 }, - DomainError::NewDomainIdsNotContiguous { expected_id: __arg1_0 }, - ) => __self_0 == __arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DomainError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for DomainError { - #[inline] - fn clone(&self) -> DomainError { - match self { - DomainError::NoSuchDomain => DomainError::NoSuchDomain, - DomainError::NewDomainIdsNotContiguous { expected_id: __self_0 } => { - DomainError::NewDomainIdsNotContiguous { - expected_id: ::core::clone::Clone::clone(__self_0), - } - } - DomainError::AddDomainsMustAddAtLeastOneDomain => { - DomainError::AddDomainsMustAddAtLeastOneDomain - } - DomainError::InvalidDomains => DomainError::InvalidDomains, - DomainError::DomainsMismatch => DomainError::DomainsMismatch, - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for DomainError {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for DomainError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use ::thiserror::__private17::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - DomainError::NoSuchDomain {} => __formatter.write_str("No such domain."), - DomainError::NewDomainIdsNotContiguous { expected_id } => { - match (expected_id.as_display(),) { - (__display_expected_id,) => { - __formatter - .write_fmt( - format_args!( - "Newly proposed domain IDs are not contiguous. Expected id: {0}", - __display_expected_id, - ), - ) - } - } - } - DomainError::AddDomainsMustAddAtLeastOneDomain {} => { - __formatter - .write_str("vote_add_domains must add at least one domain") - } - DomainError::InvalidDomains {} => { - __formatter.write_str("Invalid list of domains provided") - } - DomainError::DomainsMismatch {} => { - __formatter - .write_str( - "Domains from keyset do not match the provided domains", - ) - } - } - } - } - /// A list specifying general categories of MPC Contract errors. - #[non_exhaustive] - pub enum ErrorKind { - /// An error occurred while user is performing sign request. - #[error("{0}")] - Sign(#[from] SignError), - /// An error occurred while node is performing respond call. - #[error("{0}")] - Respond(#[from] RespondError), - /// An error occurred while user is performing public_key_* call. - #[error("{0}")] - PublicKey(#[from] PublicKeyError), - /// An error occurred while node is performing vote_* call. - #[error("{0}")] - Vote(#[from] VoteError), - #[error("{0}")] - InvalidParameters(#[from] InvalidParameters), - #[error("{0}")] - InvalidState(#[from] InvalidState), - #[error("{0}")] - ConversionError(#[from] ConversionError), - #[error("{0}")] - InvalidThreshold(#[from] InvalidThreshold), - #[error("{0}")] - InvalidCandidateSet(#[from] InvalidCandidateSet), - #[error("{0}")] - KeyEventError(#[from] KeyEventError), - #[error("{0}")] - DomainError(#[from] DomainError), - #[error("{0}")] - TeeError(#[from] TeeError), - #[error("{0}")] - NodeMigrationError(#[from] NodeMigrationError), - } - #[automatically_derived] - impl ::core::clone::Clone for ErrorKind { - #[inline] - fn clone(&self) -> ErrorKind { - match self { - ErrorKind::Sign(__self_0) => { - ErrorKind::Sign(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::Respond(__self_0) => { - ErrorKind::Respond(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::PublicKey(__self_0) => { - ErrorKind::PublicKey(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::Vote(__self_0) => { - ErrorKind::Vote(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::InvalidParameters(__self_0) => { - ErrorKind::InvalidParameters(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::InvalidState(__self_0) => { - ErrorKind::InvalidState(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::ConversionError(__self_0) => { - ErrorKind::ConversionError(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::InvalidThreshold(__self_0) => { - ErrorKind::InvalidThreshold(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::InvalidCandidateSet(__self_0) => { - ErrorKind::InvalidCandidateSet(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::KeyEventError(__self_0) => { - ErrorKind::KeyEventError(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::DomainError(__self_0) => { - ErrorKind::DomainError(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::TeeError(__self_0) => { - ErrorKind::TeeError(::core::clone::Clone::clone(__self_0)) - } - ErrorKind::NodeMigrationError(__self_0) => { - ErrorKind::NodeMigrationError(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ErrorKind { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - ErrorKind::Sign(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Sign", - &__self_0, - ) - } - ErrorKind::Respond(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Respond", - &__self_0, - ) - } - ErrorKind::PublicKey(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "PublicKey", - &__self_0, - ) - } - ErrorKind::Vote(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Vote", - &__self_0, - ) - } - ErrorKind::InvalidParameters(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InvalidParameters", - &__self_0, - ) - } - ErrorKind::InvalidState(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InvalidState", - &__self_0, - ) - } - ErrorKind::ConversionError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ConversionError", - &__self_0, - ) - } - ErrorKind::InvalidThreshold(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InvalidThreshold", - &__self_0, - ) - } - ErrorKind::InvalidCandidateSet(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InvalidCandidateSet", - &__self_0, - ) - } - ErrorKind::KeyEventError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "KeyEventError", - &__self_0, - ) - } - ErrorKind::DomainError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DomainError", - &__self_0, - ) - } - ErrorKind::TeeError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "TeeError", - &__self_0, - ) - } - ErrorKind::NodeMigrationError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "NodeMigrationError", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ErrorKind { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ErrorKind {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ErrorKind { - #[inline] - fn eq(&self, other: &ErrorKind) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - (ErrorKind::Sign(__self_0), ErrorKind::Sign(__arg1_0)) => { - __self_0 == __arg1_0 - } - (ErrorKind::Respond(__self_0), ErrorKind::Respond(__arg1_0)) => { - __self_0 == __arg1_0 - } - (ErrorKind::PublicKey(__self_0), ErrorKind::PublicKey(__arg1_0)) => { - __self_0 == __arg1_0 - } - (ErrorKind::Vote(__self_0), ErrorKind::Vote(__arg1_0)) => { - __self_0 == __arg1_0 - } - ( - ErrorKind::InvalidParameters(__self_0), - ErrorKind::InvalidParameters(__arg1_0), - ) => __self_0 == __arg1_0, - ( - ErrorKind::InvalidState(__self_0), - ErrorKind::InvalidState(__arg1_0), - ) => __self_0 == __arg1_0, - ( - ErrorKind::ConversionError(__self_0), - ErrorKind::ConversionError(__arg1_0), - ) => __self_0 == __arg1_0, - ( - ErrorKind::InvalidThreshold(__self_0), - ErrorKind::InvalidThreshold(__arg1_0), - ) => __self_0 == __arg1_0, - ( - ErrorKind::InvalidCandidateSet(__self_0), - ErrorKind::InvalidCandidateSet(__arg1_0), - ) => __self_0 == __arg1_0, - ( - ErrorKind::KeyEventError(__self_0), - ErrorKind::KeyEventError(__arg1_0), - ) => __self_0 == __arg1_0, - ( - ErrorKind::DomainError(__self_0), - ErrorKind::DomainError(__arg1_0), - ) => __self_0 == __arg1_0, - (ErrorKind::TeeError(__self_0), ErrorKind::TeeError(__arg1_0)) => { - __self_0 == __arg1_0 - } - ( - ErrorKind::NodeMigrationError(__self_0), - ErrorKind::NodeMigrationError(__arg1_0), - ) => __self_0 == __arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for ErrorKind { - fn source( - &self, - ) -> ::core::option::Option<&(dyn ::thiserror::__private17::Error + 'static)> { - use ::thiserror::__private17::AsDynError as _; - #[allow(deprecated)] - match self { - ErrorKind::Sign { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::Respond { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::PublicKey { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::Vote { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::InvalidParameters { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::InvalidState { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::ConversionError { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::InvalidThreshold { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::InvalidCandidateSet { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::KeyEventError { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::DomainError { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::TeeError { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - ErrorKind::NodeMigrationError { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for ErrorKind { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use ::thiserror::__private17::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - ErrorKind::Sign(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::Respond(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::PublicKey(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::Vote(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::InvalidParameters(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::InvalidState(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::ConversionError(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::InvalidThreshold(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::InvalidCandidateSet(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::KeyEventError(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::DomainError(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::TeeError(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorKind::NodeMigrationError(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: SignError) -> Self { - ErrorKind::Sign { 0: source } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: RespondError) -> Self { - ErrorKind::Respond { 0: source } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: PublicKeyError) -> Self { - ErrorKind::PublicKey { 0: source } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: VoteError) -> Self { - ErrorKind::Vote { 0: source } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: InvalidParameters) -> Self { - ErrorKind::InvalidParameters { - 0: source, - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: InvalidState) -> Self { - ErrorKind::InvalidState { - 0: source, - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: ConversionError) -> Self { - ErrorKind::ConversionError { - 0: source, - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: InvalidThreshold) -> Self { - ErrorKind::InvalidThreshold { - 0: source, - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: InvalidCandidateSet) -> Self { - ErrorKind::InvalidCandidateSet { - 0: source, - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: KeyEventError) -> Self { - ErrorKind::KeyEventError { - 0: source, - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: DomainError) -> Self { - ErrorKind::DomainError { - 0: source, - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: TeeError) -> Self { - ErrorKind::TeeError { 0: source } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From for ErrorKind { - fn from(source: NodeMigrationError) -> Self { - ErrorKind::NodeMigrationError { - 0: source, - } - } - } - enum ErrorRepr { - #[error("{0}")] - Simple(ErrorKind), - #[error("{message}")] - Message { kind: ErrorKind, message: Cow<'static, str> }, - } - #[automatically_derived] - impl ::core::fmt::Debug for ErrorRepr { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - ErrorRepr::Simple(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Simple", - &__self_0, - ) - } - ErrorRepr::Message { kind: __self_0, message: __self_1 } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Message", - "kind", - __self_0, - "message", - &__self_1, - ) - } - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for ErrorRepr {} - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for ErrorRepr { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use ::thiserror::__private17::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - ErrorRepr::Simple(_0) => { - match (_0.as_display(),) { - (__display0,) => { - __formatter.write_fmt(format_args!("{0}", __display0)) - } - } - } - ErrorRepr::Message { kind, message } => { - match (message.as_display(),) { - (__display_message,) => { - __formatter.write_fmt(format_args!("{0}", __display_message)) - } - } - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ErrorRepr {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ErrorRepr { - #[inline] - fn eq(&self, other: &ErrorRepr) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - (ErrorRepr::Simple(__self_0), ErrorRepr::Simple(__arg1_0)) => { - __self_0 == __arg1_0 - } - ( - ErrorRepr::Message { kind: __self_0, message: __self_1 }, - ErrorRepr::Message { kind: __arg1_0, message: __arg1_1 }, - ) => __self_0 == __arg1_0 && __self_1 == __arg1_1, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ErrorRepr { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - /// Error type that this contract will make use of for all the errors - /// returned from this library - pub struct Error { - repr: ErrorRepr, - } - #[automatically_derived] - impl ::core::fmt::Debug for Error { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Error", - "repr", - &&self.repr, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Error {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Error { - #[inline] - fn eq(&self, other: &Error) -> bool { - self.repr == other.repr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Error { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - impl near_sdk::FunctionError for Error { - fn panic(&self) -> ! { - crate::env::panic_str(&self.to_string()) - } - } -} -pub mod node_migrations { - use std::collections::BTreeMap; - use contract_interface::types::Ed25519PublicKey; - use near_account_id::AccountId; - use near_sdk::{near, store::IterableMap}; - use crate::{primitives::participants::ParticipantInfo, storage_keys::StorageKey}; - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct NodeMigrations { - backup_services_info: IterableMap, - ongoing_migrations: IterableMap, - } - #[automatically_derived] - impl ::core::fmt::Debug for NodeMigrations { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "NodeMigrations", - "backup_services_info", - &self.backup_services_info, - "ongoing_migrations", - &&self.ongoing_migrations, - ) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for NodeMigrations { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.backup_services_info, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.ongoing_migrations, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for NodeMigrations { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - backup_services_info: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - ongoing_migrations: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - impl Default for NodeMigrations { - fn default() -> Self { - Self { - backup_services_info: IterableMap::new(StorageKey::BackupServicesInfo), - ongoing_migrations: IterableMap::new(StorageKey::NodeMigrations), - } - } - } - impl NodeMigrations { - pub(crate) fn backup_services_info( - &self, - ) -> &IterableMap { - &self.backup_services_info - } - pub fn set_backup_service_info( - &mut self, - account_id: AccountId, - info: BackupServiceInfo, - ) { - self.backup_services_info.insert(account_id, info); - } - pub fn set_destination_node_info( - &mut self, - account_id: AccountId, - destination_node_info: DestinationNodeInfo, - ) { - self.ongoing_migrations.insert(account_id, destination_node_info); - } - pub fn remove_account_data(&mut self, account_id: &AccountId) { - self.backup_services_info.remove(account_id); - self.ongoing_migrations.remove(account_id); - } - pub fn remove_migration( - &mut self, - account_id: &AccountId, - ) -> Option { - self.ongoing_migrations.remove(account_id) - } - pub fn get_for_account( - &self, - account_id: &AccountId, - ) -> (AccountId, Option, Option) { - ( - account_id.clone(), - self.backup_services_info.get(account_id).cloned(), - self.ongoing_migrations.get(account_id).cloned(), - ) - } - pub fn get_all( - &self, - ) -> BTreeMap< - AccountId, - (Option, Option), - > { - let mut combined: BTreeMap< - AccountId, - (Option, Option), - > = BTreeMap::new(); - for (id, backup_serivce_info) in self.backup_services_info.iter() { - combined.insert(id.clone(), (Some(backup_serivce_info.clone()), None)); - } - for (id, destination_node_info) in self.ongoing_migrations.iter() { - combined - .entry(id.clone()) - .and_modify(|entry| entry.1 = Some(destination_node_info.clone())) - .or_insert((None, Some(destination_node_info.clone()))); - } - combined - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct BackupServiceInfo { - pub public_key: Ed25519PublicKey, - } - impl ::near_sdk::borsh::ser::BorshSerialize for BackupServiceInfo { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.public_key, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for BackupServiceInfo { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for BackupServiceInfo { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "BackupServiceInfo", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "public_key", - &self.public_key, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for BackupServiceInfo { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "public_key" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"public_key" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = BackupServiceInfo; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct BackupServiceInfo", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Ed25519PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct BackupServiceInfo with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(BackupServiceInfo { - public_key: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - Ed25519PublicKey, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "public_key", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Ed25519PublicKey, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("public_key")? - } - }; - _serde::__private228::Ok(BackupServiceInfo { - public_key: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["public_key"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "BackupServiceInfo", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for BackupServiceInfo { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "BackupServiceInfo", - "public_key", - &&self.public_key, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BackupServiceInfo {} - #[automatically_derived] - impl ::core::cmp::PartialEq for BackupServiceInfo { - #[inline] - fn eq(&self, other: &BackupServiceInfo) -> bool { - self.public_key == other.public_key - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for BackupServiceInfo { - #[inline] - fn partial_cmp( - &self, - other: &BackupServiceInfo, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.public_key, &other.public_key) - } - } - #[automatically_derived] - impl ::core::clone::Clone for BackupServiceInfo { - #[inline] - fn clone(&self) -> BackupServiceInfo { - BackupServiceInfo { - public_key: ::core::clone::Clone::clone(&self.public_key), - } - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct DestinationNodeInfo { - /// the public key used by the node to sign transactions to the contract - /// this key is different from the TLS key called `sign_pk` and stored in `ParticipantInfo`. - pub signer_account_pk: near_sdk::PublicKey, - pub destination_node_info: ParticipantInfo, - } - impl ::near_sdk::borsh::ser::BorshSerialize for DestinationNodeInfo { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.signer_account_pk, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.destination_node_info, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for DestinationNodeInfo { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - signer_account_pk: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - destination_node_info: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for DestinationNodeInfo { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "DestinationNodeInfo", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "signer_account_pk", - &self.signer_account_pk, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "destination_node_info", - &self.destination_node_info, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for DestinationNodeInfo { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "signer_account_pk" => { - _serde::__private228::Ok(__Field::__field0) - } - "destination_node_info" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"signer_account_pk" => { - _serde::__private228::Ok(__Field::__field0) - } - b"destination_node_info" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = DestinationNodeInfo; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct DestinationNodeInfo", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - near_sdk::PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct DestinationNodeInfo with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - ParticipantInfo, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct DestinationNodeInfo with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(DestinationNodeInfo { - signer_account_pk: __field0, - destination_node_info: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - near_sdk::PublicKey, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - ParticipantInfo, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "signer_account_pk", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - near_sdk::PublicKey, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "destination_node_info", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - ParticipantInfo, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "signer_account_pk", - )? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "destination_node_info", - )? - } - }; - _serde::__private228::Ok(DestinationNodeInfo { - signer_account_pk: __field0, - destination_node_info: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "signer_account_pk", - "destination_node_info", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "DestinationNodeInfo", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for DestinationNodeInfo { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "DestinationNodeInfo", - "signer_account_pk", - &self.signer_account_pk, - "destination_node_info", - &&self.destination_node_info, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for DestinationNodeInfo { - #[inline] - fn clone(&self) -> DestinationNodeInfo { - DestinationNodeInfo { - signer_account_pk: ::core::clone::Clone::clone(&self.signer_account_pk), - destination_node_info: ::core::clone::Clone::clone( - &self.destination_node_info, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DestinationNodeInfo {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DestinationNodeInfo { - #[inline] - fn eq(&self, other: &DestinationNodeInfo) -> bool { - self.signer_account_pk == other.signer_account_pk - && self.destination_node_info == other.destination_node_info - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for DestinationNodeInfo { - #[inline] - fn partial_cmp( - &self, - other: &DestinationNodeInfo, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.signer_account_pk, - &other.signer_account_pk, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.destination_node_info, - &other.destination_node_info, - ) - } - cmp => cmp, - } - } - } -} -pub mod primitives { - pub mod ckd { - use crate::{crypto_shared::kdf::derive_app_id, primitives::domain::DomainId}; - use contract_interface::types as dtos; - use near_account_id::AccountId; - use near_sdk::near; - #[serde(crate = ":: near_sdk :: serde")] - pub struct CKDRequestArgs { - pub derivation_path: String, - pub app_public_key: dtos::Bls12381G1PublicKey, - pub domain_id: DomainId, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for CKDRequestArgs { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "CKDRequestArgs", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "derivation_path", - &self.derivation_path, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "app_public_key", - &self.app_public_key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for CKDRequestArgs { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "derivation_path" => { - _serde::__private228::Ok(__Field::__field0) - } - "app_public_key" => { - _serde::__private228::Ok(__Field::__field1) - } - "domain_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"derivation_path" => { - _serde::__private228::Ok(__Field::__field0) - } - b"app_public_key" => { - _serde::__private228::Ok(__Field::__field1) - } - b"domain_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = CKDRequestArgs; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct CKDRequestArgs", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct CKDRequestArgs with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - dtos::Bls12381G1PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct CKDRequestArgs with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - DomainId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct CKDRequestArgs with 3 elements", - ), - ); - } - }; - _serde::__private228::Ok(CKDRequestArgs { - derivation_path: __field0, - app_public_key: __field1, - domain_id: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - dtos::Bls12381G1PublicKey, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "derivation_path", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "app_public_key", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - dtos::Bls12381G1PublicKey, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domain_id", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("derivation_path")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("app_public_key")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domain_id")? - } - }; - _serde::__private228::Ok(CKDRequestArgs { - derivation_path: __field0, - app_public_key: __field1, - domain_id: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "derivation_path", - "app_public_key", - "domain_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "CKDRequestArgs", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for CKDRequestArgs { - #[inline] - fn clone(&self) -> CKDRequestArgs { - CKDRequestArgs { - derivation_path: ::core::clone::Clone::clone(&self.derivation_path), - app_public_key: ::core::clone::Clone::clone(&self.app_public_key), - domain_id: ::core::clone::Clone::clone(&self.domain_id), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for CKDRequestArgs { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "CKDRequestArgs", - "derivation_path", - &self.derivation_path, - "app_public_key", - &self.app_public_key, - "domain_id", - &&self.domain_id, - ) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct CKDRequest { - /// The app ephemeral public key - pub app_public_key: dtos::Bls12381G1PublicKey, - pub app_id: dtos::CkdAppId, - pub domain_id: DomainId, - } - impl ::near_sdk::borsh::ser::BorshSerialize for CKDRequest { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.app_public_key, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.app_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for CKDRequest { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - app_public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - app_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for CKDRequest { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "CKDRequest", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "app_public_key", - &self.app_public_key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "app_id", - &self.app_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for CKDRequest { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "app_public_key" => { - _serde::__private228::Ok(__Field::__field0) - } - "app_id" => _serde::__private228::Ok(__Field::__field1), - "domain_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"app_public_key" => { - _serde::__private228::Ok(__Field::__field0) - } - b"app_id" => _serde::__private228::Ok(__Field::__field1), - b"domain_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = CKDRequest; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct CKDRequest", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - dtos::Bls12381G1PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct CKDRequest with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - dtos::CkdAppId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct CKDRequest with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - DomainId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct CKDRequest with 3 elements", - ), - ); - } - }; - _serde::__private228::Ok(CKDRequest { - app_public_key: __field0, - app_id: __field1, - domain_id: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - dtos::Bls12381G1PublicKey, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - dtos::CkdAppId, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "app_public_key", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - dtos::Bls12381G1PublicKey, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("app_id"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - dtos::CkdAppId, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domain_id", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("app_public_key")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("app_id")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domain_id")? - } - }; - _serde::__private228::Ok(CKDRequest { - app_public_key: __field0, - app_id: __field1, - domain_id: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "app_public_key", - "app_id", - "domain_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "CKDRequest", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for CKDRequest { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "CKDRequest", - "app_public_key", - &self.app_public_key, - "app_id", - &self.app_id, - "domain_id", - &&self.domain_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for CKDRequest { - #[inline] - fn clone(&self) -> CKDRequest { - CKDRequest { - app_public_key: ::core::clone::Clone::clone(&self.app_public_key), - app_id: ::core::clone::Clone::clone(&self.app_id), - domain_id: ::core::clone::Clone::clone(&self.domain_id), - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for CKDRequest { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::Ord for CKDRequest { - #[inline] - fn cmp(&self, other: &CKDRequest) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp( - &self.app_public_key, - &other.app_public_key, - ) { - ::core::cmp::Ordering::Equal => { - match ::core::cmp::Ord::cmp(&self.app_id, &other.app_id) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.domain_id, &other.domain_id) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for CKDRequest {} - #[automatically_derived] - impl ::core::cmp::PartialEq for CKDRequest { - #[inline] - fn eq(&self, other: &CKDRequest) -> bool { - self.app_public_key == other.app_public_key - && self.app_id == other.app_id && self.domain_id == other.domain_id - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for CKDRequest { - #[inline] - fn partial_cmp( - &self, - other: &CKDRequest, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.app_public_key, - &other.app_public_key, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - match ::core::cmp::PartialOrd::partial_cmp( - &self.app_id, - &other.app_id, - ) { - ::core::option::Option::Some( - ::core::cmp::Ordering::Equal, - ) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.domain_id, - &other.domain_id, - ) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - impl CKDRequest { - pub fn new( - app_public_key: dtos::Bls12381G1PublicKey, - domain_id: DomainId, - predecessor_id: &AccountId, - derivation_path: &str, - ) -> Self { - let app_id = derive_app_id(predecessor_id, derivation_path); - Self { - app_public_key, - app_id, - domain_id, - } - } - } - } - pub mod domain { - use super::key_state::AuthenticatedParticipantId; - use crate::errors::{DomainError, Error}; - use derive_more::{Deref, From}; - use near_sdk::{log, near}; - use std::collections::BTreeMap; - use std::fmt::Display; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Each domain corresponds to a specific root key in a specific signature scheme. There may be - /// multiple domains per signature scheme. The domain ID uniquely identifies a domain. - pub struct DomainId(pub u64); - #[automatically_derived] - impl ::core::fmt::Debug for DomainId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DomainId", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for DomainId { - #[inline] - fn clone(&self) -> DomainId { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for DomainId {} - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DomainId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DomainId { - #[inline] - fn eq(&self, other: &DomainId) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DomainId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::hash::Hash for DomainId { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for DomainId { - #[inline] - fn partial_cmp( - &self, - other: &DomainId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for DomainId { - #[inline] - fn cmp(&self, other: &DomainId) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[allow(unreachable_code)] - #[automatically_derived] - impl derive_more::core::convert::From<(u64)> for DomainId { - #[inline] - fn from(value: (u64)) -> Self { - DomainId(value) - } - } - #[allow(unreachable_code)] - #[automatically_derived] - impl derive_more::with_trait::Deref for DomainId { - type Target = u64; - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for DomainId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for DomainId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for DomainId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "DomainId", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for DomainId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = DomainId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct DomainId", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: u64 = ::deserialize( - __e, - )?; - _serde::__private228::Ok(DomainId(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct DomainId with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(DomainId(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "DomainId", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl Default for DomainId { - fn default() -> Self { - Self::legacy_ecdsa_id() - } - } - impl DomainId { - /// Returns the DomainId of the single ECDSA key present in the contract before V2. - pub fn legacy_ecdsa_id() -> Self { - Self(0) - } - } - impl Display for DomainId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Uniquely identifies a specific request algorithm. - /// More protocols may be added in the future. When adding new protocols, both Borsh - /// *and* JSON serialization must be kept compatible. - pub enum SignatureScheme { - Secp256k1, - Ed25519, - Bls12381, - V2Secp256k1, - } - #[automatically_derived] - impl ::core::fmt::Debug for SignatureScheme { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - SignatureScheme::Secp256k1 => "Secp256k1", - SignatureScheme::Ed25519 => "Ed25519", - SignatureScheme::Bls12381 => "Bls12381", - SignatureScheme::V2Secp256k1 => "V2Secp256k1", - }, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for SignatureScheme { - #[inline] - fn clone(&self) -> SignatureScheme { - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for SignatureScheme {} - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SignatureScheme {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SignatureScheme { - #[inline] - fn eq(&self, other: &SignatureScheme) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for SignatureScheme { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - impl ::near_sdk::borsh::ser::BorshSerialize for SignatureScheme { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - let variant_idx: u8 = match self { - SignatureScheme::Secp256k1 => 0u8, - SignatureScheme::Ed25519 => 1u8, - SignatureScheme::Bls12381 => 2u8, - SignatureScheme::V2Secp256k1 => 3u8, - }; - writer.write_all(&variant_idx.to_le_bytes())?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for SignatureScheme { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - let tag = ::deserialize_reader( - reader, - )?; - ::deserialize_variant( - reader, - tag, - ) - } - } - impl ::near_sdk::borsh::de::EnumExt for SignatureScheme { - fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - variant_tag: u8, - ) -> ::core::result::Result { - let mut return_value = if variant_tag == 0u8 { - SignatureScheme::Secp256k1 - } else if variant_tag == 1u8 { - SignatureScheme::Ed25519 - } else if variant_tag == 2u8 { - SignatureScheme::Bls12381 - } else if variant_tag == 3u8 { - SignatureScheme::V2Secp256k1 - } else { - return Err( - ::near_sdk::borsh::io::Error::new( - ::near_sdk::borsh::io::ErrorKind::InvalidData, - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Unexpected variant tag: {0:?}", variant_tag), - ); - res - }), - ), - ) - }; - Ok(return_value) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SignatureScheme { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - SignatureScheme::Secp256k1 => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "SignatureScheme", - 0u32, - "Secp256k1", - ) - } - SignatureScheme::Ed25519 => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "SignatureScheme", - 1u32, - "Ed25519", - ) - } - SignatureScheme::Bls12381 => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "SignatureScheme", - 2u32, - "Bls12381", - ) - } - SignatureScheme::V2Secp256k1 => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "SignatureScheme", - 3u32, - "V2Secp256k1", - ) - } - } - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SignatureScheme { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - _ => { - _serde::__private228::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 4", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "Secp256k1" => _serde::__private228::Ok(__Field::__field0), - "Ed25519" => _serde::__private228::Ok(__Field::__field1), - "Bls12381" => _serde::__private228::Ok(__Field::__field2), - "V2Secp256k1" => _serde::__private228::Ok(__Field::__field3), - _ => { - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"Secp256k1" => _serde::__private228::Ok(__Field::__field0), - b"Ed25519" => _serde::__private228::Ok(__Field::__field1), - b"Bls12381" => _serde::__private228::Ok(__Field::__field2), - b"V2Secp256k1" => { - _serde::__private228::Ok(__Field::__field3) - } - _ => { - let __value = &_serde::__private228::from_utf8_lossy( - __value, - ); - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SignatureScheme; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "enum SignatureScheme", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private228::Ok(SignatureScheme::Secp256k1) - } - (__Field::__field1, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private228::Ok(SignatureScheme::Ed25519) - } - (__Field::__field2, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private228::Ok(SignatureScheme::Bls12381) - } - (__Field::__field3, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private228::Ok(SignatureScheme::V2Secp256k1) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "Secp256k1", - "Ed25519", - "Bls12381", - "V2Secp256k1", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "SignatureScheme", - VARIANTS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl Default for SignatureScheme { - fn default() -> Self { - Self::Secp256k1 - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Describes the configuration of a domain: the domain ID and the protocol it uses. - pub struct DomainConfig { - pub id: DomainId, - pub scheme: SignatureScheme, - } - #[automatically_derived] - impl ::core::fmt::Debug for DomainConfig { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "DomainConfig", - "id", - &self.id, - "scheme", - &&self.scheme, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for DomainConfig { - #[inline] - fn clone(&self) -> DomainConfig { - DomainConfig { - id: ::core::clone::Clone::clone(&self.id), - scheme: ::core::clone::Clone::clone(&self.scheme), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DomainConfig {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DomainConfig { - #[inline] - fn eq(&self, other: &DomainConfig) -> bool { - self.id == other.id && self.scheme == other.scheme - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DomainConfig { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for DomainConfig { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.scheme, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for DomainConfig { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - scheme: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for DomainConfig { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "DomainConfig", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "id", - &self.id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "scheme", - &self.scheme, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for DomainConfig { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "id" => _serde::__private228::Ok(__Field::__field0), - "scheme" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"id" => _serde::__private228::Ok(__Field::__field0), - b"scheme" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = DomainConfig; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct DomainConfig", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - DomainId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct DomainConfig with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - SignatureScheme, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct DomainConfig with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(DomainConfig { - id: __field0, - scheme: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - SignatureScheme, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("id"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("scheme"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - SignatureScheme, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("scheme")? - } - }; - _serde::__private228::Ok(DomainConfig { - id: __field0, - scheme: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["id", "scheme"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "DomainConfig", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// All the domains present in the contract, as well as the next domain ID which is kept to ensure - /// that we never reuse domain IDs. (Domains may be deleted in only one case: when we decided to - /// add domains but ultimately canceled that process.) - pub struct DomainRegistry { - domains: Vec, - next_domain_id: u64, - } - #[automatically_derived] - impl ::core::fmt::Debug for DomainRegistry { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "DomainRegistry", - "domains", - &self.domains, - "next_domain_id", - &&self.next_domain_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for DomainRegistry { - #[inline] - fn clone(&self) -> DomainRegistry { - DomainRegistry { - domains: ::core::clone::Clone::clone(&self.domains), - next_domain_id: ::core::clone::Clone::clone(&self.next_domain_id), - } - } - } - #[automatically_derived] - impl ::core::default::Default for DomainRegistry { - #[inline] - fn default() -> DomainRegistry { - DomainRegistry { - domains: ::core::default::Default::default(), - next_domain_id: ::core::default::Default::default(), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DomainRegistry {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DomainRegistry { - #[inline] - fn eq(&self, other: &DomainRegistry) -> bool { - self.domains == other.domains - && self.next_domain_id == other.next_domain_id - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DomainRegistry { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for DomainRegistry { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.next_domain_id, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for DomainRegistry { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - next_domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for DomainRegistry { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "DomainRegistry", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domains", - &self.domains, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "next_domain_id", - &self.next_domain_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for DomainRegistry { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "domains" => _serde::__private228::Ok(__Field::__field0), - "next_domain_id" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"domains" => _serde::__private228::Ok(__Field::__field0), - b"next_domain_id" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = DomainRegistry; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct DomainRegistry", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct DomainRegistry with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct DomainRegistry with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(DomainRegistry { - domains: __field0, - next_domain_id: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - Vec, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domains", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Vec, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "next_domain_id", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domains")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("next_domain_id")? - } - }; - _serde::__private228::Ok(DomainRegistry { - domains: __field0, - next_domain_id: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "domains", - "next_domain_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "DomainRegistry", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl DomainRegistry { - pub fn domains(&self) -> &[DomainConfig] { - &self.domains - } - /// Migration from legacy: creates a DomainRegistry with a single ecdsa key. - pub fn new_single_ecdsa_key_from_legacy() -> Self { - let mut registry = Self::default(); - registry.add_domain(SignatureScheme::Secp256k1); - registry - } - /// Add a single domain with the given protocol, returning the DomainId of the added - /// domain. - fn add_domain(&mut self, scheme: SignatureScheme) -> DomainId { - let domain = DomainConfig { - id: DomainId(self.next_domain_id), - scheme, - }; - self.next_domain_id += 1; - self.domains.push(domain.clone()); - domain.id - } - /// Processes the addition of the given domains, returning a new DomainRegistry. - /// This stringently requires that the domains specified have sorted and contiguous IDs starting - /// from next_domain_id, returning an error otherwise. - pub fn add_domains( - &self, - domains: Vec, - ) -> Result { - let mut new_registry = self.clone(); - for domain in domains { - let new_domain_id = new_registry.add_domain(domain.scheme); - if new_domain_id != domain.id { - return Err( - DomainError::NewDomainIdsNotContiguous { - expected_id: new_domain_id, - } - .into(), - ); - } - } - Ok(new_registry) - } - /// Retain a prefix of the given number of domains. This is used for cancelling key generation, - /// where we would delete whatever domains we failed to generate a key for. - pub fn retain_domains(&mut self, num_domains: usize) { - self.domains.truncate(num_domains); - } - /// Returns the given domain by the index, not the DomainId. - pub fn get_domain_by_index(&self, index: usize) -> Option<&DomainConfig> { - self.domains.get(index) - } - /// Returns the given domain by the DomainId. - pub fn get_domain_by_domain_id( - &self, - id: DomainId, - ) -> Option<&DomainConfig> { - self.domains.iter().find(|domain| domain.id == id) - } - /// Returns the most recently added domain for the given protocol, - /// or None if no such domain exists. - pub fn most_recent_domain_for_protocol( - &self, - scheme: SignatureScheme, - ) -> Option { - self.domains - .iter() - .rev() - .find(|domain| domain.scheme == scheme) - .map(|domain| domain.id) - } - /// Constructs a DomainRegistry from its raw fields, but performing basic - /// validation that the fields could've been produced by a valid - /// sequence of add_domains and retain_domains calls. This is used for - /// init_running and testing only. - pub fn from_raw_validated( - domains: Vec, - next_domain_id: u64, - ) -> Result { - let registry = Self { domains, next_domain_id }; - for (left, right) in registry - .domains - .iter() - .zip(registry.domains.iter().skip(1)) - { - if left.id.0 >= right.id.0 { - return Err(DomainError::InvalidDomains.into()); - } - } - if let Some(largest_domain_id) = registry - .domains - .last() - .map(|domain| domain.id.0) - { - if largest_domain_id >= registry.next_domain_id { - return Err(DomainError::InvalidDomains.into()); - } - } - Ok(registry) - } - pub fn next_domain_id(&self) -> u64 { - self.next_domain_id - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Tracks votes to add domains. Each participant can at any given time vote for a list of domains - /// to add. - pub struct AddDomainsVotes { - proposal_by_account: BTreeMap>, - } - #[automatically_derived] - impl ::core::fmt::Debug for AddDomainsVotes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "AddDomainsVotes", - "proposal_by_account", - &&self.proposal_by_account, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for AddDomainsVotes { - #[inline] - fn clone(&self) -> AddDomainsVotes { - AddDomainsVotes { - proposal_by_account: ::core::clone::Clone::clone( - &self.proposal_by_account, - ), - } - } - } - #[automatically_derived] - impl ::core::default::Default for AddDomainsVotes { - #[inline] - fn default() -> AddDomainsVotes { - AddDomainsVotes { - proposal_by_account: ::core::default::Default::default(), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AddDomainsVotes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AddDomainsVotes { - #[inline] - fn eq(&self, other: &AddDomainsVotes) -> bool { - self.proposal_by_account == other.proposal_by_account - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AddDomainsVotes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq< - BTreeMap>, - >; - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for AddDomainsVotes { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.proposal_by_account, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for AddDomainsVotes { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - proposal_by_account: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for AddDomainsVotes { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "AddDomainsVotes", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "proposal_by_account", - &self.proposal_by_account, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for AddDomainsVotes { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "proposal_by_account" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"proposal_by_account" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = AddDomainsVotes; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct AddDomainsVotes", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - BTreeMap>, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct AddDomainsVotes with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(AddDomainsVotes { - proposal_by_account: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - BTreeMap>, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "proposal_by_account", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - BTreeMap>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "proposal_by_account", - )? - } - }; - _serde::__private228::Ok(AddDomainsVotes { - proposal_by_account: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["proposal_by_account"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "AddDomainsVotes", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl AddDomainsVotes { - /// Votes for the proposal, returning the total number of voters so far who - /// have proposed the exact same domains to add. - /// If the participant had voted already, this replaces the existing vote. - pub fn vote( - &mut self, - proposal: Vec, - participant: &AuthenticatedParticipantId, - ) -> u64 { - if self - .proposal_by_account - .insert(participant.clone(), proposal.clone()) - .is_some() - { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("removed old vote for signer"), - ); - res - }) - .as_str(), - ); - } - let total = self - .proposal_by_account - .values() - .filter(|&prop| prop == &proposal) - .count() as u64; - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("total votes for proposal: {0}", total), - ); - res - }) - .as_str(), - ); - total - } - } - } - pub mod key_state { - use super::domain::DomainId; - use super::participants::{ParticipantId, Participants}; - use crate::crypto_shared::types::PublicKeyExtended; - use crate::errors::{DomainError, Error, InvalidState}; - use near_account_id::AccountId; - use near_sdk::{env, near}; - use std::fmt::Display; - use utilities::AccountIdExtV1; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// An EpochId uniquely identifies a ThresholdParameters (but not vice-versa). - /// Every time we change the ThresholdParameters (participants and threshold), - /// we increment EpochId. - /// Locally on each node, each keyshare is uniquely identified by the tuple - /// (EpochId, DomainId, AttemptId). - pub struct EpochId(u64); - #[automatically_derived] - impl ::core::fmt::Debug for EpochId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "EpochId", &&self.0) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for EpochId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for EpochId { - #[inline] - fn eq(&self, other: &EpochId) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for EpochId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for EpochId { - #[inline] - fn clone(&self) -> EpochId { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for EpochId {} - #[automatically_derived] - impl ::core::hash::Hash for EpochId { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for EpochId { - #[inline] - fn partial_cmp( - &self, - other: &EpochId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for EpochId { - #[inline] - fn cmp(&self, other: &EpochId) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for EpochId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for EpochId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for EpochId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "EpochId", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for EpochId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = EpochId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct EpochId", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: u64 = ::deserialize( - __e, - )?; - _serde::__private228::Ok(EpochId(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct EpochId with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(EpochId(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "EpochId", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl EpochId { - pub const fn next(&self) -> Self { - EpochId(self.0 + 1) - } - pub const fn new(epoch_id: u64) -> Self { - EpochId(epoch_id) - } - pub fn get(&self) -> u64 { - self.0 - } - } - impl Display for EpochId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct AttemptId(u64); - #[automatically_derived] - impl ::core::fmt::Debug for AttemptId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "AttemptId", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AttemptId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AttemptId { - #[inline] - fn eq(&self, other: &AttemptId) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AttemptId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for AttemptId { - #[inline] - fn clone(&self) -> AttemptId { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for AttemptId {} - #[automatically_derived] - impl ::core::hash::Hash for AttemptId { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for AttemptId { - #[inline] - fn partial_cmp( - &self, - other: &AttemptId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for AttemptId { - #[inline] - fn cmp(&self, other: &AttemptId) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for AttemptId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for AttemptId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for AttemptId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "AttemptId", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for AttemptId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = AttemptId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct AttemptId", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: u64 = ::deserialize( - __e, - )?; - _serde::__private228::Ok(AttemptId(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct AttemptId with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(AttemptId(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "AttemptId", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl AttemptId { - pub fn new() -> Self { - AttemptId(0) - } - pub fn next(&self) -> Self { - AttemptId(&self.0 + 1) - } - pub fn get(&self) -> u64 { - self.0 - } - pub fn legacy_attempt_id() -> Self { - AttemptId(0) - } - } - impl Default for AttemptId { - fn default() -> Self { - Self::new() - } - } - impl Display for AttemptId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// A unique identifier for a key event (generation or resharing): - /// `epoch_id`: identifies the ThresholdParameters that this key is intended to function in. - /// `domain_id`: the domain this key is intended for. - /// `attempt_id`: identifies a particular attempt for this key event, in case multiple attempts - /// yielded partially valid results. This is incremented for each attempt within the - /// same epoch and domain. - pub struct KeyEventId { - pub epoch_id: EpochId, - pub domain_id: DomainId, - pub attempt_id: AttemptId, - } - #[automatically_derived] - impl ::core::fmt::Debug for KeyEventId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "KeyEventId", - "epoch_id", - &self.epoch_id, - "domain_id", - &self.domain_id, - "attempt_id", - &&self.attempt_id, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for KeyEventId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for KeyEventId { - #[inline] - fn eq(&self, other: &KeyEventId) -> bool { - self.epoch_id == other.epoch_id && self.domain_id == other.domain_id - && self.attempt_id == other.attempt_id - } - } - #[automatically_derived] - impl ::core::cmp::Eq for KeyEventId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::marker::Copy for KeyEventId {} - #[automatically_derived] - impl ::core::clone::Clone for KeyEventId { - #[inline] - fn clone(&self) -> KeyEventId { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::hash::Hash for KeyEventId { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.epoch_id, state); - ::core::hash::Hash::hash(&self.domain_id, state); - ::core::hash::Hash::hash(&self.attempt_id, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for KeyEventId { - #[inline] - fn partial_cmp( - &self, - other: &KeyEventId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.epoch_id, - &other.epoch_id, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - match ::core::cmp::PartialOrd::partial_cmp( - &self.domain_id, - &other.domain_id, - ) { - ::core::option::Option::Some( - ::core::cmp::Ordering::Equal, - ) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.attempt_id, - &other.attempt_id, - ) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::Ord for KeyEventId { - #[inline] - fn cmp(&self, other: &KeyEventId) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.epoch_id, &other.epoch_id) { - ::core::cmp::Ordering::Equal => { - match ::core::cmp::Ord::cmp(&self.domain_id, &other.domain_id) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.attempt_id, &other.attempt_id) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for KeyEventId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.attempt_id, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for KeyEventId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - attempt_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for KeyEventId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "KeyEventId", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "epoch_id", - &self.epoch_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "attempt_id", - &self.attempt_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for KeyEventId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "epoch_id" => _serde::__private228::Ok(__Field::__field0), - "domain_id" => _serde::__private228::Ok(__Field::__field1), - "attempt_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"epoch_id" => _serde::__private228::Ok(__Field::__field0), - b"domain_id" => _serde::__private228::Ok(__Field::__field1), - b"attempt_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = KeyEventId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct KeyEventId", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - EpochId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct KeyEventId with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - DomainId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct KeyEventId with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - AttemptId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct KeyEventId with 3 elements", - ), - ); - } - }; - _serde::__private228::Ok(KeyEventId { - epoch_id: __field0, - domain_id: __field1, - attempt_id: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "epoch_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domain_id", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "attempt_id", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("epoch_id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domain_id")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("attempt_id")? - } - }; - _serde::__private228::Ok(KeyEventId { - epoch_id: __field0, - domain_id: __field1, - attempt_id: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "epoch_id", - "domain_id", - "attempt_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "KeyEventId", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl KeyEventId { - pub fn new( - epoch_id: EpochId, - domain_id: DomainId, - attempt_id: AttemptId, - ) -> Self { - KeyEventId { - epoch_id, - domain_id, - attempt_id, - } - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// The identification of a specific distributed key, based on which a node would know exactly what - /// keyshare it has corresponds to this distributed key. (A distributed key refers to a specific set - /// of keyshares that nodes have which can be pieced together to form the secret key.) - pub struct KeyForDomain { - /// Identifies the domain this key is intended for. - pub domain_id: DomainId, - /// Identifies the public key. Although technically redundant given that we have the AttemptId, - /// we keep it here in the contract so that it can be verified against and queried. - pub key: PublicKeyExtended, - /// The attempt ID that generated (initially or as a result of resharing) this distributed key. - /// Nodes may have made multiple attempts to generate the distributed key, and this uniquely - /// identifies which one should ultimately be used. - pub attempt: AttemptId, - } - #[automatically_derived] - impl ::core::fmt::Debug for KeyForDomain { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "KeyForDomain", - "domain_id", - &self.domain_id, - "key", - &self.key, - "attempt", - &&self.attempt, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for KeyForDomain {} - #[automatically_derived] - impl ::core::cmp::PartialEq for KeyForDomain { - #[inline] - fn eq(&self, other: &KeyForDomain) -> bool { - self.domain_id == other.domain_id && self.key == other.key - && self.attempt == other.attempt - } - } - #[automatically_derived] - impl ::core::cmp::Eq for KeyForDomain { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for KeyForDomain { - #[inline] - fn clone(&self) -> KeyForDomain { - KeyForDomain { - domain_id: ::core::clone::Clone::clone(&self.domain_id), - key: ::core::clone::Clone::clone(&self.key), - attempt: ::core::clone::Clone::clone(&self.attempt), - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for KeyForDomain { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.key, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.attempt, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for KeyForDomain { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - attempt: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for KeyForDomain { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "KeyForDomain", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key", - &self.key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "attempt", - &self.attempt, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for KeyForDomain { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "domain_id" => _serde::__private228::Ok(__Field::__field0), - "key" => _serde::__private228::Ok(__Field::__field1), - "attempt" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"domain_id" => _serde::__private228::Ok(__Field::__field0), - b"key" => _serde::__private228::Ok(__Field::__field1), - b"attempt" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = KeyForDomain; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct KeyForDomain", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - DomainId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct KeyForDomain with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - PublicKeyExtended, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct KeyForDomain with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - AttemptId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct KeyForDomain with 3 elements", - ), - ); - } - }; - _serde::__private228::Ok(KeyForDomain { - domain_id: __field0, - key: __field1, - attempt: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - PublicKeyExtended, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domain_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("key"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - PublicKeyExtended, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "attempt", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domain_id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("key")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("attempt")? - } - }; - _serde::__private228::Ok(KeyForDomain { - domain_id: __field0, - key: __field1, - attempt: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "domain_id", - "key", - "attempt", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "KeyForDomain", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Represents a key for every domain in a specific epoch. - pub struct Keyset { - pub epoch_id: EpochId, - pub domains: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for Keyset { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Keyset", - "epoch_id", - &self.epoch_id, - "domains", - &&self.domains, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Keyset {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Keyset { - #[inline] - fn eq(&self, other: &Keyset) -> bool { - self.epoch_id == other.epoch_id && self.domains == other.domains - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Keyset { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Keyset { - #[inline] - fn clone(&self) -> Keyset { - Keyset { - epoch_id: ::core::clone::Clone::clone(&self.epoch_id), - domains: ::core::clone::Clone::clone(&self.domains), - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for Keyset { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for Keyset { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Keyset { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Keyset", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "epoch_id", - &self.epoch_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domains", - &self.domains, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Keyset { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "epoch_id" => _serde::__private228::Ok(__Field::__field0), - "domains" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"epoch_id" => _serde::__private228::Ok(__Field::__field0), - b"domains" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Keyset; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct Keyset", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - EpochId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Keyset with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Keyset with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(Keyset { - epoch_id: __field0, - domains: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - Vec, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "epoch_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domains", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Vec, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("epoch_id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domains")? - } - }; - _serde::__private228::Ok(Keyset { - epoch_id: __field0, - domains: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["epoch_id", "domains"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Keyset", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl Keyset { - pub fn new(epoch_id: EpochId, domains: Vec) -> Self { - Keyset { epoch_id, domains } - } - pub fn public_key( - &self, - domain_id: DomainId, - ) -> Result { - Ok( - self - .domains - .iter() - .find(|k| k.domain_id == domain_id) - .ok_or(DomainError::NoSuchDomain)? - .key - .clone(), - ) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// This struct is supposed to contain the participant id associated to the account `env::signer_account_id()`, - /// but is only constructible given a set of participants that includes the signer, thus acting as - /// a type system-based enforcement mechanism (albeit a best-effort one) for authenticating the - /// signer. - pub struct AuthenticatedParticipantId(ParticipantId); - #[automatically_derived] - impl ::core::fmt::Debug for AuthenticatedParticipantId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "AuthenticatedParticipantId", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for AuthenticatedParticipantId { - #[inline] - fn clone(&self) -> AuthenticatedParticipantId { - AuthenticatedParticipantId(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AuthenticatedParticipantId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AuthenticatedParticipantId { - #[inline] - fn eq(&self, other: &AuthenticatedParticipantId) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AuthenticatedParticipantId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for AuthenticatedParticipantId { - #[inline] - fn partial_cmp( - &self, - other: &AuthenticatedParticipantId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for AuthenticatedParticipantId { - #[inline] - fn cmp(&self, other: &AuthenticatedParticipantId) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for AuthenticatedParticipantId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for AuthenticatedParticipantId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for AuthenticatedParticipantId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "AuthenticatedParticipantId", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for AuthenticatedParticipantId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - AuthenticatedParticipantId, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = AuthenticatedParticipantId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct AuthenticatedParticipantId", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: ParticipantId = ::deserialize( - __e, - )?; - _serde::__private228::Ok( - AuthenticatedParticipantId(__field0), - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - ParticipantId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct AuthenticatedParticipantId with 1 element", - ), - ); - } - }; - _serde::__private228::Ok( - AuthenticatedParticipantId(__field0), - ) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "AuthenticatedParticipantId", - __Visitor { - marker: _serde::__private228::PhantomData::< - AuthenticatedParticipantId, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl AuthenticatedParticipantId { - pub fn get(&self) -> ParticipantId { - self.0.clone() - } - pub fn new(participants: &Participants) -> Result { - let signer = env::signer_account_id().as_v2_account_id(); - participants - .participants() - .iter() - .find(|(a_id, _, _)| *a_id == signer) - .map(|(_, p_id, _)| AuthenticatedParticipantId(p_id.clone())) - .ok_or_else(|| InvalidState::NotParticipant.into()) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// This struct contains the account `env::signer_account_id()`, but is only constructible given a - /// set of participants that include the signer, thus acting as a typesystem-based enforcement - /// mechanism (albeit a best-effort one) for authenticating the signer. - pub struct AuthenticatedAccountId(AccountId); - #[automatically_derived] - impl ::core::fmt::Debug for AuthenticatedAccountId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "AuthenticatedAccountId", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for AuthenticatedAccountId { - #[inline] - fn clone(&self) -> AuthenticatedAccountId { - AuthenticatedAccountId(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AuthenticatedAccountId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AuthenticatedAccountId { - #[inline] - fn eq(&self, other: &AuthenticatedAccountId) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AuthenticatedAccountId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for AuthenticatedAccountId { - #[inline] - fn partial_cmp( - &self, - other: &AuthenticatedAccountId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for AuthenticatedAccountId { - #[inline] - fn cmp(&self, other: &AuthenticatedAccountId) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::hash::Hash for AuthenticatedAccountId { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for AuthenticatedAccountId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for AuthenticatedAccountId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for AuthenticatedAccountId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "AuthenticatedAccountId", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for AuthenticatedAccountId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - AuthenticatedAccountId, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = AuthenticatedAccountId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct AuthenticatedAccountId", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: AccountId = ::deserialize( - __e, - )?; - _serde::__private228::Ok(AuthenticatedAccountId(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - AccountId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct AuthenticatedAccountId with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(AuthenticatedAccountId(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "AuthenticatedAccountId", - __Visitor { - marker: _serde::__private228::PhantomData::< - AuthenticatedAccountId, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl AuthenticatedAccountId { - pub fn get(&self) -> &AccountId { - &self.0 - } - pub fn new(participants: &Participants) -> Result { - let signer = env::signer_account_id().as_v2_account_id(); - if participants.participants().iter().any(|(a_id, _, _)| *a_id == signer) - { - Ok(AuthenticatedAccountId(signer)) - } else { - Err(InvalidState::NotParticipant.into()) - } - } - } - } - pub mod participants { - use crate::errors::{Error, InvalidCandidateSet, InvalidParameters}; - use near_account_id::AccountId; - use near_sdk::{near, PublicKey}; - use std::{collections::BTreeSet, fmt::Display}; - pub mod hpke { - pub type PublicKey = [u8; 32]; - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct ParticipantInfo { - pub url: String, - /// The public key used for verifying messages. - pub sign_pk: PublicKey, - } - #[automatically_derived] - impl ::core::fmt::Debug for ParticipantInfo { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "ParticipantInfo", - "url", - &self.url, - "sign_pk", - &&self.sign_pk, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ParticipantInfo {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ParticipantInfo { - #[inline] - fn eq(&self, other: &ParticipantInfo) -> bool { - self.url == other.url && self.sign_pk == other.sign_pk - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ParticipantInfo { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for ParticipantInfo { - #[inline] - fn partial_cmp( - &self, - other: &ParticipantInfo, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp(&self.url, &other.url) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.sign_pk, - &other.sign_pk, - ) - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::Ord for ParticipantInfo { - #[inline] - fn cmp(&self, other: &ParticipantInfo) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.url, &other.url) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.sign_pk, &other.sign_pk) - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for ParticipantInfo { - #[inline] - fn clone(&self) -> ParticipantInfo { - ParticipantInfo { - url: ::core::clone::Clone::clone(&self.url), - sign_pk: ::core::clone::Clone::clone(&self.sign_pk), - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for ParticipantInfo { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.url, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.sign_pk, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for ParticipantInfo { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - url: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - sign_pk: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ParticipantInfo { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "ParticipantInfo", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "url", - &self.url, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "sign_pk", - &self.sign_pk, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ParticipantInfo { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "url" => _serde::__private228::Ok(__Field::__field0), - "sign_pk" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"url" => _serde::__private228::Ok(__Field::__field0), - b"sign_pk" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ParticipantInfo; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct ParticipantInfo", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ParticipantInfo with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct ParticipantInfo with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(ParticipantInfo { - url: __field0, - sign_pk: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("url"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "sign_pk", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("url")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("sign_pk")? - } - }; - _serde::__private228::Ok(ParticipantInfo { - url: __field0, - sign_pk: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["url", "sign_pk"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ParticipantInfo", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct ParticipantId(pub u32); - #[automatically_derived] - impl ::core::fmt::Debug for ParticipantId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ParticipantId", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ParticipantId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ParticipantId { - #[inline] - fn eq(&self, other: &ParticipantId) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ParticipantId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for ParticipantId { - #[inline] - fn partial_cmp( - &self, - other: &ParticipantId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for ParticipantId { - #[inline] - fn cmp(&self, other: &ParticipantId) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::clone::Clone for ParticipantId { - #[inline] - fn clone(&self) -> ParticipantId { - ParticipantId(::core::clone::Clone::clone(&self.0)) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for ParticipantId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for ParticipantId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ParticipantId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "ParticipantId", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ParticipantId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ParticipantId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct ParticipantId", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: u32 = ::deserialize( - __e, - )?; - _serde::__private228::Ok(ParticipantId(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct ParticipantId with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(ParticipantId(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "ParticipantId", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl ParticipantId { - pub fn get(&self) -> u32 { - self.0 - } - pub fn next(&self) -> Self { - ParticipantId(self.0 + 1) - } - } - impl Display for ParticipantId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct Participants { - next_id: ParticipantId, - participants: Vec<(AccountId, ParticipantId, ParticipantInfo)>, - } - #[automatically_derived] - impl ::core::fmt::Debug for Participants { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Participants", - "next_id", - &self.next_id, - "participants", - &&self.participants, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Participants {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Participants { - #[inline] - fn eq(&self, other: &Participants) -> bool { - self.next_id == other.next_id && self.participants == other.participants - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Participants { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq< - Vec<(AccountId, ParticipantId, ParticipantInfo)>, - >; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Participants { - #[inline] - fn partial_cmp( - &self, - other: &Participants, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.next_id, - &other.next_id, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.participants, - &other.participants, - ) - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Participants { - #[inline] - fn cmp(&self, other: &Participants) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.next_id, &other.next_id) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.participants, &other.participants) - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for Participants { - #[inline] - fn clone(&self) -> Participants { - Participants { - next_id: ::core::clone::Clone::clone(&self.next_id), - participants: ::core::clone::Clone::clone(&self.participants), - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for Participants { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.next_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.participants, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for Participants { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - next_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - participants: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Participants { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Participants", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "next_id", - &self.next_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "participants", - &self.participants, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Participants { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "next_id" => _serde::__private228::Ok(__Field::__field0), - "participants" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"next_id" => _serde::__private228::Ok(__Field::__field0), - b"participants" => { - _serde::__private228::Ok(__Field::__field1) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Participants; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct Participants", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - ParticipantId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Participants with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec<(AccountId, ParticipantId, ParticipantInfo)>, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Participants with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(Participants { - next_id: __field0, - participants: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - ParticipantId, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - Vec<(AccountId, ParticipantId, ParticipantInfo)>, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "next_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - ParticipantId, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "participants", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Vec<(AccountId, ParticipantId, ParticipantInfo)>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("next_id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("participants")? - } - }; - _serde::__private228::Ok(Participants { - next_id: __field0, - participants: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["next_id", "participants"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Participants", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl Default for Participants { - fn default() -> Self { - Self::new() - } - } - impl Participants { - pub fn new() -> Self { - Participants { - next_id: ParticipantId(0), - participants: Vec::new(), - } - } - #[allow(clippy::len_without_is_empty)] - pub fn len(&self) -> usize { - self.participants.len() - } - pub fn insert_with_id( - &mut self, - account_id: AccountId, - info: ParticipantInfo, - id: ParticipantId, - ) -> Result<(), Error> { - if self - .participants - .iter() - .any(|(a_id, p_id, _)| *a_id == account_id || *p_id == id) - { - return Err(InvalidParameters::ParticipantAlreadyInSet.into()); - } - if id < self.next_id() { - return Err(InvalidParameters::ParticipantAlreadyUsed.into()); - } - self.participants.push((account_id.clone(), id.clone(), info)); - self.next_id.0 = id.0 + 1; - Ok(()) - } - pub fn insert( - &mut self, - account_id: AccountId, - info: ParticipantInfo, - ) -> Result<(), Error> { - self.insert_with_id(account_id, info, self.next_id.clone()) - } - pub fn participants( - &self, - ) -> &Vec<(AccountId, ParticipantId, ParticipantInfo)> { - &self.participants - } - pub fn next_id(&self) -> ParticipantId { - self.next_id.clone() - } - /// Validates that the fields are coherent: - /// - All participant IDs are unique. - /// - All account IDs are unique. - /// - The next_id is greater than all participant IDs. - pub fn validate(&self) -> Result<(), Error> { - let mut ids: BTreeSet = BTreeSet::new(); - let mut accounts: BTreeSet = BTreeSet::new(); - for (acc_id, pid, _) in &self.participants { - accounts.insert(acc_id.clone()); - ids.insert(pid.clone()); - if self.next_id.get() <= pid.get() { - return Err(InvalidCandidateSet::IncoherentParticipantIds.into()); - } - } - if ids.len() != self.len() { - return Err(InvalidCandidateSet::IncoherentParticipantIds.into()); - } - if accounts.len() != self.len() { - return Err(InvalidCandidateSet::IncoherentParticipantIds.into()); - } - Ok(()) - } - pub fn is_participant(&self, account_id: &AccountId) -> bool { - self.participants.iter().any(|(a_id, _, _)| a_id == account_id) - } - pub fn init( - next_id: ParticipantId, - participants: Vec<(AccountId, ParticipantId, ParticipantInfo)>, - ) -> Self { - Self { next_id, participants } - } - pub fn info(&self, account_id: &AccountId) -> Option<&ParticipantInfo> { - self.participants - .iter() - .find(|(a_id, _, _)| a_id == account_id) - .map(|(_, _, info)| info) - } - pub fn update_info( - &mut self, - account_id: AccountId, - new_info: ParticipantInfo, - ) -> Result<(), Error> { - for (participant_account_id, _, participant_info) in self - .participants - .iter_mut() - { - if *participant_account_id == account_id { - *participant_info = new_info.clone(); - return Ok(()); - } - } - Err(crate::errors::InvalidState::NotParticipant.into()) - } - } - } - pub mod signature { - use crate::crypto_shared; - use crate::errors::{Error, InvalidParameters}; - use crate::DomainId; - use crypto_shared::derive_tweak; - use near_account_id::AccountId; - use near_sdk::{near, CryptoHash}; - use std::fmt::Debug; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct Tweak([u8; 32]); - impl ::near_sdk::borsh::ser::BorshSerialize for Tweak { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for Tweak { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Tweak { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "Tweak", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Tweak { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Tweak; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct Tweak", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: [u8; 32] = <[u8; 32] as _serde::Deserialize>::deserialize( - __e, - )?; - _serde::__private228::Ok(Tweak(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - [u8; 32], - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct Tweak with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(Tweak(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "Tweak", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for Tweak { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Tweak", &&self.0) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Tweak { - #[inline] - fn clone(&self) -> Tweak { - Tweak(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Tweak { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Tweak { - #[inline] - fn cmp(&self, other: &Tweak) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Tweak {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Tweak { - #[inline] - fn eq(&self, other: &Tweak) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Tweak { - #[inline] - fn partial_cmp( - &self, - other: &Tweak, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - impl Tweak { - pub fn as_bytes(&self) -> [u8; 32] { - self.0 - } - pub fn new(bytes: [u8; 32]) -> Self { - Self(bytes) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// A signature payload; the right payload must be passed in for the curve. - /// The json encoding for this payload converts the bytes to hex string. - pub enum Payload { - Ecdsa(Bytes<32, 32>), - Eddsa(Bytes<32, 1232>), - } - impl ::near_sdk::borsh::ser::BorshSerialize for Payload { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - let variant_idx: u8 = match self { - Payload::Ecdsa(..) => 0u8, - Payload::Eddsa(..) => 1u8, - }; - writer.write_all(&variant_idx.to_le_bytes())?; - match self { - Payload::Ecdsa(id0) => { - ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; - } - Payload::Eddsa(id0) => { - ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; - } - } - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for Payload { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - let tag = ::deserialize_reader( - reader, - )?; - ::deserialize_variant( - reader, - tag, - ) - } - } - impl ::near_sdk::borsh::de::EnumExt for Payload { - fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - variant_tag: u8, - ) -> ::core::result::Result { - let mut return_value = if variant_tag == 0u8 { - Payload::Ecdsa( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ) - } else if variant_tag == 1u8 { - Payload::Eddsa( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ) - } else { - return Err( - ::near_sdk::borsh::io::Error::new( - ::near_sdk::borsh::io::ErrorKind::InvalidData, - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Unexpected variant tag: {0:?}", variant_tag), - ); - res - }), - ), - ) - }; - Ok(return_value) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Payload { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - Payload::Ecdsa(ref __field0) => { - _serde::Serializer::serialize_newtype_variant( - __serializer, - "Payload", - 0u32, - "Ecdsa", - __field0, - ) - } - Payload::Eddsa(ref __field0) => { - _serde::Serializer::serialize_newtype_variant( - __serializer, - "Payload", - 1u32, - "Eddsa", - __field0, - ) - } - } - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Payload { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => { - _serde::__private228::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "Ecdsa" => _serde::__private228::Ok(__Field::__field0), - "Eddsa" => _serde::__private228::Ok(__Field::__field1), - _ => { - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"Ecdsa" => _serde::__private228::Ok(__Field::__field0), - b"Eddsa" => _serde::__private228::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private228::from_utf8_lossy( - __value, - ); - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Payload; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "enum Payload", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::__private228::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes<32, 32>, - >(__variant), - Payload::Ecdsa, - ) - } - (__Field::__field1, __variant) => { - _serde::__private228::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes<32, 1232>, - >(__variant), - Payload::Eddsa, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &["Ecdsa", "Eddsa"]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "Payload", - VARIANTS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for Payload { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Payload::Ecdsa(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ecdsa", - &__self_0, - ) - } - Payload::Eddsa(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Eddsa", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for Payload { - #[inline] - fn clone(&self) -> Payload { - match self { - Payload::Ecdsa(__self_0) => { - Payload::Ecdsa(::core::clone::Clone::clone(__self_0)) - } - Payload::Eddsa(__self_0) => { - Payload::Eddsa(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Payload { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Payload { - #[inline] - fn cmp(&self, other: &Payload) -> ::core::cmp::Ordering { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) { - ::core::cmp::Ordering::Equal => { - match (self, other) { - (Payload::Ecdsa(__self_0), Payload::Ecdsa(__arg1_0)) => { - ::core::cmp::Ord::cmp(__self_0, __arg1_0) - } - (Payload::Eddsa(__self_0), Payload::Eddsa(__arg1_0)) => { - ::core::cmp::Ord::cmp(__self_0, __arg1_0) - } - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Payload {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Payload { - #[inline] - fn eq(&self, other: &Payload) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - (Payload::Ecdsa(__self_0), Payload::Ecdsa(__arg1_0)) => { - __self_0 == __arg1_0 - } - (Payload::Eddsa(__self_0), Payload::Eddsa(__arg1_0)) => { - __self_0 == __arg1_0 - } - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Payload { - #[inline] - fn partial_cmp( - &self, - other: &Payload, - ) -> ::core::option::Option<::core::cmp::Ordering> { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - match (self, other) { - (Payload::Ecdsa(__self_0), Payload::Ecdsa(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - (Payload::Eddsa(__self_0), Payload::Eddsa(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - _ => { - ::core::cmp::PartialOrd::partial_cmp( - &__self_discr, - &__arg1_discr, - ) - } - } - } - } - impl Payload { - pub fn from_legacy_ecdsa(bytes: [u8; 32]) -> Self { - Payload::Ecdsa(Bytes::new(bytes.to_vec()).unwrap()) - } - pub fn as_ecdsa(&self) -> Option<&[u8; 32]> { - match self { - Payload::Ecdsa(bytes) => Some(bytes.as_fixed_bytes()), - _ => None, - } - } - pub fn as_eddsa(&self) -> Option<&[u8]> { - match self { - Payload::Eddsa(bytes) => Some(bytes.as_bytes()), - _ => None, - } - } - } - #[borsh(crate = ":: near_sdk :: borsh")] - /// A byte array with a statically encoded minimum and maximum length. - /// The `new` function as well as json deserialization checks that the length is within bounds. - /// The borsh deserialization does not perform such checks, as the borsh serialization is only - /// used for internal contract storage. - pub struct Bytes(Vec); - impl< - const MIN_LEN: usize, - const MAX_LEN: usize, - > ::near_sdk::borsh::ser::BorshSerialize for Bytes { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl< - const MIN_LEN: usize, - const MAX_LEN: usize, - > ::near_sdk::borsh::de::BorshDeserialize for Bytes { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for Bytes { - #[inline] - fn clone(&self) -> Bytes { - Bytes(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for Bytes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::cmp::Ord - for Bytes { - #[inline] - fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl< - const MIN_LEN: usize, - const MAX_LEN: usize, - > ::core::marker::StructuralPartialEq for Bytes {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for Bytes { - #[inline] - fn eq(&self, other: &Bytes) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd - for Bytes { - #[inline] - fn partial_cmp( - &self, - other: &Bytes, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - impl Bytes { - pub fn new(bytes: Vec) -> Result { - if bytes.len() < MIN_LEN || bytes.len() > MAX_LEN { - return Err(InvalidParameters::MalformedPayload.into()); - } - Ok(Self(bytes)) - } - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - } - impl Bytes { - pub fn as_fixed_bytes(&self) -> &[u8; N] { - self.0.as_slice().try_into().unwrap() - } - } - impl Debug - for Bytes { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("Bytes").field(&hex::encode(&self.0)).finish() - } - } - impl near_sdk::serde::Serialize - for Bytes { - fn serialize(&self, serializer: S) -> Result - where - S: near_sdk::serde::Serializer, - { - hex::encode(&self.0).serialize(serializer) - } - } - impl< - 'de, - const MIN_LEN: usize, - const MAX_LEN: usize, - > near_sdk::serde::Deserialize<'de> for Bytes { - fn deserialize(deserializer: D) -> Result - where - D: near_sdk::serde::Deserializer<'de>, - { - let s = String::deserialize(deserializer)?; - let bytes = hex::decode(&s).map_err(near_sdk::serde::de::Error::custom)?; - Self::new(bytes).map_err(near_sdk::serde::de::Error::custom) - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// The index into calling the YieldResume feature of NEAR. This will allow to resume - /// a yield call after the contract has been called back via this index. - pub struct YieldIndex { - pub data_id: CryptoHash, - } - impl ::near_sdk::borsh::ser::BorshSerialize for YieldIndex { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.data_id, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for YieldIndex { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - data_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for YieldIndex { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "YieldIndex", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "data_id", - &self.data_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for YieldIndex { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "data_id" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"data_id" => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = YieldIndex; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct YieldIndex", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - CryptoHash, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct YieldIndex with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(YieldIndex { data_id: __field0 }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "data_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("data_id")? - } - }; - _serde::__private228::Ok(YieldIndex { data_id: __field0 }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["data_id"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "YieldIndex", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for YieldIndex { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "YieldIndex", - "data_id", - &&self.data_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for YieldIndex { - #[inline] - fn clone(&self) -> YieldIndex { - YieldIndex { - data_id: ::core::clone::Clone::clone(&self.data_id), - } - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct SignatureRequest { - pub tweak: Tweak, - pub payload: Payload, - pub domain_id: DomainId, - } - impl ::near_sdk::borsh::ser::BorshSerialize for SignatureRequest { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.tweak, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.payload, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for SignatureRequest { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - tweak: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - payload: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SignatureRequest { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SignatureRequest", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "tweak", - &self.tweak, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "payload", - &self.payload, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SignatureRequest { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "tweak" => _serde::__private228::Ok(__Field::__field0), - "payload" => _serde::__private228::Ok(__Field::__field1), - "domain_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"tweak" => _serde::__private228::Ok(__Field::__field0), - b"payload" => _serde::__private228::Ok(__Field::__field1), - b"domain_id" => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SignatureRequest; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct SignatureRequest", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Tweak, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SignatureRequest with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Payload, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct SignatureRequest with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - DomainId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct SignatureRequest with 3 elements", - ), - ); - } - }; - _serde::__private228::Ok(SignatureRequest { - tweak: __field0, - payload: __field1, - domain_id: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("tweak"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "payload", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domain_id", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("tweak")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("payload")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domain_id")? - } - }; - _serde::__private228::Ok(SignatureRequest { - tweak: __field0, - payload: __field1, - domain_id: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "tweak", - "payload", - "domain_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SignatureRequest", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - SignatureRequest, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for SignatureRequest { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "SignatureRequest", - "tweak", - &self.tweak, - "payload", - &self.payload, - "domain_id", - &&self.domain_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for SignatureRequest { - #[inline] - fn clone(&self) -> SignatureRequest { - SignatureRequest { - tweak: ::core::clone::Clone::clone(&self.tweak), - payload: ::core::clone::Clone::clone(&self.payload), - domain_id: ::core::clone::Clone::clone(&self.domain_id), - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for SignatureRequest { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::Ord for SignatureRequest { - #[inline] - fn cmp(&self, other: &SignatureRequest) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.tweak, &other.tweak) { - ::core::cmp::Ordering::Equal => { - match ::core::cmp::Ord::cmp(&self.payload, &other.payload) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.domain_id, &other.domain_id) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for SignatureRequest {} - #[automatically_derived] - impl ::core::cmp::PartialEq for SignatureRequest { - #[inline] - fn eq(&self, other: &SignatureRequest) -> bool { - self.tweak == other.tweak && self.payload == other.payload - && self.domain_id == other.domain_id - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for SignatureRequest { - #[inline] - fn partial_cmp( - &self, - other: &SignatureRequest, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp(&self.tweak, &other.tweak) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - match ::core::cmp::PartialOrd::partial_cmp( - &self.payload, - &other.payload, - ) { - ::core::option::Option::Some( - ::core::cmp::Ordering::Equal, - ) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.domain_id, - &other.domain_id, - ) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - impl SignatureRequest { - pub fn new( - domain: DomainId, - payload: Payload, - predecessor_id: &AccountId, - path: &str, - ) -> Self { - let tweak = derive_tweak(predecessor_id, path); - SignatureRequest { - domain_id: domain, - tweak, - payload, - } - } - } - #[serde(crate = ":: near_sdk :: serde")] - pub struct SignRequestArgs { - pub path: String, - pub payload_v2: Option, - #[serde(rename = "payload")] - pub deprecated_payload: Option<[u8; 32]>, - pub domain_id: Option, - #[serde(rename = "key_version")] - pub deprecated_key_version: Option, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for SignRequestArgs { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SignRequestArgs", - false as usize + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "path", - &self.path, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "payload_v2", - &self.payload_v2, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "payload", - &self.deprecated_payload, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key_version", - &self.deprecated_key_version, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SignRequestArgs { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - 4u64 => _serde::__private228::Ok(__Field::__field4), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "path" => _serde::__private228::Ok(__Field::__field0), - "payload_v2" => _serde::__private228::Ok(__Field::__field1), - "payload" => _serde::__private228::Ok(__Field::__field2), - "domain_id" => _serde::__private228::Ok(__Field::__field3), - "key_version" => _serde::__private228::Ok(__Field::__field4), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"path" => _serde::__private228::Ok(__Field::__field0), - b"payload_v2" => _serde::__private228::Ok(__Field::__field1), - b"payload" => _serde::__private228::Ok(__Field::__field2), - b"domain_id" => _serde::__private228::Ok(__Field::__field3), - b"key_version" => { - _serde::__private228::Ok(__Field::__field4) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SignRequestArgs; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct SignRequestArgs", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SignRequestArgs with 5 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct SignRequestArgs with 5 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - Option<[u8; 32]>, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct SignRequestArgs with 5 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct SignRequestArgs with 5 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct SignRequestArgs with 5 elements", - ), - ); - } - }; - _serde::__private228::Ok(SignRequestArgs { - path: __field0, - payload_v2: __field1, - deprecated_payload: __field2, - domain_id: __field3, - deprecated_key_version: __field4, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option< - Option<[u8; 32]>, - > = _serde::__private228::None; - let mut __field3: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - let mut __field4: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("path"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "payload_v2", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "payload", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option<[u8; 32]>, - >(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private228::Option::is_some(&__field3) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domain_id", - ), - ); - } - __field3 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private228::Option::is_some(&__field4) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "key_version", - ), - ); - } - __field4 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("path")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("payload_v2")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("payload")? - } - }; - let __field3 = match __field3 { - _serde::__private228::Some(__field3) => __field3, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domain_id")? - } - }; - let __field4 = match __field4 { - _serde::__private228::Some(__field4) => __field4, - _serde::__private228::None => { - _serde::__private228::de::missing_field("key_version")? - } - }; - _serde::__private228::Ok(SignRequestArgs { - path: __field0, - payload_v2: __field1, - deprecated_payload: __field2, - domain_id: __field3, - deprecated_key_version: __field4, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "path", - "payload_v2", - "payload", - "domain_id", - "key_version", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SignRequestArgs", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for SignRequestArgs { - #[inline] - fn clone(&self) -> SignRequestArgs { - SignRequestArgs { - path: ::core::clone::Clone::clone(&self.path), - payload_v2: ::core::clone::Clone::clone(&self.payload_v2), - deprecated_payload: ::core::clone::Clone::clone( - &self.deprecated_payload, - ), - domain_id: ::core::clone::Clone::clone(&self.domain_id), - deprecated_key_version: ::core::clone::Clone::clone( - &self.deprecated_key_version, - ), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for SignRequestArgs { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "SignRequestArgs", - "path", - &self.path, - "payload_v2", - &self.payload_v2, - "deprecated_payload", - &self.deprecated_payload, - "domain_id", - &self.domain_id, - "deprecated_key_version", - &&self.deprecated_key_version, - ) - } - } - #[automatically_derived] - impl ::core::default::Default for SignRequestArgs { - #[inline] - fn default() -> SignRequestArgs { - SignRequestArgs { - path: ::core::default::Default::default(), - payload_v2: ::core::default::Default::default(), - deprecated_payload: ::core::default::Default::default(), - domain_id: ::core::default::Default::default(), - deprecated_key_version: ::core::default::Default::default(), - } - } - } - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct SignRequest { - pub payload: Payload, - pub path: String, - pub domain_id: DomainId, - } - impl ::near_sdk::borsh::ser::BorshSerialize for SignRequest { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.payload, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.path, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.domain_id, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for SignRequest { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - payload: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - path: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - domain_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for SignRequest { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "SignRequest", - "payload", - &self.payload, - "path", - &self.path, - "domain_id", - &&self.domain_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for SignRequest { - #[inline] - fn clone(&self) -> SignRequest { - SignRequest { - payload: ::core::clone::Clone::clone(&self.payload), - path: ::core::clone::Clone::clone(&self.path), - domain_id: ::core::clone::Clone::clone(&self.domain_id), - } - } - } - impl TryFrom for SignRequest { - type Error = Error; - fn try_from(args: SignRequestArgs) -> Result { - let payload = match (args.payload_v2, args.deprecated_payload) { - (Some(payload), None) => payload, - (None, Some(payload)) => Payload::from_legacy_ecdsa(payload), - _ => return Err(InvalidParameters::MalformedPayload.into()), - }; - let domain_id = match (args.domain_id, args.deprecated_key_version) { - (Some(domain_id), None) => domain_id, - (None, Some(key_version)) => DomainId(key_version.into()), - _ => return Err(InvalidParameters::InvalidDomainId.into()), - }; - Ok(SignRequest { - payload, - path: args.path, - domain_id, - }) - } - } - #[borsh(crate = ":: near_sdk :: borsh")] - pub enum SignatureResult { - Ok(T), - Err(E), - } - impl ::near_sdk::borsh::ser::BorshSerialize for SignatureResult - where - T: ::near_sdk::borsh::ser::BorshSerialize, - E: ::near_sdk::borsh::ser::BorshSerialize, - { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - let variant_idx: u8 = match self { - SignatureResult::Ok(..) => 0u8, - SignatureResult::Err(..) => 1u8, - }; - writer.write_all(&variant_idx.to_le_bytes())?; - match self { - SignatureResult::Ok(id0) => { - ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; - } - SignatureResult::Err(id0) => { - ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; - } - } - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for SignatureResult - where - T: ::near_sdk::borsh::de::BorshDeserialize, - E: ::near_sdk::borsh::de::BorshDeserialize, - { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - let tag = ::deserialize_reader( - reader, - )?; - ::deserialize_variant( - reader, - tag, - ) - } - } - impl ::near_sdk::borsh::de::EnumExt for SignatureResult - where - T: ::near_sdk::borsh::de::BorshDeserialize, - E: ::near_sdk::borsh::de::BorshDeserialize, - { - fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - variant_tag: u8, - ) -> ::core::result::Result { - let mut return_value = if variant_tag == 0u8 { - SignatureResult::Ok( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ) - } else if variant_tag == 1u8 { - SignatureResult::Err( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ) - } else { - return Err( - ::near_sdk::borsh::io::Error::new( - ::near_sdk::borsh::io::ErrorKind::InvalidData, - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Unexpected variant tag: {0:?}", variant_tag), - ); - res - }), - ), - ) - }; - Ok(return_value) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for SignatureResult { - #[inline] - fn clone(&self) -> SignatureResult { - match self { - SignatureResult::Ok(__self_0) => { - SignatureResult::Ok(::core::clone::Clone::clone(__self_0)) - } - SignatureResult::Err(__self_0) => { - SignatureResult::Err(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug - for SignatureResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - SignatureResult::Ok(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ok", - &__self_0, - ) - } - SignatureResult::Err(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Err", - &__self_0, - ) - } - } - } - } - } - pub mod thresholds { - use super::participants::{ParticipantId, ParticipantInfo, Participants}; - use crate::errors::{Error, InvalidCandidateSet, InvalidThreshold}; - use near_account_id::AccountId; - use near_sdk::near; - use std::collections::BTreeMap; - /// Minimum absolute threshold required. - const MIN_THRESHOLD_ABSOLUTE: u64 = 2; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Stores the cryptographic threshold for a distributed key. - /// ``` - /// use mpc_contract::primitives::thresholds::Threshold; - /// let dt = Threshold::new(8); - /// assert!(dt.value() == 8); - /// ``` - pub struct Threshold(u64); - #[automatically_derived] - impl ::core::fmt::Debug for Threshold { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Threshold", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Threshold {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Threshold { - #[inline] - fn eq(&self, other: &Threshold) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Threshold { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Threshold { - #[inline] - fn partial_cmp( - &self, - other: &Threshold, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Threshold { - #[inline] - fn cmp(&self, other: &Threshold) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Threshold { - #[inline] - fn clone(&self) -> Threshold { - Threshold(::core::clone::Clone::clone(&self.0)) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for Threshold { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for Threshold { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok( - Self( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ), - ) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Threshold { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "Threshold", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Threshold { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Threshold; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct Threshold", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: u64 = ::deserialize( - __e, - )?; - _serde::__private228::Ok(Threshold(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct Threshold with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(Threshold(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "Threshold", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl Threshold { - pub fn new(val: u64) -> Self { - Threshold(val) - } - pub fn value(&self) -> u64 { - self.0 - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Stores information about the threshold key parameters: - /// - owners of key shares - /// - cryptographic threshold - pub struct ThresholdParameters { - participants: Participants, - threshold: Threshold, - } - #[automatically_derived] - impl ::core::fmt::Debug for ThresholdParameters { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "ThresholdParameters", - "participants", - &self.participants, - "threshold", - &&self.threshold, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ThresholdParameters {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ThresholdParameters { - #[inline] - fn eq(&self, other: &ThresholdParameters) -> bool { - self.participants == other.participants - && self.threshold == other.threshold - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ThresholdParameters { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for ThresholdParameters { - #[inline] - fn partial_cmp( - &self, - other: &ThresholdParameters, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.participants, - &other.participants, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.threshold, - &other.threshold, - ) - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::Ord for ThresholdParameters { - #[inline] - fn cmp(&self, other: &ThresholdParameters) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.participants, &other.participants) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.threshold, &other.threshold) - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for ThresholdParameters { - #[inline] - fn clone(&self) -> ThresholdParameters { - ThresholdParameters { - participants: ::core::clone::Clone::clone(&self.participants), - threshold: ::core::clone::Clone::clone(&self.threshold), - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for ThresholdParameters { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.participants, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.threshold, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for ThresholdParameters { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - participants: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - threshold: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ThresholdParameters { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "ThresholdParameters", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "participants", - &self.participants, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "threshold", - &self.threshold, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ThresholdParameters { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "participants" => { - _serde::__private228::Ok(__Field::__field0) - } - "threshold" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"participants" => { - _serde::__private228::Ok(__Field::__field0) - } - b"threshold" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ThresholdParameters; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct ThresholdParameters", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Participants, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ThresholdParameters with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Threshold, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct ThresholdParameters with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(ThresholdParameters { - participants: __field0, - threshold: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - Participants, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "participants", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Participants, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "threshold", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("participants")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("threshold")? - } - }; - _serde::__private228::Ok(ThresholdParameters { - participants: __field0, - threshold: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "participants", - "threshold", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ThresholdParameters", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - ThresholdParameters, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl ThresholdParameters { - /// Constructs Threshold parameters from `participants` and `threshold` if the - /// threshold meets the absolute and relative validation criteria. - pub fn new( - participants: Participants, - threshold: Threshold, - ) -> Result { - match Self::validate_threshold( - participants.len() as u64, - threshold.clone(), - ) { - Ok(_) => { - Ok(ThresholdParameters { - participants, - threshold, - }) - } - Err(err) => Err(err), - } - } - /// Ensures that the threshold `k` is sensible and meets the absolute and minimum requirements. - /// That is: - /// - threshold must be at least `MIN_THRESHOLD_ABSOLUTE` - /// - threshold can not exceed the number of shares `n_shares`. - /// - threshold must be at least 60% of the number of shares (rounded upwards). - pub fn validate_threshold(n_shares: u64, k: Threshold) -> Result<(), Error> { - if k.value() > n_shares { - return Err( - InvalidThreshold::MaxRequirementFailed - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("cannot exceed {0}, found {1:?}", n_shares, k), - ); - res - }), - ), - ); - } - if k.value() < MIN_THRESHOLD_ABSOLUTE { - return Err(InvalidThreshold::MinAbsRequirementFailed.into()); - } - let percentage_bound = (3 * n_shares).div_ceil(5); - if k.value() < percentage_bound { - return Err( - InvalidThreshold::MinRelRequirementFailed - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "require at least {0}, found {1:?}", - percentage_bound, - k, - ), - ); - res - }), - ), - ); - } - Ok(()) - } - pub fn validate(&self) -> Result<(), Error> { - Self::validate_threshold( - self.participants.len() as u64, - self.threshold(), - )?; - self.participants.validate() - } - /// Validates the incoming proposal against the current one, ensuring it's allowed based on the - /// current participants and threshold settings. Also verifies the TEE quote of the participant - /// who submitted the proposal. - pub fn validate_incoming_proposal( - &self, - proposal: &ThresholdParameters, - ) -> Result<(), Error> { - proposal.validate()?; - let mut old_by_id: BTreeMap = BTreeMap::new(); - let mut old_by_acc: BTreeMap< - AccountId, - (ParticipantId, ParticipantInfo), - > = BTreeMap::new(); - for (acc, id, info) in self.participants().participants() { - old_by_id.insert(id.clone(), acc.clone()); - old_by_acc.insert(acc.clone(), (id.clone(), info.clone())); - } - let new_participants = proposal.participants().participants(); - let mut new_min_id = u32::MAX; - let mut new_max_id = 0u32; - let mut n_old = 0u64; - for (new_account, new_id, new_info) in new_participants { - match old_by_acc.get(new_account) { - Some((old_id, old_info)) => { - if new_id != old_id { - return Err( - InvalidCandidateSet::IncoherentParticipantIds.into(), - ); - } - if *new_info != *old_info { - return Err( - InvalidCandidateSet::IncoherentParticipantIds.into(), - ); - } - n_old += 1; - } - None => { - if old_by_id.contains_key(new_id) { - return Err( - InvalidCandidateSet::IncoherentParticipantIds.into(), - ); - } - new_min_id = std::cmp::min(new_min_id, new_id.get()); - new_max_id = std::cmp::max(new_max_id, new_id.get()); - } - } - } - if n_old < self.threshold().value() { - return Err(InvalidCandidateSet::InsufficientOldParticipants.into()); - } - let n_new = proposal.participants().len() as u64 - n_old; - if n_new > 0 { - if n_new - 1 != (new_max_id - new_min_id) as u64 { - return Err( - InvalidCandidateSet::NewParticipantIdsNotContiguous.into(), - ); - } - if new_min_id != self.participants().next_id().get() { - return Err( - InvalidCandidateSet::NewParticipantIdsNotContiguous.into(), - ); - } - if new_max_id + 1 != proposal.participants().next_id().get() { - return Err(InvalidCandidateSet::NewParticipantIdsTooHigh.into()); - } - } - Ok(()) - } - pub fn threshold(&self) -> Threshold { - self.threshold.clone() - } - /// Returns the map of Participants. - pub fn participants(&self) -> &Participants { - &self.participants - } - /// For integration testing. - pub fn new_unvalidated( - participants: Participants, - threshold: Threshold, - ) -> Self { - ThresholdParameters { - participants, - threshold, - } - } - pub fn update_info( - &mut self, - account_id: AccountId, - new_info: ParticipantInfo, - ) -> Result<(), Error> { - self.participants.update_info(account_id, new_info) - } - } - } - pub mod votes { - use super::thresholds::ThresholdParameters; - use super::{key_state::AuthenticatedAccountId, participants::Participants}; - use near_sdk::{log, near}; - use std::collections::BTreeMap; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Tracks votes for ThresholdParameters (new participants and threshold). - /// Each current participant can maintain one vote. - pub struct ThresholdParametersVotes { - proposal_by_account: BTreeMap, - } - #[automatically_derived] - impl ::core::clone::Clone for ThresholdParametersVotes { - #[inline] - fn clone(&self) -> ThresholdParametersVotes { - ThresholdParametersVotes { - proposal_by_account: ::core::clone::Clone::clone( - &self.proposal_by_account, - ), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ThresholdParametersVotes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "ThresholdParametersVotes", - "proposal_by_account", - &&self.proposal_by_account, - ) - } - } - #[automatically_derived] - impl ::core::default::Default for ThresholdParametersVotes { - #[inline] - fn default() -> ThresholdParametersVotes { - ThresholdParametersVotes { - proposal_by_account: ::core::default::Default::default(), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ThresholdParametersVotes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ThresholdParametersVotes { - #[inline] - fn eq(&self, other: &ThresholdParametersVotes) -> bool { - self.proposal_by_account == other.proposal_by_account - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ThresholdParametersVotes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq< - BTreeMap, - >; - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for ThresholdParametersVotes { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.proposal_by_account, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for ThresholdParametersVotes { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - proposal_by_account: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ThresholdParametersVotes { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "ThresholdParametersVotes", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "proposal_by_account", - &self.proposal_by_account, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ThresholdParametersVotes { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "proposal_by_account" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"proposal_by_account" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - ThresholdParametersVotes, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ThresholdParametersVotes; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct ThresholdParametersVotes", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - BTreeMap, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ThresholdParametersVotes with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(ThresholdParametersVotes { - proposal_by_account: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - BTreeMap, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "proposal_by_account", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - BTreeMap, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "proposal_by_account", - )? - } - }; - _serde::__private228::Ok(ThresholdParametersVotes { - proposal_by_account: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["proposal_by_account"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ThresholdParametersVotes", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - ThresholdParametersVotes, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl ThresholdParametersVotes { - /// return the number of votes for `proposal` casted by members of `participants` - pub fn n_votes( - &self, - proposal: &ThresholdParameters, - participants: &Participants, - ) -> u64 { - self - .proposal_by_account - .iter() - .filter(|&(acc, prop)| { - participants - .participants() - .iter() - .any(|(acc_id, _, _)| acc.get() == acc_id) - && prop == proposal - }) - .count() as u64 - } - /// Registers a vote by `participant` for `proposal`. - /// Removes any existing votes by `participant`. - /// Returns the number of participants who have voted for the same proposal (including the new - /// vote). - pub fn vote( - &mut self, - proposal: &ThresholdParameters, - participant: AuthenticatedAccountId, - ) -> u64 { - if self - .proposal_by_account - .insert(participant, proposal.clone()) - .is_some() - { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("removed one vote for signer"), - ); - res - }) - .as_str(), - ); - } - self - .proposal_by_account - .values() - .filter(|&prop| prop == proposal) - .count() as u64 - } - } - } - pub(crate) mod time { - use std::time::Duration; - pub(crate) struct Timestamp { - duration_since_unix_epoch: Duration, - } - #[automatically_derived] - impl ::core::fmt::Debug for Timestamp { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Timestamp", - "duration_since_unix_epoch", - &&self.duration_since_unix_epoch, - ) - } - } - #[automatically_derived] - impl ::core::marker::Copy for Timestamp {} - #[automatically_derived] - impl ::core::clone::Clone for Timestamp { - #[inline] - fn clone(&self) -> Timestamp { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Timestamp {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Timestamp { - #[inline] - fn eq(&self, other: &Timestamp) -> bool { - self.duration_since_unix_epoch == other.duration_since_unix_epoch - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Timestamp { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Timestamp { - #[inline] - fn partial_cmp( - &self, - other: &Timestamp, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp( - &self.duration_since_unix_epoch, - &other.duration_since_unix_epoch, - ) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Timestamp { - #[inline] - fn cmp(&self, other: &Timestamp) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp( - &self.duration_since_unix_epoch, - &other.duration_since_unix_epoch, - ) - } - } - impl Timestamp { - pub(crate) fn now() -> Self { - let block_time_nano_seconds = near_sdk::env::block_timestamp(); - Self { - duration_since_unix_epoch: Duration::from_nanos( - block_time_nano_seconds, - ), - } - } - pub(crate) fn checked_add(self, duration: Duration) -> Option { - let current_time_stamp = self.duration_since_unix_epoch; - let new_time_stamp = current_time_stamp.checked_add(duration)?; - Some(Timestamp { - duration_since_unix_epoch: new_time_stamp, - }) - } - } - impl borsh::BorshSerialize for Timestamp { - fn serialize( - &self, - writer: &mut W, - ) -> std::io::Result<()> { - let duration_milliseconds: u64 = self - .duration_since_unix_epoch - .as_secs(); - let duration_milliseconds_bytes: [u8; 8] = duration_milliseconds - .to_be_bytes(); - writer.write_all(&duration_milliseconds_bytes) - } - } - impl borsh::BorshDeserialize for Timestamp { - fn deserialize_reader( - reader: &mut R, - ) -> std::io::Result { - let mut duration_milliseconds_bytes: [u8; 8] = [0; 8]; - reader.read_exact(&mut duration_milliseconds_bytes)?; - let duration_milliseconds = u64::from_be_bytes( - duration_milliseconds_bytes, - ); - let duration_since_unix_epoch = Duration::from_secs( - duration_milliseconds, - ); - Ok(Self { duration_since_unix_epoch }) - } - } - } -} -pub mod state { - pub mod initializing { - use super::key_event::KeyEvent; - use super::running::RunningContractState; - use crate::crypto_shared::types::PublicKeyExtended; - use crate::errors::{Error, InvalidParameters}; - use crate::primitives::domain::DomainRegistry; - use crate::primitives::key_state::{ - AuthenticatedParticipantId, EpochId, KeyEventId, KeyForDomain, Keyset, - }; - use near_account_id::AccountId; - use near_sdk::near; - use std::collections::BTreeSet; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// In this state, we generate a new key for each new domain. At any given point of time, we are - /// generating the key of a single domain. After that, we move on to the next domain, or if there - /// are no more domains, transition into the Running state. - /// - /// This state is reached by calling vote_add_domains from the Running state by a threshold number - /// of participants. - /// - /// While generating the key for a domain, the `generating_key` field internally handles multiple - /// attempts as needed, only finishing when an attempt has succeeded. - /// - /// Additionally, a threshold number of participants can vote to cancel this state; doing so will - /// revert back to the Running state but deleting the domains for which we have not yet successfully - /// generated a key. This can be useful if the current set of participants are no longer all online - /// and we wish to perform a resharing before adding domains again. - pub struct InitializingContractState { - /// All domains, including the already existing ones and the ones we're generating a new key for - pub domains: DomainRegistry, - /// The epoch ID; this is the same as the Epoch ID of the Running state we transitioned from. - pub epoch_id: EpochId, - /// The key for each domain we have already generated a key for; this is in the same order as - /// the domains in the DomainRegistry, except that it only has a prefix of the domains. - pub generated_keys: Vec, - /// The key generation state for the currently generating domain (the next domain after - /// `generated_keys`). - pub generating_key: KeyEvent, - /// Votes that have been cast to cancel the key generation. - pub cancel_votes: BTreeSet, - } - #[automatically_derived] - impl ::core::fmt::Debug for InitializingContractState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "InitializingContractState", - "domains", - &self.domains, - "epoch_id", - &self.epoch_id, - "generated_keys", - &self.generated_keys, - "generating_key", - &self.generating_key, - "cancel_votes", - &&self.cancel_votes, - ) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for InitializingContractState { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.generated_keys, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.generating_key, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.cancel_votes, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for InitializingContractState { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - generated_keys: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - generating_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - cancel_votes: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for InitializingContractState { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "InitializingContractState", - false as usize + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domains", - &self.domains, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "epoch_id", - &self.epoch_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "generated_keys", - &self.generated_keys, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "generating_key", - &self.generating_key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "cancel_votes", - &self.cancel_votes, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for InitializingContractState { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - 4u64 => _serde::__private228::Ok(__Field::__field4), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "domains" => _serde::__private228::Ok(__Field::__field0), - "epoch_id" => _serde::__private228::Ok(__Field::__field1), - "generated_keys" => { - _serde::__private228::Ok(__Field::__field2) - } - "generating_key" => { - _serde::__private228::Ok(__Field::__field3) - } - "cancel_votes" => { - _serde::__private228::Ok(__Field::__field4) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"domains" => _serde::__private228::Ok(__Field::__field0), - b"epoch_id" => _serde::__private228::Ok(__Field::__field1), - b"generated_keys" => { - _serde::__private228::Ok(__Field::__field2) - } - b"generating_key" => { - _serde::__private228::Ok(__Field::__field3) - } - b"cancel_votes" => { - _serde::__private228::Ok(__Field::__field4) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - InitializingContractState, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = InitializingContractState; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct InitializingContractState", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - DomainRegistry, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct InitializingContractState with 5 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - EpochId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct InitializingContractState with 5 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct InitializingContractState with 5 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - KeyEvent, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct InitializingContractState with 5 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - BTreeSet, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct InitializingContractState with 5 elements", - ), - ); - } - }; - _serde::__private228::Ok(InitializingContractState { - domains: __field0, - epoch_id: __field1, - generated_keys: __field2, - generating_key: __field3, - cancel_votes: __field4, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - DomainRegistry, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - let mut __field2: _serde::__private228::Option< - Vec, - > = _serde::__private228::None; - let mut __field3: _serde::__private228::Option = _serde::__private228::None; - let mut __field4: _serde::__private228::Option< - BTreeSet, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domains", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - DomainRegistry, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "epoch_id", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "generated_keys", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Vec, - >(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private228::Option::is_some(&__field3) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "generating_key", - ), - ); - } - __field3 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private228::Option::is_some(&__field4) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "cancel_votes", - ), - ); - } - __field4 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - BTreeSet, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domains")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("epoch_id")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("generated_keys")? - } - }; - let __field3 = match __field3 { - _serde::__private228::Some(__field3) => __field3, - _serde::__private228::None => { - _serde::__private228::de::missing_field("generating_key")? - } - }; - let __field4 = match __field4 { - _serde::__private228::Some(__field4) => __field4, - _serde::__private228::None => { - _serde::__private228::de::missing_field("cancel_votes")? - } - }; - _serde::__private228::Ok(InitializingContractState { - domains: __field0, - epoch_id: __field1, - generated_keys: __field2, - generating_key: __field3, - cancel_votes: __field4, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "domains", - "epoch_id", - "generated_keys", - "generating_key", - "cancel_votes", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "InitializingContractState", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - InitializingContractState, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl InitializingContractState { - /// Starts a new attempt to generate a key for the current domain. - /// Returns an Error if the signer is not the leader (the participant with the lowest ID). - pub fn start( - &mut self, - key_event_id: KeyEventId, - key_event_timeout_blocks: u64, - ) -> Result<(), Error> { - self.generating_key.start(key_event_id, key_event_timeout_blocks) - } - /// Casts a vote for `public_key` for the attempt identified by `key_event_id`. - /// Upon success (a return of Ok(...)), the effect of this method is one of the following: - /// - A vote has been collected but we don't have enough votes yet. - /// - This vote is for a public key that disagrees from an earlier voted public key, causing - /// the attempt to abort; another call to `start` is then necessary. - /// - Everyone has now voted for the same public key; the state transitions into generating a - /// key for the next domain. (This returns Ok(None) still). - /// - Same as the last case, except that all domains have a generated key now, and we return - /// Ok(Some(running state)) that the caller should now transition into. - /// - /// Fails in the following cases: - /// - There is no active key generation attempt (including if the attempt timed out). - /// - The key_event_id corresponds to a different domain, different epoch, or different attempt - /// from the current key generation attempt. - /// - The signer is not a participant. - pub fn vote_pk( - &mut self, - key_event_id: KeyEventId, - public_key: PublicKeyExtended, - ) -> Result, Error> { - if self.generating_key.vote_success(&key_event_id, public_key.clone())? { - self.generated_keys - .push(KeyForDomain { - domain_id: key_event_id.domain_id, - key: public_key.clone(), - attempt: key_event_id.attempt_id, - }); - if let Some(next_domain) = self - .domains - .get_domain_by_index(self.generated_keys.len()) - { - self.generating_key = KeyEvent::new( - self.epoch_id, - next_domain.clone(), - self.generating_key.proposed_parameters().clone(), - ); - } else { - return Ok( - Some( - RunningContractState::new( - self.domains.clone(), - Keyset::new(self.epoch_id, self.generated_keys.clone()), - self.generating_key.proposed_parameters().clone(), - ), - ), - ); - } - } - Ok(None) - } - /// Casts a vote to abort the current key generation attempt. - /// After aborting, another call to start() is necessary to start a new attempt. - /// Returns error if there is no active attempt, or if the signer is not a participant. - pub fn vote_abort(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { - self.generating_key.vote_abort(key_event_id) - } - /// Casts a vote to cancel key generation. Any keys that have already been generated - /// are kept and we transition into Running state; remaining domains are permanently deleted. - /// Deleted domain IDs are not reused again. - /// - /// The next_domain_id parameter is used to verify that this cancel vote is indeed for this - /// particular instance of key generation, not some older instance. - pub fn vote_cancel( - &mut self, - next_domain_id: u64, - ) -> Result, Error> { - if next_domain_id != self.domains.next_domain_id() { - return Err(InvalidParameters::NextDomainIdMismatch.into()); - } - let participant = AuthenticatedParticipantId::new( - self.generating_key.proposed_parameters().participants(), - )?; - let required_threshold = self - .generating_key - .proposed_parameters() - .threshold() - .value() as usize; - if self.cancel_votes.insert(participant) - && self.cancel_votes.len() >= required_threshold - { - let mut domains = self.domains.clone(); - domains.retain_domains(self.generated_keys.len()); - return Ok( - Some( - RunningContractState::new( - domains, - Keyset::new(self.epoch_id, self.generated_keys.clone()), - self.generating_key.proposed_parameters().clone(), - ), - ), - ); - } - Ok(None) - } - pub fn is_participant(&self, account_id: &AccountId) -> bool { - self.generating_key - .proposed_parameters() - .participants() - .is_participant(account_id) - } - } - } - pub mod key_event { - use crate::crypto_shared::types::PublicKeyExtended; - use crate::errors::Error; - use crate::errors::KeyEventError; - use crate::errors::VoteError; - use crate::primitives::domain::DomainConfig; - use crate::primitives::key_state::KeyEventId; - use crate::primitives::key_state::{AttemptId, EpochId}; - use crate::primitives::thresholds::ThresholdParameters; - use crate::state::AuthenticatedParticipantId; - use near_sdk::BlockHeight; - use near_sdk::{env, log, near}; - use std::collections::BTreeSet; - use utilities::AccountIdExtV1; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Maintains the state for the current key generation or resharing. - pub struct KeyEvent { - /// The epoch ID that we're generating or resharing keys for. - epoch_id: EpochId, - /// The domain that we're generating or resharing the key for. - domain: DomainConfig, - /// The participants and threshold that shall participate in the key event. - parameters: ThresholdParameters, - /// If exists, the current attempt to generate or reshare the key. - instance: Option, - /// The ID of the next attempt to generate or reshare the key. - next_attempt_id: AttemptId, - } - #[automatically_derived] - impl ::core::fmt::Debug for KeyEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "KeyEvent", - "epoch_id", - &self.epoch_id, - "domain", - &self.domain, - "parameters", - &self.parameters, - "instance", - &self.instance, - "next_attempt_id", - &&self.next_attempt_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for KeyEvent { - #[inline] - fn clone(&self) -> KeyEvent { - KeyEvent { - epoch_id: ::core::clone::Clone::clone(&self.epoch_id), - domain: ::core::clone::Clone::clone(&self.domain), - parameters: ::core::clone::Clone::clone(&self.parameters), - instance: ::core::clone::Clone::clone(&self.instance), - next_attempt_id: ::core::clone::Clone::clone(&self.next_attempt_id), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for KeyEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq for KeyEvent { - #[inline] - fn eq(&self, other: &KeyEvent) -> bool { - self.epoch_id == other.epoch_id && self.domain == other.domain - && self.parameters == other.parameters - && self.instance == other.instance - && self.next_attempt_id == other.next_attempt_id - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for KeyEvent { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.epoch_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.domain, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.parameters, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.instance, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.next_attempt_id, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for KeyEvent { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - domain: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - parameters: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - instance: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - next_attempt_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for KeyEvent { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "KeyEvent", - false as usize + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "epoch_id", - &self.epoch_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain", - &self.domain, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "parameters", - &self.parameters, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "instance", - &self.instance, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "next_attempt_id", - &self.next_attempt_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for KeyEvent { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - 4u64 => _serde::__private228::Ok(__Field::__field4), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "epoch_id" => _serde::__private228::Ok(__Field::__field0), - "domain" => _serde::__private228::Ok(__Field::__field1), - "parameters" => _serde::__private228::Ok(__Field::__field2), - "instance" => _serde::__private228::Ok(__Field::__field3), - "next_attempt_id" => { - _serde::__private228::Ok(__Field::__field4) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"epoch_id" => _serde::__private228::Ok(__Field::__field0), - b"domain" => _serde::__private228::Ok(__Field::__field1), - b"parameters" => _serde::__private228::Ok(__Field::__field2), - b"instance" => _serde::__private228::Ok(__Field::__field3), - b"next_attempt_id" => { - _serde::__private228::Ok(__Field::__field4) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = KeyEvent; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct KeyEvent", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - EpochId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct KeyEvent with 5 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - DomainConfig, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct KeyEvent with 5 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - ThresholdParameters, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct KeyEvent with 5 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct KeyEvent with 5 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - AttemptId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct KeyEvent with 5 elements", - ), - ); - } - }; - _serde::__private228::Ok(KeyEvent { - epoch_id: __field0, - domain: __field1, - parameters: __field2, - instance: __field3, - next_attempt_id: __field4, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - DomainConfig, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option< - ThresholdParameters, - > = _serde::__private228::None; - let mut __field3: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - let mut __field4: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "epoch_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("domain"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - DomainConfig, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "parameters", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - ThresholdParameters, - >(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private228::Option::is_some(&__field3) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "instance", - ), - ); - } - __field3 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private228::Option::is_some(&__field4) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "next_attempt_id", - ), - ); - } - __field4 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("epoch_id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domain")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("parameters")? - } - }; - let __field3 = match __field3 { - _serde::__private228::Some(__field3) => __field3, - _serde::__private228::None => { - _serde::__private228::de::missing_field("instance")? - } - }; - let __field4 = match __field4 { - _serde::__private228::Some(__field4) => __field4, - _serde::__private228::None => { - _serde::__private228::de::missing_field("next_attempt_id")? - } - }; - _serde::__private228::Ok(KeyEvent { - epoch_id: __field0, - domain: __field1, - parameters: __field2, - instance: __field3, - next_attempt_id: __field4, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "epoch_id", - "domain", - "parameters", - "instance", - "next_attempt_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "KeyEvent", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl KeyEvent { - pub fn new( - epoch_id: EpochId, - domain: DomainConfig, - proposed_parameters: ThresholdParameters, - ) -> Self { - KeyEvent { - epoch_id, - domain, - parameters: proposed_parameters, - instance: None, - next_attempt_id: AttemptId::new(), - } - } - /// Start a new key event instance as the leader, if one isn't already active. - /// The leader is always the participant with the lowest participant ID. - pub fn start( - &mut self, - key_event_id: KeyEventId, - timeout_blocks: u64, - ) -> Result<(), Error> { - self.cleanup_if_timed_out(); - if self.instance.is_some() { - return Err(KeyEventError::ActiveKeyEvent.into()); - } - let expected_key_event_id = KeyEventId::new( - self.epoch_id, - self.domain.id, - self.next_attempt_id, - ); - if key_event_id != expected_key_event_id { - return Err(KeyEventError::KeyEventIdMismatch.into()); - } - self.verify_leader()?; - self.instance = Some( - KeyEventInstance::new(self.next_attempt_id, timeout_blocks), - ); - self.next_attempt_id = self.next_attempt_id.next(); - Ok(()) - } - /// Ensures that the signer account matches the leader participant. - /// The leader is the one with the lowest participant ID. - pub fn verify_leader(&self) -> Result<(), Error> { - let signer_account_id = env::signer_account_id().as_v2_account_id(); - if self - .parameters - .participants() - .participants() - .iter() - .min_by_key(|(_, participant_id, _)| participant_id) - .unwrap() - .0 != signer_account_id - { - return Err(VoteError::VoterNotLeader.into()); - } - Ok(()) - } - pub fn epoch_id(&self) -> EpochId { - self.epoch_id - } - pub fn domain(&self) -> DomainConfig { - self.domain.clone() - } - pub fn proposed_parameters(&self) -> &ThresholdParameters { - &self.parameters - } - /// Casts a vote for `public_key` in `key_event_id`. - /// Fails if `signer` is not a candidate, if the candidate already voted or if there is no active key event. - /// If this vote disagrees with an earlier vote on the public key, aborts the current attempt. - /// Otherwise, returns true iff all participants have voted for the same public key. - pub fn vote_success( - &mut self, - key_event_id: &KeyEventId, - public_key: PublicKeyExtended, - ) -> Result { - let candidate = self.verify_vote(key_event_id)?; - match self - .instance - .as_mut() - .unwrap() - .vote_success(candidate, public_key)? - { - VoteSuccessResult::Voted(count) => { - if count == self.parameters.participants().len() { - Ok(true) - } else { - Ok(false) - } - } - VoteSuccessResult::PublicKeyDisagreement => { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Public key disagreement; aborting key event instance.", - ), - ); - res - }) - .as_str(), - ); - self.instance = None; - Ok(false) - } - } - } - /// Casts a vote to abort the current keygen instance. - /// A new instance needs to be started later to start a new keygen attempt. - pub fn vote_abort(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { - let candidate = self.verify_vote(&key_event_id)?; - if self.instance.as_ref().unwrap().completed.contains(&candidate) { - return Err(VoteError::VoteAlreadySubmitted.into()); - } - self.instance = None; - Ok(()) - } - /// Convenience function to internally remove the current instance if it timed out. - /// Whoever reads and parses the state must treat a timed out instance as equivalent to not - /// having an instance at all; thus this function performs no functional change. - fn cleanup_if_timed_out(&mut self) { - if let Some(instance) = self.instance.as_ref() { - if !instance.active() { - self.instance = None; - } - } - } - /// Verifies that the signer is authorized to cast a vote and that the key event ID corresponds - /// to the current generation attempt. - fn verify_vote( - &mut self, - key_event_id: &KeyEventId, - ) -> Result { - let candidate = AuthenticatedParticipantId::new( - self.parameters.participants(), - )?; - self.cleanup_if_timed_out(); - let Some(instance) = self.instance.as_ref() else { - return Err(KeyEventError::NoActiveKeyEvent.into()); - }; - if key_event_id.epoch_id != self.epoch_id - || key_event_id.domain_id != self.domain.id - || key_event_id.attempt_id != instance.attempt_id - { - return Err(KeyEventError::KeyEventIdMismatch.into()); - } - Ok(candidate) - } - /// Returns the KeyEventId that identifies the current key generation or resharing attempt. - /// It returns None if there is no active attempt (including if the attempt has timed out). - pub fn current_key_event_id(&self) -> Option { - let instance = self.instance.as_ref()?; - if instance.expires_on <= env::block_height() { - return None; - } - Some(KeyEventId::new(self.epoch_id, self.domain.id, instance.attempt_id)) - } - pub fn domain_id(&self) -> crate::primitives::domain::DomainId { - self.domain.id - } - /// Returns the current key event instance (or none) - pub fn instance(&self) -> &Option { - &self.instance - } - pub fn next_attempt_id(&self) -> AttemptId { - self.next_attempt_id - } - } - /// See KeyEventInstance::vote_success. - enum VoteSuccessResult { - /// Voted successfully, returning the number of votes so far. - Voted(usize), - /// Participants disagreed on the public key, consensus failed. - PublicKeyDisagreement, - } - #[automatically_derived] - impl ::core::fmt::Debug for VoteSuccessResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - VoteSuccessResult::Voted(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Voted", - &__self_0, - ) - } - VoteSuccessResult::PublicKeyDisagreement => { - ::core::fmt::Formatter::write_str(f, "PublicKeyDisagreement") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for VoteSuccessResult {} - #[automatically_derived] - impl ::core::cmp::PartialEq for VoteSuccessResult { - #[inline] - fn eq(&self, other: &VoteSuccessResult) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - ( - VoteSuccessResult::Voted(__self_0), - VoteSuccessResult::Voted(__arg1_0), - ) => __self_0 == __arg1_0, - _ => true, - } - } - } - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// State for a single attempt at generating or resharing a key. - pub struct KeyEventInstance { - attempt_id: AttemptId, - /// The block in which KeyEvent::start() was called. - started_in: BlockHeight, - /// The block that this attempt expires on. To clarify off-by-one behavior: if the contract were - /// called *on* or after this height, the attempt is considered no longer existent. - expires_on: BlockHeight, - /// The participants that voted that they successfully completed the keygen or resharing. - completed: BTreeSet, - /// The public key currently voted for. This is None iff no one has voted. - public_key: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for KeyEventInstance { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "KeyEventInstance", - "attempt_id", - &self.attempt_id, - "started_in", - &self.started_in, - "expires_on", - &self.expires_on, - "completed", - &self.completed, - "public_key", - &&self.public_key, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for KeyEventInstance { - #[inline] - fn clone(&self) -> KeyEventInstance { - KeyEventInstance { - attempt_id: ::core::clone::Clone::clone(&self.attempt_id), - started_in: ::core::clone::Clone::clone(&self.started_in), - expires_on: ::core::clone::Clone::clone(&self.expires_on), - completed: ::core::clone::Clone::clone(&self.completed), - public_key: ::core::clone::Clone::clone(&self.public_key), - } - } - } - #[automatically_derived] - impl ::core::default::Default for KeyEventInstance { - #[inline] - fn default() -> KeyEventInstance { - KeyEventInstance { - attempt_id: ::core::default::Default::default(), - started_in: ::core::default::Default::default(), - expires_on: ::core::default::Default::default(), - completed: ::core::default::Default::default(), - public_key: ::core::default::Default::default(), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for KeyEventInstance {} - #[automatically_derived] - impl ::core::cmp::PartialEq for KeyEventInstance { - #[inline] - fn eq(&self, other: &KeyEventInstance) -> bool { - self.attempt_id == other.attempt_id - && self.started_in == other.started_in - && self.expires_on == other.expires_on - && self.completed == other.completed - && self.public_key == other.public_key - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for KeyEventInstance { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.attempt_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.started_in, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.expires_on, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.completed, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.public_key, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for KeyEventInstance { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - attempt_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - started_in: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - expires_on: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - completed: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for KeyEventInstance { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "KeyEventInstance", - false as usize + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "attempt_id", - &self.attempt_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "started_in", - &self.started_in, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "expires_on", - &self.expires_on, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "completed", - &self.completed, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "public_key", - &self.public_key, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for KeyEventInstance { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - 4u64 => _serde::__private228::Ok(__Field::__field4), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "attempt_id" => _serde::__private228::Ok(__Field::__field0), - "started_in" => _serde::__private228::Ok(__Field::__field1), - "expires_on" => _serde::__private228::Ok(__Field::__field2), - "completed" => _serde::__private228::Ok(__Field::__field3), - "public_key" => _serde::__private228::Ok(__Field::__field4), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"attempt_id" => _serde::__private228::Ok(__Field::__field0), - b"started_in" => _serde::__private228::Ok(__Field::__field1), - b"expires_on" => _serde::__private228::Ok(__Field::__field2), - b"completed" => _serde::__private228::Ok(__Field::__field3), - b"public_key" => _serde::__private228::Ok(__Field::__field4), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = KeyEventInstance; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct KeyEventInstance", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - AttemptId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct KeyEventInstance with 5 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - BlockHeight, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct KeyEventInstance with 5 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - BlockHeight, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct KeyEventInstance with 5 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - BTreeSet, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct KeyEventInstance with 5 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct KeyEventInstance with 5 elements", - ), - ); - } - }; - _serde::__private228::Ok(KeyEventInstance { - attempt_id: __field0, - started_in: __field1, - expires_on: __field2, - completed: __field3, - public_key: __field4, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - BlockHeight, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option< - BlockHeight, - > = _serde::__private228::None; - let mut __field3: _serde::__private228::Option< - BTreeSet, - > = _serde::__private228::None; - let mut __field4: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "attempt_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "started_in", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - BlockHeight, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "expires_on", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - BlockHeight, - >(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private228::Option::is_some(&__field3) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "completed", - ), - ); - } - __field3 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - BTreeSet, - >(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private228::Option::is_some(&__field4) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "public_key", - ), - ); - } - __field4 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("attempt_id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("started_in")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("expires_on")? - } - }; - let __field3 = match __field3 { - _serde::__private228::Some(__field3) => __field3, - _serde::__private228::None => { - _serde::__private228::de::missing_field("completed")? - } - }; - let __field4 = match __field4 { - _serde::__private228::Some(__field4) => __field4, - _serde::__private228::None => { - _serde::__private228::de::missing_field("public_key")? - } - }; - _serde::__private228::Ok(KeyEventInstance { - attempt_id: __field0, - started_in: __field1, - expires_on: __field2, - completed: __field3, - public_key: __field4, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "attempt_id", - "started_in", - "expires_on", - "completed", - "public_key", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "KeyEventInstance", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - KeyEventInstance, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl KeyEventInstance { - pub fn new(attempt_id: AttemptId, timeout_blocks: u64) -> Self { - KeyEventInstance { - attempt_id, - started_in: env::block_height(), - expires_on: env::block_height() + 1 + timeout_blocks, - completed: BTreeSet::new(), - public_key: None, - } - } - pub fn completed(&self) -> &BTreeSet { - &self.completed - } - pub fn active(&self) -> bool { - env::block_height() < self.expires_on - } - pub fn attempt_id(&self) -> AttemptId { - self.attempt_id - } - pub fn expires_on(&self) -> u64 { - self.expires_on - } - /// Commits the vote of `candidate` to `public_key`, returning either Voted with the number of - /// votes already cast, or PublicKeyDisagreement if this vote conflicts with an earlier vote's - /// public key. - /// Fails if the candidate already submitted a vote. - fn vote_success( - &mut self, - candidate: AuthenticatedParticipantId, - public_key: PublicKeyExtended, - ) -> Result { - if let Some(existing_public_key) = &self.public_key { - if existing_public_key != &public_key { - return Ok(VoteSuccessResult::PublicKeyDisagreement); - } - } else { - self.public_key = Some(public_key); - } - if self.completed.contains(&candidate) { - return Err(VoteError::VoteAlreadySubmitted.into()); - } - self.completed.insert(candidate.clone()); - Ok(VoteSuccessResult::Voted(self.completed.len())) - } - } - } - pub mod resharing { - use std::collections::HashSet; - use super::key_event::KeyEvent; - use super::running::RunningContractState; - use crate::errors::{Error, InvalidParameters}; - use crate::primitives::key_state::{ - AuthenticatedAccountId, EpochId, KeyEventId, KeyForDomain, Keyset, - }; - use crate::primitives::thresholds::ThresholdParameters; - use near_account_id::AccountId; - use near_sdk::near; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// In this state, we reshare the key of every domain onto a new set of participants and threshold. - /// Similar to key generation, we reshare the key of one domain at a time; when we finish resharing - /// for one domain, we move on to the next or transition to the Running state. - /// - /// This state is reached by calling vote_new_parameters from the Running state. - /// - /// This state keeps the previous running state because: - /// - The previous running state's ThresholdParameters are needed in order to facilitate the - /// possible re-proposal of a new ThresholdParameters, in case the currently proposed set of - /// participants are no longer all online. For tracking the votes we also use the same - /// tracking structure in the running state. - /// - The previous running state's keys are needed to copy the public keys. - /// - We use the previous running state's DomainRegistry. - pub struct ResharingContractState { - pub previous_running_state: RunningContractState, - pub reshared_keys: Vec, - pub resharing_key: KeyEvent, - pub cancellation_requests: HashSet, - } - #[automatically_derived] - impl ::core::fmt::Debug for ResharingContractState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "ResharingContractState", - "previous_running_state", - &self.previous_running_state, - "reshared_keys", - &self.reshared_keys, - "resharing_key", - &self.resharing_key, - "cancellation_requests", - &&self.cancellation_requests, - ) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for ResharingContractState { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.previous_running_state, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.reshared_keys, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.resharing_key, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.cancellation_requests, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for ResharingContractState { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - previous_running_state: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - reshared_keys: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - resharing_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - cancellation_requests: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ResharingContractState { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "ResharingContractState", - false as usize + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "previous_running_state", - &self.previous_running_state, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "reshared_keys", - &self.reshared_keys, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "resharing_key", - &self.resharing_key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "cancellation_requests", - &self.cancellation_requests, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ResharingContractState { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "previous_running_state" => { - _serde::__private228::Ok(__Field::__field0) - } - "reshared_keys" => { - _serde::__private228::Ok(__Field::__field1) - } - "resharing_key" => { - _serde::__private228::Ok(__Field::__field2) - } - "cancellation_requests" => { - _serde::__private228::Ok(__Field::__field3) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"previous_running_state" => { - _serde::__private228::Ok(__Field::__field0) - } - b"reshared_keys" => { - _serde::__private228::Ok(__Field::__field1) - } - b"resharing_key" => { - _serde::__private228::Ok(__Field::__field2) - } - b"cancellation_requests" => { - _serde::__private228::Ok(__Field::__field3) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData< - ResharingContractState, - >, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ResharingContractState; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct ResharingContractState", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - RunningContractState, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ResharingContractState with 4 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct ResharingContractState with 4 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - KeyEvent, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct ResharingContractState with 4 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - HashSet, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct ResharingContractState with 4 elements", - ), - ); - } - }; - _serde::__private228::Ok(ResharingContractState { - previous_running_state: __field0, - reshared_keys: __field1, - resharing_key: __field2, - cancellation_requests: __field3, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - RunningContractState, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - Vec, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option = _serde::__private228::None; - let mut __field3: _serde::__private228::Option< - HashSet, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "previous_running_state", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - RunningContractState, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "reshared_keys", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Vec, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "resharing_key", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private228::Option::is_some(&__field3) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "cancellation_requests", - ), - ); - } - __field3 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - HashSet, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "previous_running_state", - )? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("reshared_keys")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("resharing_key")? - } - }; - let __field3 = match __field3 { - _serde::__private228::Some(__field3) => __field3, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "cancellation_requests", - )? - } - }; - _serde::__private228::Ok(ResharingContractState { - previous_running_state: __field0, - reshared_keys: __field1, - resharing_key: __field2, - cancellation_requests: __field3, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "previous_running_state", - "reshared_keys", - "resharing_key", - "cancellation_requests", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ResharingContractState", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - ResharingContractState, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl ResharingContractState { - pub fn previous_keyset(&self) -> &Keyset { - &self.previous_running_state.keyset - } - /// Returns the epoch ID that we would transition into if resharing were completed successfully. - /// This would increment if we end up voting for a re-proposal. - pub fn prospective_epoch_id(&self) -> EpochId { - self.resharing_key.epoch_id() - } - /// Casts a vote for a re-proposal. Requires the signer to be a participant of the prospective epoch. - /// Returns a new [`ResharingContractState`] if all participants of the re-proposal voted for the re-proposal. - /// Note that transitioning to a new state implicitly requires `threshold` number of votes from participants of the - /// previous running state. - pub fn vote_new_parameters( - &mut self, - prospective_epoch_id: EpochId, - proposal: &ThresholdParameters, - ) -> Result, Error> { - let expected_prospective_epoch_id = self.prospective_epoch_id().next(); - if prospective_epoch_id != expected_prospective_epoch_id { - return Err( - InvalidParameters::EpochMismatch { - expected: expected_prospective_epoch_id, - provided: prospective_epoch_id, - } - .into(), - ); - } - if self.previous_running_state.process_new_parameters_proposal(proposal)? - { - return Ok( - Some(ResharingContractState { - previous_running_state: RunningContractState::new( - self.previous_running_state.domains.clone(), - self.previous_running_state.keyset.clone(), - self.previous_running_state.parameters.clone(), - ), - reshared_keys: Vec::new(), - resharing_key: KeyEvent::new( - self.prospective_epoch_id().next(), - self - .previous_running_state - .domains - .get_domain_by_index(0) - .unwrap() - .clone(), - proposal.clone(), - ), - cancellation_requests: HashSet::new(), - }), - ); - } - Ok(None) - } - /// Starts a new attempt to reshare the key for the current domain. - /// Returns an Error if the signer is not the leader (the participant with the lowest ID). - pub fn start( - &mut self, - key_event_id: KeyEventId, - key_event_timeout_blocks: u64, - ) -> Result<(), Error> { - self.resharing_key.start(key_event_id, key_event_timeout_blocks) - } - /// Casts a successfully-reshared vote for for the attempt identified by `key_event_id`. - /// Upon success (a return of Ok(...)), the effect of this method is one of the following: - /// - A vote has been collected but we don't have enough votes yet. - /// - Everyone has now voted; the state transitions into resharing the key for the next domain. - /// (This returns Ok(None) still). - /// - Same as the last case, except that all domains' keys have been reshared now, and we - /// return Ok(Some(running state)) that the caller should now transition into. - /// - /// Fails in the following cases: - /// - There is no active key resharing attempt (including if the attempt timed out). - /// - The key_event_id corresponds to a different domain, different epoch, or different attempt - /// from the current key resharing attempt. - /// - The signer is not a participant in the *proposed* set of participants. - pub fn vote_reshared( - &mut self, - key_event_id: KeyEventId, - ) -> Result, Error> { - let previous_key = self - .previous_keyset() - .domains[self.reshared_keys.len()] - .clone(); - if self - .resharing_key - .vote_success(&key_event_id, previous_key.key.clone())? - { - let new_key = KeyForDomain { - domain_id: key_event_id.domain_id, - attempt: key_event_id.attempt_id, - key: previous_key.key, - }; - self.reshared_keys.push(new_key); - if let Some(next_domain) = self - .previous_running_state - .domains - .get_domain_by_index(self.reshared_keys.len()) - { - self.resharing_key = KeyEvent::new( - self.prospective_epoch_id(), - next_domain.clone(), - self.resharing_key.proposed_parameters().clone(), - ); - } else { - return Ok( - Some( - RunningContractState::new( - self.previous_running_state.domains.clone(), - Keyset::new( - self.prospective_epoch_id(), - self.reshared_keys.clone(), - ), - self.resharing_key.proposed_parameters().clone(), - ), - ), - ); - } - } - Ok(None) - } - /// Casts a vote to abort the current key resharing attempt. - /// After aborting, another call to start() is necessary to start a new attempt. - /// Returns error if there is no active attempt, or if the signer is not a proposed participant. - pub fn vote_abort(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { - self.resharing_key.vote_abort(key_event_id) - } - pub fn vote_cancel_resharing( - &mut self, - ) -> Result, Error> { - let previous_running_participants = self - .previous_running_state - .parameters - .participants(); - let authenticated_candidate = AuthenticatedAccountId::new( - previous_running_participants, - )?; - self.cancellation_requests.insert(authenticated_candidate); - let cancellation_votes_count = self.cancellation_requests.len() as u64; - let previous_running_threshold = self - .previous_running_state - .parameters - .threshold(); - let threshold_cancellation_votes_reached: bool = cancellation_votes_count - >= previous_running_threshold.value(); - let running_state = if threshold_cancellation_votes_reached { - let mut previous_running_state = self.previous_running_state.clone(); - let prospective_epoch_id = self.prospective_epoch_id(); - previous_running_state.previously_cancelled_resharing_epoch_id = Some( - prospective_epoch_id, - ); - Some(previous_running_state) - } else { - None - }; - Ok(running_state) - } - pub fn is_participant_or_prospective_participant( - &self, - account_id: &AccountId, - ) -> bool { - self.previous_running_state.is_participant(account_id) - || self - .resharing_key - .proposed_parameters() - .participants() - .is_participant(account_id) - } - } - } - pub mod running { - use super::initializing::InitializingContractState; - use super::key_event::KeyEvent; - use super::resharing::ResharingContractState; - use crate::errors::{DomainError, Error, InvalidParameters, VoteError}; - use crate::primitives::{ - domain::{AddDomainsVotes, DomainConfig, DomainRegistry}, - key_state::{ - AuthenticatedAccountId, AuthenticatedParticipantId, EpochId, Keyset, - }, - thresholds::ThresholdParameters, votes::ThresholdParametersVotes, - }; - use near_account_id::AccountId; - use near_sdk::near; - use std::collections::{BTreeSet, HashSet}; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// In this state, the contract is ready to process signature requests. - /// - /// Proposals can be submitted to modify the state: - /// - vote_add_domains, upon threshold agreement, transitions into the - /// Initializing state to generate keys for new domains. - /// - vote_new_parameters, upon threshold agreement, transitions into the - /// Resharing state to reshare keys for new participants and also change the - /// threshold if desired. - pub struct RunningContractState { - /// The domains for which we have a key ready for signature processing. - pub domains: DomainRegistry, - /// The keys that are currently in use; for each domain provides an unique identifier for a - /// distributed key, so that the nodes can identify which local keyshare to use. - pub keyset: Keyset, - /// The current participants and threshold. - pub parameters: ThresholdParameters, - /// Votes for proposals for a new set of participants and threshold. - pub parameters_votes: ThresholdParametersVotes, - /// Votes for proposals to add new domains. - pub add_domains_votes: AddDomainsVotes, - /// The previous epoch id for a resharing state that was cancelled. - /// This epoch id is tracked, as the next time the state transitions to resharing, - /// we can't reuse a previously cancelled epoch id. - pub previously_cancelled_resharing_epoch_id: Option, - } - #[automatically_derived] - impl ::core::clone::Clone for RunningContractState { - #[inline] - fn clone(&self) -> RunningContractState { - RunningContractState { - domains: ::core::clone::Clone::clone(&self.domains), - keyset: ::core::clone::Clone::clone(&self.keyset), - parameters: ::core::clone::Clone::clone(&self.parameters), - parameters_votes: ::core::clone::Clone::clone( - &self.parameters_votes, - ), - add_domains_votes: ::core::clone::Clone::clone( - &self.add_domains_votes, - ), - previously_cancelled_resharing_epoch_id: ::core::clone::Clone::clone( - &self.previously_cancelled_resharing_epoch_id, - ), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for RunningContractState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "domains", - "keyset", - "parameters", - "parameters_votes", - "add_domains_votes", - "previously_cancelled_resharing_epoch_id", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.domains, - &self.keyset, - &self.parameters, - &self.parameters_votes, - &self.add_domains_votes, - &&self.previously_cancelled_resharing_epoch_id, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "RunningContractState", - names, - values, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RunningContractState {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RunningContractState { - #[inline] - fn eq(&self, other: &RunningContractState) -> bool { - self.domains == other.domains && self.keyset == other.keyset - && self.parameters == other.parameters - && self.parameters_votes == other.parameters_votes - && self.add_domains_votes == other.add_domains_votes - && self.previously_cancelled_resharing_epoch_id - == other.previously_cancelled_resharing_epoch_id - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RunningContractState { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for RunningContractState { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.domains, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.keyset, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.parameters, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.parameters_votes, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.add_domains_votes, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.previously_cancelled_resharing_epoch_id, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for RunningContractState { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - domains: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - keyset: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - parameters: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - parameters_votes: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - add_domains_votes: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - previously_cancelled_resharing_epoch_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for RunningContractState { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "RunningContractState", - false as usize + 1 + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domains", - &self.domains, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "keyset", - &self.keyset, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "parameters", - &self.parameters, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "parameters_votes", - &self.parameters_votes, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "add_domains_votes", - &self.add_domains_votes, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "previously_cancelled_resharing_epoch_id", - &self.previously_cancelled_resharing_epoch_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RunningContractState { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - 4u64 => _serde::__private228::Ok(__Field::__field4), - 5u64 => _serde::__private228::Ok(__Field::__field5), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "domains" => _serde::__private228::Ok(__Field::__field0), - "keyset" => _serde::__private228::Ok(__Field::__field1), - "parameters" => _serde::__private228::Ok(__Field::__field2), - "parameters_votes" => { - _serde::__private228::Ok(__Field::__field3) - } - "add_domains_votes" => { - _serde::__private228::Ok(__Field::__field4) - } - "previously_cancelled_resharing_epoch_id" => { - _serde::__private228::Ok(__Field::__field5) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"domains" => _serde::__private228::Ok(__Field::__field0), - b"keyset" => _serde::__private228::Ok(__Field::__field1), - b"parameters" => _serde::__private228::Ok(__Field::__field2), - b"parameters_votes" => { - _serde::__private228::Ok(__Field::__field3) - } - b"add_domains_votes" => { - _serde::__private228::Ok(__Field::__field4) - } - b"previously_cancelled_resharing_epoch_id" => { - _serde::__private228::Ok(__Field::__field5) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = RunningContractState; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct RunningContractState", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - DomainRegistry, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct RunningContractState with 6 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Keyset, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct RunningContractState with 6 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - ThresholdParameters, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct RunningContractState with 6 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - ThresholdParametersVotes, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct RunningContractState with 6 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - AddDomainsVotes, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct RunningContractState with 6 elements", - ), - ); - } - }; - let __field5 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 5usize, - &"struct RunningContractState with 6 elements", - ), - ); - } - }; - _serde::__private228::Ok(RunningContractState { - domains: __field0, - keyset: __field1, - parameters: __field2, - parameters_votes: __field3, - add_domains_votes: __field4, - previously_cancelled_resharing_epoch_id: __field5, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - DomainRegistry, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - let mut __field2: _serde::__private228::Option< - ThresholdParameters, - > = _serde::__private228::None; - let mut __field3: _serde::__private228::Option< - ThresholdParametersVotes, - > = _serde::__private228::None; - let mut __field4: _serde::__private228::Option< - AddDomainsVotes, - > = _serde::__private228::None; - let mut __field5: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "domains", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - DomainRegistry, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("keyset"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "parameters", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - ThresholdParameters, - >(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private228::Option::is_some(&__field3) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "parameters_votes", - ), - ); - } - __field3 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - ThresholdParametersVotes, - >(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private228::Option::is_some(&__field4) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "add_domains_votes", - ), - ); - } - __field4 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - AddDomainsVotes, - >(&mut __map)?, - ); - } - __Field::__field5 => { - if _serde::__private228::Option::is_some(&__field5) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "previously_cancelled_resharing_epoch_id", - ), - ); - } - __field5 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("domains")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("keyset")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field("parameters")? - } - }; - let __field3 = match __field3 { - _serde::__private228::Some(__field3) => __field3, - _serde::__private228::None => { - _serde::__private228::de::missing_field("parameters_votes")? - } - }; - let __field4 = match __field4 { - _serde::__private228::Some(__field4) => __field4, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "add_domains_votes", - )? - } - }; - let __field5 = match __field5 { - _serde::__private228::Some(__field5) => __field5, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "previously_cancelled_resharing_epoch_id", - )? - } - }; - _serde::__private228::Ok(RunningContractState { - domains: __field0, - keyset: __field1, - parameters: __field2, - parameters_votes: __field3, - add_domains_votes: __field4, - previously_cancelled_resharing_epoch_id: __field5, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "domains", - "keyset", - "parameters", - "parameters_votes", - "add_domains_votes", - "previously_cancelled_resharing_epoch_id", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "RunningContractState", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::< - RunningContractState, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl RunningContractState { - pub fn new( - domains: DomainRegistry, - keyset: Keyset, - parameters: ThresholdParameters, - ) -> Self { - RunningContractState { - domains, - keyset, - parameters, - parameters_votes: ThresholdParametersVotes::default(), - add_domains_votes: AddDomainsVotes::default(), - previously_cancelled_resharing_epoch_id: None, - } - } - pub fn transition_to_resharing_no_checks( - &mut self, - proposal: &ThresholdParameters, - ) -> Option { - if let Some(first_domain) = self.domains.get_domain_by_index(0) { - let epoch_id = self.prospective_epoch_id(); - Some(ResharingContractState { - previous_running_state: RunningContractState::new( - self.domains.clone(), - self.keyset.clone(), - self.parameters.clone(), - ), - reshared_keys: Vec::new(), - resharing_key: KeyEvent::new( - epoch_id, - first_domain.clone(), - proposal.clone(), - ), - cancellation_requests: HashSet::new(), - }) - } else { - *self = RunningContractState::new( - self.domains.clone(), - Keyset::new(self.keyset.epoch_id.next(), Vec::new()), - proposal.clone(), - ); - None - } - } - /// Casts a vote for `proposal` to the current state, propagating any errors. - /// Returns ResharingContractState if the proposal is accepted. - pub fn vote_new_parameters( - &mut self, - prospective_epoch_id: EpochId, - proposal: &ThresholdParameters, - ) -> Result, Error> { - let expected_prospective_epoch_id = self.prospective_epoch_id(); - if prospective_epoch_id != expected_prospective_epoch_id { - return Err( - InvalidParameters::EpochMismatch { - expected: expected_prospective_epoch_id, - provided: prospective_epoch_id, - } - .into(), - ); - } - if self.process_new_parameters_proposal(proposal)? { - return Ok(self.transition_to_resharing_no_checks(proposal)); - } - Ok(None) - } - pub fn prospective_epoch_id(&self) -> EpochId { - match self.previously_cancelled_resharing_epoch_id { - Some(cancelled_epoch_id) => cancelled_epoch_id, - None => self.keyset.epoch_id, - } - .next() - } - /// Casts a vote for `proposal`, removing any previous votes by `env::signer_account_id()`. - /// Fails if the proposal is invalid or the signer is not a proposed participant. - /// Returns true if all participants of the proposed parameters voted for it. - pub(super) fn process_new_parameters_proposal( - &mut self, - proposal: &ThresholdParameters, - ) -> Result { - self.parameters.validate_incoming_proposal(proposal)?; - let candidate = AuthenticatedAccountId::new(proposal.participants())?; - if AuthenticatedAccountId::new(self.parameters.participants()).is_err() { - let n_votes = self - .parameters_votes - .n_votes(proposal, self.parameters.participants()); - if n_votes < self.parameters.threshold().value() { - return Err(VoteError::VoterPending.into()); - } - } - let n_votes = self.parameters_votes.vote(proposal, candidate); - Ok(proposal.participants().len() as u64 == n_votes) - } - /// Casts a vote for the signer participant to add new domains, replacing any previous vote. - /// If the number of votes for the same set of new domains reaches the number of participants, - /// returns the InitializingContractState we should transition into to generate keys for these - /// new domains. - pub fn vote_add_domains( - &mut self, - domains: Vec, - ) -> Result, Error> { - if domains.is_empty() { - return Err(DomainError::AddDomainsMustAddAtLeastOneDomain.into()); - } - let participant = AuthenticatedParticipantId::new( - self.parameters.participants(), - )?; - let n_votes = self.add_domains_votes.vote(domains.clone(), &participant); - if self.parameters.participants().len() as u64 == n_votes { - let new_domains = self.domains.add_domains(domains.clone())?; - Ok( - Some(InitializingContractState { - generated_keys: self.keyset.domains.clone(), - domains: new_domains, - epoch_id: self.keyset.epoch_id, - generating_key: KeyEvent::new( - self.keyset.epoch_id, - domains[0].clone(), - self.parameters.clone(), - ), - cancel_votes: BTreeSet::new(), - }), - ) - } else { - Ok(None) - } - } - pub fn is_participant(&self, account_id: &AccountId) -> bool { - self.parameters.participants().is_participant(account_id) - } - } - } - use crate::crypto_shared::types::PublicKeyExtended; - use crate::errors::{DomainError, Error, InvalidState}; - use crate::primitives::{ - domain::{DomainConfig, DomainId, DomainRegistry, SignatureScheme}, - key_state::{AuthenticatedParticipantId, EpochId, KeyEventId}, - participants::Participants, thresholds::{Threshold, ThresholdParameters}, - }; - use initializing::InitializingContractState; - use near_account_id::AccountId; - use near_sdk::near; - use resharing::ResharingContractState; - use running::RunningContractState; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub enum ProtocolContractState { - NotInitialized, - Initializing(InitializingContractState), - Running(RunningContractState), - Resharing(ResharingContractState), - } - #[automatically_derived] - impl ::core::fmt::Debug for ProtocolContractState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - ProtocolContractState::NotInitialized => { - ::core::fmt::Formatter::write_str(f, "NotInitialized") - } - ProtocolContractState::Initializing(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Initializing", - &__self_0, - ) - } - ProtocolContractState::Running(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Running", - &__self_0, - ) - } - ProtocolContractState::Resharing(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Resharing", - &__self_0, - ) - } - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for ProtocolContractState { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - let variant_idx: u8 = match self { - ProtocolContractState::NotInitialized => 0u8, - ProtocolContractState::Initializing(..) => 1u8, - ProtocolContractState::Running(..) => 2u8, - ProtocolContractState::Resharing(..) => 3u8, - }; - writer.write_all(&variant_idx.to_le_bytes())?; - match self { - ProtocolContractState::Initializing(id0) => { - ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; - } - ProtocolContractState::Running(id0) => { - ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; - } - ProtocolContractState::Resharing(id0) => { - ::near_sdk::borsh::BorshSerialize::serialize(id0, writer)?; - } - _ => {} - } - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for ProtocolContractState { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - let tag = ::deserialize_reader( - reader, - )?; - ::deserialize_variant(reader, tag) - } - } - impl ::near_sdk::borsh::de::EnumExt for ProtocolContractState { - fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - variant_tag: u8, - ) -> ::core::result::Result { - let mut return_value = if variant_tag == 0u8 { - ProtocolContractState::NotInitialized - } else if variant_tag == 1u8 { - ProtocolContractState::Initializing( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ) - } else if variant_tag == 2u8 { - ProtocolContractState::Running( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ) - } else if variant_tag == 3u8 { - ProtocolContractState::Resharing( - ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - ) - } else { - return Err( - ::near_sdk::borsh::io::Error::new( - ::near_sdk::borsh::io::ErrorKind::InvalidData, - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Unexpected variant tag: {0:?}", variant_tag), - ); - res - }), - ), - ) - }; - Ok(return_value) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ProtocolContractState { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - ProtocolContractState::NotInitialized => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "ProtocolContractState", - 0u32, - "NotInitialized", - ) - } - ProtocolContractState::Initializing(ref __field0) => { - _serde::Serializer::serialize_newtype_variant( - __serializer, - "ProtocolContractState", - 1u32, - "Initializing", - __field0, - ) - } - ProtocolContractState::Running(ref __field0) => { - _serde::Serializer::serialize_newtype_variant( - __serializer, - "ProtocolContractState", - 2u32, - "Running", - __field0, - ) - } - ProtocolContractState::Resharing(ref __field0) => { - _serde::Serializer::serialize_newtype_variant( - __serializer, - "ProtocolContractState", - 3u32, - "Resharing", - __field0, - ) - } - } - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ProtocolContractState { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - 3u64 => _serde::__private228::Ok(__Field::__field3), - _ => { - _serde::__private228::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 4", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "NotInitialized" => { - _serde::__private228::Ok(__Field::__field0) - } - "Initializing" => _serde::__private228::Ok(__Field::__field1), - "Running" => _serde::__private228::Ok(__Field::__field2), - "Resharing" => _serde::__private228::Ok(__Field::__field3), - _ => { - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"NotInitialized" => { - _serde::__private228::Ok(__Field::__field0) - } - b"Initializing" => { - _serde::__private228::Ok(__Field::__field1) - } - b"Running" => _serde::__private228::Ok(__Field::__field2), - b"Resharing" => _serde::__private228::Ok(__Field::__field3), - _ => { - let __value = &_serde::__private228::from_utf8_lossy( - __value, - ); - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ProtocolContractState; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "enum ProtocolContractState", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private228::Ok( - ProtocolContractState::NotInitialized, - ) - } - (__Field::__field1, __variant) => { - _serde::__private228::Result::map( - _serde::de::VariantAccess::newtype_variant::< - InitializingContractState, - >(__variant), - ProtocolContractState::Initializing, - ) - } - (__Field::__field2, __variant) => { - _serde::__private228::Result::map( - _serde::de::VariantAccess::newtype_variant::< - RunningContractState, - >(__variant), - ProtocolContractState::Running, - ) - } - (__Field::__field3, __variant) => { - _serde::__private228::Result::map( - _serde::de::VariantAccess::newtype_variant::< - ResharingContractState, - >(__variant), - ProtocolContractState::Resharing, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "NotInitialized", - "Initializing", - "Running", - "Resharing", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "ProtocolContractState", - VARIANTS, - __Visitor { - marker: _serde::__private228::PhantomData::< - ProtocolContractState, - >, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl ProtocolContractState { - pub fn domain_registry(&self) -> Result<&DomainRegistry, Error> { - let domain_registry = match self { - ProtocolContractState::Running(state) => &state.domains, - ProtocolContractState::Resharing(state) => { - &state.previous_running_state.domains - } - _ => return Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), - }; - Ok(domain_registry) - } - pub fn public_key( - &self, - domain_id: DomainId, - ) -> Result { - match self { - ProtocolContractState::Running(state) => { - state.keyset.public_key(domain_id) - } - ProtocolContractState::Resharing(state) => { - state.previous_keyset().public_key(domain_id) - } - _ => Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), - } - } - pub fn threshold(&self) -> Result { - match self { - ProtocolContractState::Initializing(state) => { - Ok(state.generating_key.proposed_parameters().threshold()) - } - ProtocolContractState::Running(state) => Ok(state.parameters.threshold()), - ProtocolContractState::Resharing(state) => { - Ok(state.previous_running_state.parameters.threshold()) - } - ProtocolContractState::NotInitialized => { - Err(InvalidState::UnexpectedProtocolState.into()) - } - } - } - pub fn start_keygen_instance( - &mut self, - key_event_id: KeyEventId, - key_event_timeout_blocks: u64, - ) -> Result<(), Error> { - let ProtocolContractState::Initializing(state) = self else { - return Err(InvalidState::ProtocolStateNotInitializing.into()); - }; - state.start(key_event_id, key_event_timeout_blocks) - } - pub fn start_reshare_instance( - &mut self, - key_event_id: KeyEventId, - key_event_timeout_blocks: u64, - ) -> Result<(), Error> { - let ProtocolContractState::Resharing(state) = self else { - return Err(InvalidState::ProtocolStateNotResharing.into()); - }; - state.start(key_event_id, key_event_timeout_blocks) - } - pub fn vote_reshared( - &mut self, - key_event_id: KeyEventId, - ) -> Result, Error> { - let ProtocolContractState::Resharing(state) = self else { - return Err(InvalidState::ProtocolStateNotResharing.into()); - }; - state - .vote_reshared(key_event_id) - .map(|x| x.map(ProtocolContractState::Running)) - } - pub fn vote_cancel_resharing( - &mut self, - ) -> Result, Error> { - let ProtocolContractState::Resharing(state) = self else { - return Err(InvalidState::ProtocolStateNotResharing.into()); - }; - state.vote_cancel_resharing().map(|x| x.map(ProtocolContractState::Running)) - } - /// Casts a vote for `public_key` in `key_event_id` during Initialization. - /// Fails if the protocol is not in `Initializing` state. - /// Returns the new protocol state if enough votes have been submitted. - pub fn vote_pk( - &mut self, - key_event_id: KeyEventId, - public_key: PublicKeyExtended, - ) -> Result, Error> { - let ProtocolContractState::Initializing(state) = self else { - return Err(InvalidState::ProtocolStateNotInitializing.into()); - }; - state - .vote_pk(key_event_id, public_key) - .map(|x| x.map(ProtocolContractState::Running)) - } - /// Casts a vote for `proposed_parameters`, returning the new protocol state if the proposal is - /// accepted. Returns an error if the protocol is not in the Running or Resharing state. - pub fn vote_new_parameters( - &mut self, - prospective_epoch_id: EpochId, - proposed_parameters: &ThresholdParameters, - ) -> Result, Error> { - match self { - ProtocolContractState::Running(state) => { - state.vote_new_parameters(prospective_epoch_id, proposed_parameters) - } - ProtocolContractState::Resharing(state) => { - state.vote_new_parameters(prospective_epoch_id, proposed_parameters) - } - _ => Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), - } - .map(|x| x.map(ProtocolContractState::Resharing)) - } - pub fn vote_add_domains( - &mut self, - domains: Vec, - ) -> Result, Error> { - match self { - ProtocolContractState::Running(state) => state.vote_add_domains(domains), - _ => Err(InvalidState::ProtocolStateNotRunning.into()), - } - .map(|x| x.map(ProtocolContractState::Initializing)) - } - pub fn vote_abort_key_event_instance( - &mut self, - key_event_id: KeyEventId, - ) -> Result<(), Error> { - match self { - ProtocolContractState::Resharing(state) => state.vote_abort(key_event_id), - ProtocolContractState::Initializing(state) => { - state.vote_abort(key_event_id) - } - _ => Err(InvalidState::ProtocolStateNotRunningNorResharing.into()), - } - } - pub fn vote_cancel_keygen( - &mut self, - next_domain_id: u64, - ) -> Result, Error> { - match self { - ProtocolContractState::Initializing(state) => { - state.vote_cancel(next_domain_id) - } - _ => Err(InvalidState::ProtocolStateNotInitializing.into()), - } - .map(|x| x.map(ProtocolContractState::Running)) - } - pub fn most_recent_domain_for_protocol( - &self, - signature_scheme: SignatureScheme, - ) -> Result { - self.domain_registry()? - .most_recent_domain_for_protocol(signature_scheme) - .ok_or_else(|| DomainError::NoSuchDomain.into()) - } - pub(super) fn threshold_parameters( - &self, - ) -> Result<&ThresholdParameters, ContractNotInitialized> { - match self { - ProtocolContractState::NotInitialized => Err(ContractNotInitialized), - ProtocolContractState::Initializing(initializing_contract_state) => { - Ok(initializing_contract_state.generating_key.proposed_parameters()) - } - ProtocolContractState::Running(running_contract_state) => { - Ok(&running_contract_state.parameters) - } - ProtocolContractState::Resharing(resharing_contract_state) => { - Ok(&resharing_contract_state.previous_running_state.parameters) - } - } - } - } - impl ProtocolContractState { - pub fn name(&self) -> &'static str { - match self { - ProtocolContractState::NotInitialized => "NotInitialized", - ProtocolContractState::Initializing(_) => "Initializing", - ProtocolContractState::Running(_) => "Running", - ProtocolContractState::Resharing(_) => "Resharing", - } - } - pub fn is_running_or_resharing(&self) -> bool { - match self { - ProtocolContractState::Running(_) - | ProtocolContractState::Resharing(_) => true, - _ => false, - } - } - pub fn authenticate_update_vote(&self) -> Result<(), Error> { - match &self { - ProtocolContractState::Initializing(state) => { - AuthenticatedParticipantId::new( - state.generating_key.proposed_parameters().participants(), - )?; - } - ProtocolContractState::Running(state) => { - AuthenticatedParticipantId::new(state.parameters.participants())?; - } - ProtocolContractState::Resharing(state) => { - AuthenticatedParticipantId::new( - state.previous_running_state.parameters.participants(), - )?; - } - ProtocolContractState::NotInitialized => { - return Err( - InvalidState::UnexpectedProtocolState.message(self.name()), - ); - } - }; - Ok(()) - } - /// Returns a reference to the relevant `Participants` list - /// based on the current protocol phase. - /// - /// - `Initializing` → uses proposed participants from generating_key - /// - `Running` → uses current active participants - /// - `Resharing` → uses new participants from resharing proposal - /// - /// Panics if called when `NotInitialized`. - pub fn active_participants(&self) -> &Participants { - match self { - ProtocolContractState::Initializing(state) => { - state.generating_key.proposed_parameters().participants() - } - ProtocolContractState::Running(state) => state.parameters.participants(), - ProtocolContractState::Resharing(state) => { - state.resharing_key.proposed_parameters().participants() - } - ProtocolContractState::NotInitialized => { - { - ::core::panicking::panic_fmt( - format_args!( - "Protocol must be Initializing, Running, or Resharing to access active participants", - ), - ); - }; - } - } - } - pub fn is_existing_or_prospective_participant( - &self, - account_id: &AccountId, - ) -> Result { - let is_existing_or_prospective_participant = match &self { - ProtocolContractState::Initializing(state) => { - state.is_participant(account_id) - } - ProtocolContractState::Running(state) => state.is_participant(account_id), - ProtocolContractState::Resharing(state) => { - state.is_participant_or_prospective_participant(account_id) - } - ProtocolContractState::NotInitialized => { - return Err( - InvalidState::UnexpectedProtocolState.message(self.name()), - ); - } - }; - Ok(is_existing_or_prospective_participant) - } - } - pub(super) struct ContractNotInitialized; - #[automatically_derived] - impl ::core::fmt::Debug for ContractNotInitialized { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "ContractNotInitialized") - } - } - #[automatically_derived] - impl ::core::clone::Clone for ContractNotInitialized { - #[inline] - fn clone(&self) -> ContractNotInitialized { - ContractNotInitialized - } - } -} -pub mod storage_keys { - use near_sdk::{near, BorshStorageKey}; - #[borsh(crate = ":: near_sdk :: borsh")] - pub enum StorageKey { - _DeprecatedPendingRequests, - /// Proposed updates to the contract code and config. - _DeprecatedProposedUpdatesEntries, - _DeprecatedRequestsByTimestamp, - PendingSignatureRequestsV2, - ProposedUpdatesEntriesV2, - ProposedUpdatesVotesV2, - _DeprecatedTeeParticipantAttestation, - PendingCKDRequests, - BackupServicesInfo, - NodeMigrations, - } - #[automatically_derived] - impl ::core::hash::Hash for StorageKey { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - let __self_discr = ::core::intrinsics::discriminant_value(self); - ::core::hash::Hash::hash(&__self_discr, state) - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageKey { - #[inline] - fn clone(&self) -> StorageKey { - match self { - StorageKey::_DeprecatedPendingRequests => { - StorageKey::_DeprecatedPendingRequests - } - StorageKey::_DeprecatedProposedUpdatesEntries => { - StorageKey::_DeprecatedProposedUpdatesEntries - } - StorageKey::_DeprecatedRequestsByTimestamp => { - StorageKey::_DeprecatedRequestsByTimestamp - } - StorageKey::PendingSignatureRequestsV2 => { - StorageKey::PendingSignatureRequestsV2 - } - StorageKey::ProposedUpdatesEntriesV2 => { - StorageKey::ProposedUpdatesEntriesV2 - } - StorageKey::ProposedUpdatesVotesV2 => StorageKey::ProposedUpdatesVotesV2, - StorageKey::_DeprecatedTeeParticipantAttestation => { - StorageKey::_DeprecatedTeeParticipantAttestation - } - StorageKey::PendingCKDRequests => StorageKey::PendingCKDRequests, - StorageKey::BackupServicesInfo => StorageKey::BackupServicesInfo, - StorageKey::NodeMigrations => StorageKey::NodeMigrations, - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageKey { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - StorageKey::_DeprecatedPendingRequests => { - "_DeprecatedPendingRequests" - } - StorageKey::_DeprecatedProposedUpdatesEntries => { - "_DeprecatedProposedUpdatesEntries" - } - StorageKey::_DeprecatedRequestsByTimestamp => { - "_DeprecatedRequestsByTimestamp" - } - StorageKey::PendingSignatureRequestsV2 => { - "PendingSignatureRequestsV2" - } - StorageKey::ProposedUpdatesEntriesV2 => "ProposedUpdatesEntriesV2", - StorageKey::ProposedUpdatesVotesV2 => "ProposedUpdatesVotesV2", - StorageKey::_DeprecatedTeeParticipantAttestation => { - "_DeprecatedTeeParticipantAttestation" - } - StorageKey::PendingCKDRequests => "PendingCKDRequests", - StorageKey::BackupServicesInfo => "BackupServicesInfo", - StorageKey::NodeMigrations => "NodeMigrations", - }, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageKey {} - #[automatically_derived] - impl ::core::cmp::PartialEq for StorageKey { - #[inline] - fn eq(&self, other: &StorageKey) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageKey { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - impl ::near_sdk::__private::BorshIntoStorageKey for StorageKey - where - StorageKey: ::near_sdk::borsh::BorshSerialize, - {} - impl ::near_sdk::borsh::ser::BorshSerialize for StorageKey { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - let variant_idx: u8 = match self { - StorageKey::_DeprecatedPendingRequests => 0u8, - StorageKey::_DeprecatedProposedUpdatesEntries => 1u8, - StorageKey::_DeprecatedRequestsByTimestamp => 2u8, - StorageKey::PendingSignatureRequestsV2 => 3u8, - StorageKey::ProposedUpdatesEntriesV2 => 4u8, - StorageKey::ProposedUpdatesVotesV2 => 5u8, - StorageKey::_DeprecatedTeeParticipantAttestation => 6u8, - StorageKey::PendingCKDRequests => 7u8, - StorageKey::BackupServicesInfo => 8u8, - StorageKey::NodeMigrations => 9u8, - }; - writer.write_all(&variant_idx.to_le_bytes())?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for StorageKey { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - let tag = ::deserialize_reader( - reader, - )?; - ::deserialize_variant(reader, tag) - } - } - impl ::near_sdk::borsh::de::EnumExt for StorageKey { - fn deserialize_variant<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - variant_tag: u8, - ) -> ::core::result::Result { - let mut return_value = if variant_tag == 0u8 { - StorageKey::_DeprecatedPendingRequests - } else if variant_tag == 1u8 { - StorageKey::_DeprecatedProposedUpdatesEntries - } else if variant_tag == 2u8 { - StorageKey::_DeprecatedRequestsByTimestamp - } else if variant_tag == 3u8 { - StorageKey::PendingSignatureRequestsV2 - } else if variant_tag == 4u8 { - StorageKey::ProposedUpdatesEntriesV2 - } else if variant_tag == 5u8 { - StorageKey::ProposedUpdatesVotesV2 - } else if variant_tag == 6u8 { - StorageKey::_DeprecatedTeeParticipantAttestation - } else if variant_tag == 7u8 { - StorageKey::PendingCKDRequests - } else if variant_tag == 8u8 { - StorageKey::BackupServicesInfo - } else if variant_tag == 9u8 { - StorageKey::NodeMigrations - } else { - return Err( - ::near_sdk::borsh::io::Error::new( - ::near_sdk::borsh::io::ErrorKind::InvalidData, - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Unexpected variant tag: {0:?}", variant_tag), - ); - res - }), - ), - ) - }; - Ok(return_value) - } - } -} -pub mod tee { - pub mod proposal { - use borsh::{BorshDeserialize, BorshSerialize}; - use near_sdk::{env::sha256, log, near}; - use std::{collections::BTreeMap, time::Duration}; - use crate::primitives::{key_state::AuthenticatedParticipantId, time::Timestamp}; - pub use mpc_primitives::hash::{LauncherDockerComposeHash, MpcDockerImageHash}; - /// TCB info JSON file containing measurement values. - const LAUNCHER_DOCKER_COMPOSE_YAML_TEMPLATE: &str = "version: \'3.8\'\n\nservices:\n launcher:\n image: nearone/mpc-launcher@sha256:4065f2fce41415962be92471a4e793ff5147b00b2784617c7e8098be2761a875\n\n container_name: launcher\n\n environment:\n - DOCKER_CONTENT_TRUST=1\n - DEFAULT_IMAGE_DIGEST=sha256:{{DEFAULT_IMAGE_DIGEST_HASH}}\n\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - /var/run/dstack.sock:/var/run/dstack.sock\n - /tapp:/tapp:ro\n - shared-volume:/mnt/shared:ro\n\n security_opt:\n - no-new-privileges:true\n\n read_only: true\n\n tmpfs:\n - /tmp\n\nvolumes:\n shared-volume:\n name: shared-volume\n"; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - /// Tracks votes to add whitelisted TEE code hashes. Each participant can at any given time vote for - /// a code hash to add. - pub struct CodeHashesVotes { - pub proposal_by_account: BTreeMap< - AuthenticatedParticipantId, - MpcDockerImageHash, - >, - } - #[automatically_derived] - impl ::core::fmt::Debug for CodeHashesVotes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "CodeHashesVotes", - "proposal_by_account", - &&self.proposal_by_account, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for CodeHashesVotes { - #[inline] - fn clone(&self) -> CodeHashesVotes { - CodeHashesVotes { - proposal_by_account: ::core::clone::Clone::clone( - &self.proposal_by_account, - ), - } - } - } - #[automatically_derived] - impl ::core::default::Default for CodeHashesVotes { - #[inline] - fn default() -> CodeHashesVotes { - CodeHashesVotes { - proposal_by_account: ::core::default::Default::default(), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for CodeHashesVotes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for CodeHashesVotes { - #[inline] - fn eq(&self, other: &CodeHashesVotes) -> bool { - self.proposal_by_account == other.proposal_by_account - } - } - #[automatically_derived] - impl ::core::cmp::Eq for CodeHashesVotes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq< - BTreeMap, - >; - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for CodeHashesVotes { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.proposal_by_account, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for CodeHashesVotes { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - proposal_by_account: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for CodeHashesVotes { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "CodeHashesVotes", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "proposal_by_account", - &self.proposal_by_account, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for CodeHashesVotes { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "proposal_by_account" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"proposal_by_account" => { - _serde::__private228::Ok(__Field::__field0) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = CodeHashesVotes; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct CodeHashesVotes", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - BTreeMap, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct CodeHashesVotes with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(CodeHashesVotes { - proposal_by_account: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - BTreeMap, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "proposal_by_account", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - BTreeMap, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "proposal_by_account", - )? - } - }; - _serde::__private228::Ok(CodeHashesVotes { - proposal_by_account: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["proposal_by_account"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "CodeHashesVotes", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl CodeHashesVotes { - /// Casts a vote for the proposal and returns the total number of participants who have voted - /// for the same code hash. If the participant already voted, their previous vote is replaced. - pub fn vote( - &mut self, - proposal: MpcDockerImageHash, - participant: &AuthenticatedParticipantId, - ) -> u64 { - if self - .proposal_by_account - .insert(participant.clone(), proposal.clone()) - .is_some() - { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("removed old vote for signer"), - ); - res - }) - .as_str(), - ); - } - let total = self.count_votes(&proposal); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("total votes for proposal: {0}", total), - ); - res - }) - .as_str(), - ); - total - } - /// Counts the total number of participants who have voted for the given code hash. - fn count_votes(&self, proposal: &MpcDockerImageHash) -> u64 { - self - .proposal_by_account - .values() - .filter(|&prop| prop == proposal) - .count() as u64 - } - /// Clears all proposals. - pub fn clear_votes(&mut self) { - self.proposal_by_account.clear(); - } - } - /// An allowed Docker image configuration entry containing both the MPC image hash and its - /// corresponding launcher compose hash, along with when it was added to the allowlist. - pub struct AllowedMpcDockerImage { - pub(crate) image_hash: MpcDockerImageHash, - pub(crate) docker_compose_hash: LauncherDockerComposeHash, - pub(crate) added: Timestamp, - } - #[automatically_derived] - impl ::core::fmt::Debug for AllowedMpcDockerImage { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "AllowedMpcDockerImage", - "image_hash", - &self.image_hash, - "docker_compose_hash", - &self.docker_compose_hash, - "added", - &&self.added, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for AllowedMpcDockerImage { - #[inline] - fn clone(&self) -> AllowedMpcDockerImage { - AllowedMpcDockerImage { - image_hash: ::core::clone::Clone::clone(&self.image_hash), - docker_compose_hash: ::core::clone::Clone::clone( - &self.docker_compose_hash, - ), - added: ::core::clone::Clone::clone(&self.added), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AllowedMpcDockerImage {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AllowedMpcDockerImage { - #[inline] - fn eq(&self, other: &AllowedMpcDockerImage) -> bool { - self.image_hash == other.image_hash - && self.docker_compose_hash == other.docker_compose_hash - && self.added == other.added - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AllowedMpcDockerImage { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - impl borsh::ser::BorshSerialize for AllowedMpcDockerImage { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.image_hash, writer)?; - borsh::BorshSerialize::serialize(&self.docker_compose_hash, writer)?; - borsh::BorshSerialize::serialize(&self.added, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for AllowedMpcDockerImage { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - image_hash: borsh::BorshDeserialize::deserialize_reader(reader)?, - docker_compose_hash: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - added: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - /// Collection of whitelisted Docker code hashes that are the only ones MPC nodes are allowed to - /// run. - pub(crate) struct AllowedDockerImageHashes { - /// Whitelisted code hashes, sorted by when they were added (oldest first). Expired entries are - /// lazily cleaned up during insertions and TEE validation. - allowed_tee_proposals: Vec, - } - #[automatically_derived] - impl ::core::clone::Clone for AllowedDockerImageHashes { - #[inline] - fn clone(&self) -> AllowedDockerImageHashes { - AllowedDockerImageHashes { - allowed_tee_proposals: ::core::clone::Clone::clone( - &self.allowed_tee_proposals, - ), - } - } - } - #[automatically_derived] - impl ::core::default::Default for AllowedDockerImageHashes { - #[inline] - fn default() -> AllowedDockerImageHashes { - AllowedDockerImageHashes { - allowed_tee_proposals: ::core::default::Default::default(), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for AllowedDockerImageHashes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "AllowedDockerImageHashes", - "allowed_tee_proposals", - &&self.allowed_tee_proposals, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AllowedDockerImageHashes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AllowedDockerImageHashes { - #[inline] - fn eq(&self, other: &AllowedDockerImageHashes) -> bool { - self.allowed_tee_proposals == other.allowed_tee_proposals - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AllowedDockerImageHashes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - impl borsh::ser::BorshSerialize for AllowedDockerImageHashes { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.allowed_tee_proposals, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for AllowedDockerImageHashes { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - allowed_tee_proposals: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - impl AllowedDockerImageHashes { - /// Checks if a Docker image hash is still valid (not expired). - fn valid_entries( - &self, - tee_upgrade_deadline_duration: Duration, - ) -> Vec { - let current_time = Timestamp::now(); - let cutoff_index = self - .allowed_tee_proposals - .iter() - .rposition(|allowed_docker_image| { - let Some(grace_period_deadline) = allowed_docker_image - .added - .checked_add(tee_upgrade_deadline_duration) else { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Error: timestamp overflowed when calculating grace_period_deadline.", - ), - ); - res - }) - .as_str(), - ); - return true; - }; - grace_period_deadline < current_time - }) - .unwrap_or(0); - self.allowed_tee_proposals.get(cutoff_index..).unwrap_or(&[]).to_vec() - } - /// Removes all expired code hashes and returns the number of removed entries. - /// Ensures that at least one (the latest) proposal always remains in the whitelist. - pub fn cleanup_expired_hashes( - &mut self, - tee_upgrade_deadline_duration: Duration, - ) { - let valid_entries = self.valid_entries(tee_upgrade_deadline_duration); - self.allowed_tee_proposals = valid_entries; - } - /// Inserts a new code hash into the list after cleaning expired entries. Maintains the sorted - /// order by `added` (ascending). - pub fn insert( - &mut self, - code_hash: MpcDockerImageHash, - tee_upgrade_deadline_duration: Duration, - ) { - self.cleanup_expired_hashes(tee_upgrade_deadline_duration); - if let Some(pos) = self - .allowed_tee_proposals - .iter() - .position(|entry| entry.image_hash == code_hash) - { - self.allowed_tee_proposals.remove(pos); - } - let docker_compose_hash = Self::get_docker_compose_hash( - code_hash.clone(), - ); - let new_entry = AllowedMpcDockerImage { - image_hash: code_hash, - docker_compose_hash, - added: Timestamp::now(), - }; - let insert_index = self - .allowed_tee_proposals - .iter() - .rposition(|entry| new_entry.added < entry.added) - .unwrap_or(self.allowed_tee_proposals.len()); - self.allowed_tee_proposals.insert(insert_index, new_entry); - } - /// Returns valid hashes without cleaning expired entries (read-only). Ensures that at least - /// one proposal (the latest) is always returned. Use [`Self::cleanup_expired_hashes`] - /// explicitly when cleanup of the internal structure is needed. - pub fn get( - &self, - tee_upgrade_deadline_duration: Duration, - ) -> Vec { - self.valid_entries(tee_upgrade_deadline_duration) - } - pub fn get_docker_compose_hash( - mpc_docker_image_hash: MpcDockerImageHash, - ) -> LauncherDockerComposeHash { - let filled_yaml = LAUNCHER_DOCKER_COMPOSE_YAML_TEMPLATE - .replace( - "{{DEFAULT_IMAGE_DIGEST_HASH}}", - &mpc_docker_image_hash.as_hex(), - ); - let hash = sha256(filled_yaml.as_bytes()); - if !(hash.len() == 32) { - { - ::core::panicking::panic_fmt( - format_args!("Docker compose hash must be 32 bytes long"), - ); - } - } - let mut hash_arr = [0u8; 32]; - hash_arr.copy_from_slice(&hash); - LauncherDockerComposeHash::from(hash_arr) - } - } - } - pub mod tee_state { - use crate::{ - primitives::{ - key_state::AuthenticatedParticipantId, participants::Participants, - }, - tee::proposal::{ - AllowedDockerImageHashes, AllowedMpcDockerImage, CodeHashesVotes, - MpcDockerImageHash, - }, - TryIntoInterfaceType, - }; - use borsh::{BorshDeserialize, BorshSerialize}; - use mpc_attestation::{ - attestation::{self, Attestation, VerifiedAttestation}, - report_data::{ReportData, ReportDataV1}, - }; - use mpc_primitives::hash::LauncherDockerComposeHash; - use near_account_id::AccountId; - use near_sdk::{env, near}; - use std::{collections::BTreeMap, hash::{Hash, Hasher}}; - use std::{collections::HashSet, time::Duration}; - use utilities::AccountIdExtV1; - #[serde(crate = ":: near_sdk :: serde")] - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct NodeId { - /// Operator account - pub account_id: AccountId, - /// TLS public key, MUST BE of type Ed25519 - pub tls_public_key: near_sdk::PublicKey, - pub account_public_key: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for NodeId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "NodeId", - "account_id", - &self.account_id, - "tls_public_key", - &self.tls_public_key, - "account_public_key", - &&self.account_public_key, - ) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for NodeId { - #[inline] - fn cmp(&self, other: &NodeId) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.account_id, &other.account_id) { - ::core::cmp::Ordering::Equal => { - match ::core::cmp::Ord::cmp( - &self.tls_public_key, - &other.tls_public_key, - ) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp( - &self.account_public_key, - &other.account_public_key, - ) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for NodeId { - #[inline] - fn partial_cmp( - &self, - other: &NodeId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.account_id, - &other.account_id, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - match ::core::cmp::PartialOrd::partial_cmp( - &self.tls_public_key, - &other.tls_public_key, - ) { - ::core::option::Option::Some( - ::core::cmp::Ordering::Equal, - ) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.account_public_key, - &other.account_public_key, - ) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for NodeId { - #[inline] - fn clone(&self) -> NodeId { - NodeId { - account_id: ::core::clone::Clone::clone(&self.account_id), - tls_public_key: ::core::clone::Clone::clone(&self.tls_public_key), - account_public_key: ::core::clone::Clone::clone( - &self.account_public_key, - ), - } - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for NodeId { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.account_id, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.tls_public_key, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize( - &self.account_public_key, - writer, - )?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for NodeId { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - account_id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - tls_public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - account_public_key: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl _serde::Serialize for NodeId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "NodeId", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "account_id", - &self.account_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "tls_public_key", - &self.tls_public_key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "account_public_key", - &self.account_public_key, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for NodeId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - 2u64 => _serde::__private228::Ok(__Field::__field2), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "account_id" => _serde::__private228::Ok(__Field::__field0), - "tls_public_key" => { - _serde::__private228::Ok(__Field::__field1) - } - "account_public_key" => { - _serde::__private228::Ok(__Field::__field2) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"account_id" => _serde::__private228::Ok(__Field::__field0), - b"tls_public_key" => { - _serde::__private228::Ok(__Field::__field1) - } - b"account_public_key" => { - _serde::__private228::Ok(__Field::__field2) - } - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = NodeId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct NodeId", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - AccountId, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct NodeId with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - near_sdk::PublicKey, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct NodeId with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct NodeId with 3 elements", - ), - ); - } - }; - _serde::__private228::Ok(NodeId { - account_id: __field0, - tls_public_key: __field1, - account_public_key: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - near_sdk::PublicKey, - > = _serde::__private228::None; - let mut __field2: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "account_id", - ), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "tls_public_key", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - near_sdk::PublicKey, - >(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private228::Option::is_some(&__field2) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "account_public_key", - ), - ); - } - __field2 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("account_id")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("tls_public_key")? - } - }; - let __field2 = match __field2 { - _serde::__private228::Some(__field2) => __field2, - _serde::__private228::None => { - _serde::__private228::de::missing_field( - "account_public_key", - )? - } - }; - _serde::__private228::Ok(NodeId { - account_id: __field0, - tls_public_key: __field1, - account_public_key: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "account_id", - "tls_public_key", - "account_public_key", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "NodeId", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl PartialEq for NodeId { - fn eq(&self, other: &Self) -> bool { - self.account_id == other.account_id - && self.tls_public_key == other.tls_public_key - } - } - impl Eq for NodeId {} - impl Hash for NodeId { - fn hash(&self, state: &mut H) { - self.account_id.hash(state); - self.tls_public_key.hash(state); - } - } - pub enum TeeQuoteStatus { - /// TEE quote and Docker image verification both passed successfully. - /// The participant is considered to have a valid, verified TEE status. - Valid, - /// TEE verification failed - either the quote verification failed, - /// the Docker image verification failed, or both validations failed. - /// The participant should not be trusted for TEE-dependent operations. - Invalid(String), - } - #[automatically_derived] - impl ::core::fmt::Debug for TeeQuoteStatus { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TeeQuoteStatus::Valid => { - ::core::fmt::Formatter::write_str(f, "Valid") - } - TeeQuoteStatus::Invalid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Invalid", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for TeeQuoteStatus { - #[inline] - fn clone(&self) -> TeeQuoteStatus { - match self { - TeeQuoteStatus::Valid => TeeQuoteStatus::Valid, - TeeQuoteStatus::Invalid(__self_0) => { - TeeQuoteStatus::Invalid(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TeeQuoteStatus {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TeeQuoteStatus { - #[inline] - fn eq(&self, other: &TeeQuoteStatus) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - ( - TeeQuoteStatus::Invalid(__self_0), - TeeQuoteStatus::Invalid(__arg1_0), - ) => __self_0 == __arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TeeQuoteStatus { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - pub(crate) enum AttestationSubmissionError { - #[error("the submitted attestation failed verification, reason: {:?}", .0)] - InvalidAttestation(#[from] attestation::VerificationError), - #[error("the submitted attestation's TLS key is not a valid ED25519 key")] - InvalidTlsKey, - } - #[automatically_derived] - impl ::core::fmt::Debug for AttestationSubmissionError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - AttestationSubmissionError::InvalidAttestation(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InvalidAttestation", - &__self_0, - ) - } - AttestationSubmissionError::InvalidTlsKey => { - ::core::fmt::Formatter::write_str(f, "InvalidTlsKey") - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for AttestationSubmissionError { - #[inline] - fn clone(&self) -> AttestationSubmissionError { - match self { - AttestationSubmissionError::InvalidAttestation(__self_0) => { - AttestationSubmissionError::InvalidAttestation( - ::core::clone::Clone::clone(__self_0), - ) - } - AttestationSubmissionError::InvalidTlsKey => { - AttestationSubmissionError::InvalidTlsKey - } - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::thiserror::__private17::Error for AttestationSubmissionError { - fn source( - &self, - ) -> ::core::option::Option< - &(dyn ::thiserror::__private17::Error + 'static), - > { - use ::thiserror::__private17::AsDynError as _; - #[allow(deprecated)] - match self { - AttestationSubmissionError::InvalidAttestation { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - AttestationSubmissionError::InvalidTlsKey { .. } => { - ::core::option::Option::None - } - } - } - } - #[allow(unused_qualifications)] - #[automatically_derived] - impl ::core::fmt::Display for AttestationSubmissionError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - AttestationSubmissionError::InvalidAttestation(_0) => { - __formatter - .write_fmt( - format_args!( - "the submitted attestation failed verification, reason: {0:?}", - _0, - ), - ) - } - AttestationSubmissionError::InvalidTlsKey {} => { - __formatter - .write_str( - "the submitted attestation's TLS key is not a valid ED25519 key", - ) - } - } - } - } - #[allow( - deprecated, - unused_qualifications, - clippy::elidable_lifetime_names, - clippy::needless_lifetimes, - )] - #[automatically_derived] - impl ::core::convert::From - for AttestationSubmissionError { - fn from(source: attestation::VerificationError) -> Self { - AttestationSubmissionError::InvalidAttestation { - 0: source, - } - } - } - pub(crate) enum ParticipantInsertion { - NewlyInsertedParticipant, - UpdatedExistingParticipant, - } - #[automatically_derived] - impl ::core::fmt::Debug for ParticipantInsertion { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - ParticipantInsertion::NewlyInsertedParticipant => { - "NewlyInsertedParticipant" - } - ParticipantInsertion::UpdatedExistingParticipant => { - "UpdatedExistingParticipant" - } - }, - ) - } - } - pub enum TeeValidationResult { - /// All participants are valid - Full, - /// Only a subset of the participants have a valid attestation. - Partial { participants_with_valid_attestation: Participants }, - } - #[automatically_derived] - impl ::core::fmt::Debug for TeeValidationResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TeeValidationResult::Full => { - ::core::fmt::Formatter::write_str(f, "Full") - } - TeeValidationResult::Partial { - participants_with_valid_attestation: __self_0, - } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Partial", - "participants_with_valid_attestation", - &__self_0, - ) - } - } - } - } - pub(crate) struct NodeAttestation { - pub(crate) node_id: NodeId, - pub(crate) verified_attestation: VerifiedAttestation, - } - #[automatically_derived] - impl ::core::fmt::Debug for NodeAttestation { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "NodeAttestation", - "node_id", - &self.node_id, - "verified_attestation", - &&self.verified_attestation, - ) - } - } - impl borsh::ser::BorshSerialize for NodeAttestation { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.node_id, writer)?; - borsh::BorshSerialize::serialize(&self.verified_attestation, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for NodeAttestation { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - node_id: borsh::BorshDeserialize::deserialize_reader(reader)?, - verified_attestation: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - pub struct TeeState { - pub(crate) allowed_docker_image_hashes: AllowedDockerImageHashes, - pub(crate) allowed_launcher_compose_hashes: Vec, - pub(crate) votes: CodeHashesVotes, - /// Mapping of TLS public key of a participant to its [`NodeAttestation`]. - /// Attestations are stored for any valid participant that has submitted one, not - /// just for the currently active participants. - pub(crate) stored_attestations: BTreeMap< - near_sdk::PublicKey, - NodeAttestation, - >, - } - #[automatically_derived] - impl ::core::default::Default for TeeState { - #[inline] - fn default() -> TeeState { - TeeState { - allowed_docker_image_hashes: ::core::default::Default::default(), - allowed_launcher_compose_hashes: ::core::default::Default::default(), - votes: ::core::default::Default::default(), - stored_attestations: ::core::default::Default::default(), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TeeState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "TeeState", - "allowed_docker_image_hashes", - &self.allowed_docker_image_hashes, - "allowed_launcher_compose_hashes", - &self.allowed_launcher_compose_hashes, - "votes", - &self.votes, - "stored_attestations", - &&self.stored_attestations, - ) - } - } - impl borsh::ser::BorshSerialize for TeeState { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize( - &self.allowed_docker_image_hashes, - writer, - )?; - borsh::BorshSerialize::serialize( - &self.allowed_launcher_compose_hashes, - writer, - )?; - borsh::BorshSerialize::serialize(&self.votes, writer)?; - borsh::BorshSerialize::serialize(&self.stored_attestations, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for TeeState { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - allowed_docker_image_hashes: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - allowed_launcher_compose_hashes: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - votes: borsh::BorshDeserialize::deserialize_reader(reader)?, - stored_attestations: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - impl TeeState { - /// Creates a [`TeeState`] with an initial set of participants that will receive a valid mocked attestation. - pub(crate) fn with_mocked_participant_attestations( - participants: &Participants, - ) -> Self { - let mut participants_attestations = BTreeMap::new(); - participants - .participants() - .iter() - .for_each(|(account_id, _, participant_info)| { - let node_id = NodeId { - account_id: account_id.clone(), - tls_public_key: participant_info.sign_pk.clone(), - account_public_key: None, - }; - participants_attestations - .insert( - participant_info.sign_pk.clone(), - NodeAttestation { - node_id, - verified_attestation: VerifiedAttestation::Mock( - attestation::MockAttestation::Valid, - ), - }, - ); - }); - Self { - stored_attestations: participants_attestations, - ..Default::default() - } - } - fn current_time_seconds() -> u64 { - let current_time_milliseconds = env::block_timestamp_ms(); - current_time_milliseconds / 1_000 - } - /// Adds a participant attestation for the given node iff the attestation succeeds verification. - pub(crate) fn add_participant( - &mut self, - node_id: NodeId, - attestation: Attestation, - tee_upgrade_deadline_duration: Duration, - ) -> Result { - let tls_public_key = node_id - .tls_public_key - .clone() - .try_into_dto_type() - .map_err(|_| AttestationSubmissionError::InvalidTlsKey)?; - let account_public_key = match node_id.account_public_key.clone() { - Some(pk) => pk.try_into_dto_type().ok(), - None => None, - }; - let account_key_bytes = match account_public_key { - Some(ref pk) => *pk.as_bytes(), - None => [0u8; 32], - }; - let expected_report_data: ReportData = ReportDataV1::new( - *tls_public_key.as_bytes(), - account_key_bytes, - ) - .into(); - let verified_attestation = attestation - .verify( - expected_report_data.into(), - Self::current_time_seconds(), - &self - .get_allowed_mpc_docker_image_hashes( - tee_upgrade_deadline_duration, - ), - &self.allowed_launcher_compose_hashes, - )?; - let tls_pk = node_id.tls_public_key.clone(); - let insertion = self - .stored_attestations - .insert( - tls_pk, - NodeAttestation { - node_id, - verified_attestation, - }, - ); - Ok( - match insertion { - Some(_previous_attestation) => { - ParticipantInsertion::UpdatedExistingParticipant - } - None => ParticipantInsertion::NewlyInsertedParticipant, - }, - ) - } - /// reverifies stored participant attestations. - pub(crate) fn reverify_participants( - &self, - node_id: &NodeId, - tee_upgrade_deadline_duration: Duration, - ) -> TeeQuoteStatus { - let allowed_mpc_docker_image_hashes = self - .get_allowed_mpc_docker_image_hashes(tee_upgrade_deadline_duration); - let allowed_launcher_compose_hashes = &self - .allowed_launcher_compose_hashes; - let participant_attestation = self - .stored_attestations - .get(&node_id.tls_public_key); - let Some(participant_attestation) = participant_attestation else { - return TeeQuoteStatus::Invalid( - "participant has no attestation".to_string(), - ); - }; - let time_stamp_seconds = Self::current_time_seconds(); - match participant_attestation - .verified_attestation - .re_verify( - time_stamp_seconds, - &allowed_mpc_docker_image_hashes, - allowed_launcher_compose_hashes, - ) - { - Ok(()) => TeeQuoteStatus::Valid, - Err(err) => TeeQuoteStatus::Invalid(err.to_string()), - } - } - /// reverifies stored participant attestations and removes any participant attestation - /// from the internal state that fails reverifications. Reverification can fail for example - /// the MPC image hash the attestation was tied to is no longer allowed, or due to certificate - /// expiries. - pub fn reverify_and_cleanup_participants( - &mut self, - participants: &Participants, - tee_upgrade_deadline_duration: Duration, - ) -> TeeValidationResult { - self.allowed_docker_image_hashes - .cleanup_expired_hashes(tee_upgrade_deadline_duration); - let participants_with_valid_attestation: Vec<_> = participants - .participants() - .iter() - .filter(|(account_id, _, participant_info)| { - let tls_public_key = participant_info.sign_pk.clone(); - let maybe_node = self.find_node_id_by_tls_key(&tls_public_key); - let node_id = NodeId { - account_id: account_id.clone(), - tls_public_key: tls_public_key.clone(), - account_public_key: maybe_node - .and_then(|n| n.account_public_key.clone()), - }; - let tee_status = self - .reverify_participants( - &node_id, - tee_upgrade_deadline_duration, - ); - match tee_status { - TeeQuoteStatus::Valid => true, - _ => false, - } - }) - .cloned() - .collect(); - if participants_with_valid_attestation.len() != participants.len() { - let participants_with_valid_attestation = Participants::init( - participants.next_id(), - participants_with_valid_attestation, - ); - TeeValidationResult::Partial { - participants_with_valid_attestation, - } - } else { - TeeValidationResult::Full - } - } - pub fn vote( - &mut self, - code_hash: MpcDockerImageHash, - participant: &AuthenticatedParticipantId, - ) -> u64 { - self.votes.vote(code_hash.clone(), participant) - } - pub fn get_allowed_mpc_docker_image_hashes( - &self, - tee_upgrade_deadline_duration: Duration, - ) -> Vec { - self.get_allowed_mpc_docker_images(tee_upgrade_deadline_duration) - .into_iter() - .map(|entry| entry.image_hash) - .collect() - } - pub fn get_allowed_mpc_docker_images( - &self, - tee_upgrade_deadline_duration: Duration, - ) -> Vec { - self.allowed_docker_image_hashes.get(tee_upgrade_deadline_duration) - } - pub fn whitelist_tee_proposal( - &mut self, - tee_proposal: MpcDockerImageHash, - tee_upgrade_deadline_duration: Duration, - ) { - self.votes.clear_votes(); - self.allowed_launcher_compose_hashes - .push( - AllowedDockerImageHashes::get_docker_compose_hash( - tee_proposal.clone(), - ), - ); - self.allowed_docker_image_hashes - .insert(tee_proposal, tee_upgrade_deadline_duration); - } - /// Removes TEE information for nodes that are not in the provided participants list. - /// Used to clean up storage after a resharing concludes. - pub fn clean_non_participants(&mut self, participants: &Participants) { - let active_tls_keys: HashSet<&near_sdk::PublicKey> = participants - .participants() - .iter() - .map(|(_, _, p_info)| &p_info.sign_pk) - .collect(); - let stale_keys: Vec = self - .stored_attestations - .keys() - .filter(|tls_pk| !active_tls_keys.contains(*tls_pk)) - .cloned() - .collect(); - for tls_pk in stale_keys { - self.stored_attestations.remove(&tls_pk); - } - } - /// Returns the list of accounts that currently have TEE attestations stored. - /// Note: This may include accounts that are no longer active protocol participants. - pub fn get_tee_accounts(&self) -> Vec { - self.stored_attestations - .values() - .map(|node_attestation| node_attestation.node_id.clone()) - .collect() - } - /// Find a NodeId by its TLS public key. - pub fn find_node_id_by_tls_key( - &self, - tls_public_key: &near_sdk::PublicKey, - ) -> Option { - self.stored_attestations - .get(tls_public_key) - .map(|node_attestation| node_attestation.node_id.clone()) - } - /// Returns Ok(()) if the caller has at least one participant entry - /// whose TLS key matches an attested node belonging to the caller account. - /// - /// Handles multiple participants per account and supports legacy mock nodes. - pub(crate) fn is_caller_an_attested_participant( - &self, - participants: &Participants, - ) -> Result<(), AttestationCheckError> { - let signer_pk = env::signer_account_pk(); - let signer_id = env::signer_account_id().as_v2_account_id(); - let info = participants - .info(&signer_id) - .ok_or(AttestationCheckError::CallerNotParticipant)?; - let attestation = self - .stored_attestations - .get(&info.sign_pk) - .ok_or(AttestationCheckError::AttestationNotFound)?; - if attestation.node_id.account_id != signer_id { - return Err(AttestationCheckError::AttestationOwnerMismatch); - } - if let Some(node_pk) = &attestation.node_id.account_public_key { - if node_pk != &signer_pk { - return Err(AttestationCheckError::AttestationKeyMismatch); - } - } - Ok(()) - } - } - pub(crate) enum AttestationCheckError { - CallerNotParticipant, - AttestationNotFound, - AttestationOwnerMismatch, - AttestationKeyMismatch, - } - #[automatically_derived] - impl ::core::fmt::Debug for AttestationCheckError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - AttestationCheckError::CallerNotParticipant => { - "CallerNotParticipant" - } - AttestationCheckError::AttestationNotFound => { - "AttestationNotFound" - } - AttestationCheckError::AttestationOwnerMismatch => { - "AttestationOwnerMismatch" - } - AttestationCheckError::AttestationKeyMismatch => { - "AttestationKeyMismatch" - } - }, - ) - } - } - } -} -pub mod update { - use std::collections::BTreeMap; - use std::hash::Hash; - use crate::{ - dto_mapping::IntoInterfaceType, errors::{ConversionError, Error}, - primitives::participants::Participants, storage_keys::StorageKey, - }; - use borsh::{self, BorshDeserialize, BorshSerialize}; - use contract_interface::types::UpdateHash; - use derive_more::Deref; - use near_account_id::AccountId; - use near_sdk::{ - env, near, serde::{Deserialize, Serialize}, - store::IterableMap, Gas, NearToken, Promise, - }; - pub struct UpdateId(pub(crate) u64); - #[automatically_derived] - impl ::core::marker::Copy for UpdateId {} - #[automatically_derived] - impl ::core::clone::Clone for UpdateId { - #[inline] - fn clone(&self) -> UpdateId { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::default::Default for UpdateId { - #[inline] - fn default() -> UpdateId { - UpdateId(::core::default::Default::default()) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for UpdateId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "UpdateId", &&self.0) - } - } - impl borsh::de::BorshDeserialize for UpdateId { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self(borsh::BorshDeserialize::deserialize_reader(reader)?)) - } - } - impl borsh::ser::BorshSerialize for UpdateId { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.0, writer)?; - Ok(()) - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for UpdateId { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "UpdateId", - &self.0, - ) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for UpdateId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = UpdateId; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "tuple struct UpdateId", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private228::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: u64 = ::deserialize( - __e, - )?; - _serde::__private228::Ok(UpdateId(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct UpdateId with 1 element", - ), - ); - } - }; - _serde::__private228::Ok(UpdateId(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "UpdateId", - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for UpdateId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for UpdateId { - #[inline] - fn eq(&self, other: &UpdateId) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for UpdateId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for UpdateId { - #[inline] - fn partial_cmp( - &self, - other: &UpdateId, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for UpdateId { - #[inline] - fn cmp(&self, other: &UpdateId) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::hash::Hash for UpdateId { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[allow(unreachable_code)] - #[automatically_derived] - impl derive_more::with_trait::Deref for UpdateId { - type Target = u64; - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl UpdateId { - pub fn generate(&mut self) -> Self { - let id = self.0; - self.0 += 1; - Self(id) - } - } - impl From for UpdateId { - fn from(id: u64) -> Self { - Self(id) - } - } - pub enum Update { - Contract(Vec), - Config(contract_interface::types::Config), - } - #[automatically_derived] - impl ::core::clone::Clone for Update { - #[inline] - fn clone(&self) -> Update { - match self { - Update::Contract(__self_0) => { - Update::Contract(::core::clone::Clone::clone(__self_0)) - } - Update::Config(__self_0) => { - Update::Config(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Update { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Update::Contract(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Contract", - &__self_0, - ) - } - Update::Config(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Config", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Update {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Update { - #[inline] - fn eq(&self, other: &Update) -> bool { - let __self_discr = ::core::intrinsics::discriminant_value(self); - let __arg1_discr = ::core::intrinsics::discriminant_value(other); - __self_discr == __arg1_discr - && match (self, other) { - (Update::Contract(__self_0), Update::Contract(__arg1_0)) => { - __self_0 == __arg1_0 - } - (Update::Config(__self_0), Update::Config(__arg1_0)) => { - __self_0 == __arg1_0 - } - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Update { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - Update::Contract(ref __field0) => { - _serde::Serializer::serialize_newtype_variant( - __serializer, - "Update", - 0u32, - "Contract", - __field0, - ) - } - Update::Config(ref __field0) => { - _serde::Serializer::serialize_newtype_variant( - __serializer, - "Update", - 1u32, - "Config", - __field0, - ) - } - } - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Update { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => { - _serde::__private228::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "Contract" => _serde::__private228::Ok(__Field::__field0), - "Config" => _serde::__private228::Ok(__Field::__field1), - _ => { - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"Contract" => _serde::__private228::Ok(__Field::__field0), - b"Config" => _serde::__private228::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private228::from_utf8_lossy( - __value, - ); - _serde::__private228::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Update; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "enum Update", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::__private228::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Vec, - >(__variant), - Update::Contract, - ) - } - (__Field::__field1, __variant) => { - _serde::__private228::Result::map( - _serde::de::VariantAccess::newtype_variant::< - contract_interface::types::Config, - >(__variant), - Update::Config, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &["Contract", "Config"]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "Update", - VARIANTS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl borsh::ser::BorshSerialize for Update { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - let variant_idx: u8 = match self { - Update::Contract(..) => 0u8, - Update::Config(..) => 1u8, - }; - writer.write_all(&variant_idx.to_le_bytes())?; - match self { - Update::Contract(id0) => { - borsh::BorshSerialize::serialize(id0, writer)?; - } - Update::Config(id0) => { - borsh::BorshSerialize::serialize(id0, writer)?; - } - } - Ok(()) - } - } - impl borsh::de::BorshDeserialize for Update { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - let tag = ::deserialize_reader(reader)?; - ::deserialize_variant(reader, tag) - } - } - impl borsh::de::EnumExt for Update { - fn deserialize_variant<__R: borsh::io::Read>( - reader: &mut __R, - variant_tag: u8, - ) -> ::core::result::Result { - let mut return_value = if variant_tag == 0u8 { - Update::Contract(borsh::BorshDeserialize::deserialize_reader(reader)?) - } else if variant_tag == 1u8 { - Update::Config(borsh::BorshDeserialize::deserialize_reader(reader)?) - } else { - return Err( - borsh::io::Error::new( - borsh::io::ErrorKind::InvalidData, - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Unexpected variant tag: {0:?}", variant_tag), - ); - res - }), - ), - ) - }; - Ok(return_value) - } - } - pub struct ProposeUpdateArgs { - pub code: Option>, - pub config: Option, - } - #[automatically_derived] - impl ::core::clone::Clone for ProposeUpdateArgs { - #[inline] - fn clone(&self) -> ProposeUpdateArgs { - ProposeUpdateArgs { - code: ::core::clone::Clone::clone(&self.code), - config: ::core::clone::Clone::clone(&self.config), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ProposeUpdateArgs { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "ProposeUpdateArgs", - "code", - &self.code, - "config", - &&self.config, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ProposeUpdateArgs {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ProposeUpdateArgs { - #[inline] - fn eq(&self, other: &ProposeUpdateArgs) -> bool { - self.code == other.code && self.config == other.config - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ProposeUpdateArgs { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "ProposeUpdateArgs", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "code", - &self.code, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "config", - &self.config, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ProposeUpdateArgs { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "code" => _serde::__private228::Ok(__Field::__field0), - "config" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"code" => _serde::__private228::Ok(__Field::__field0), - b"config" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ProposeUpdateArgs; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct ProposeUpdateArgs", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Option>, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ProposeUpdateArgs with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct ProposeUpdateArgs with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(ProposeUpdateArgs { - code: __field0, - config: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option< - Option>, - > = _serde::__private228::None; - let mut __field1: _serde::__private228::Option< - Option, - > = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("code"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option>, - >(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("config"), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("code")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("config")? - } - }; - _serde::__private228::Ok(ProposeUpdateArgs { - code: __field0, - config: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["code", "config"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ProposeUpdateArgs", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl borsh::ser::BorshSerialize for ProposeUpdateArgs { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.code, writer)?; - borsh::BorshSerialize::serialize(&self.config, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for ProposeUpdateArgs { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - code: borsh::BorshDeserialize::deserialize_reader(reader)?, - config: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - impl TryFrom for Update { - type Error = Error; - fn try_from(value: ProposeUpdateArgs) -> Result { - let ProposeUpdateArgs { code, config } = value; - let update = match (code, config) { - (Some(contract), None) => Update::Contract(contract), - (None, Some(config)) => Update::Config(config), - (Some(_), Some(_)) => { - return Err( - ConversionError::DataConversion - .message( - "Code and config updates are not allowed at the same time", - ), - ); - } - _ => { - return Err( - ConversionError::DataConversion - .message( - "Expected either code or config update, received none of them", - ), - ); - } - }; - Ok(update) - } - } - pub(crate) struct UpdateEntry { - pub(super) update: Update, - pub(super) bytes_used: u128, - } - #[automatically_derived] - impl ::core::clone::Clone for UpdateEntry { - #[inline] - fn clone(&self) -> UpdateEntry { - UpdateEntry { - update: ::core::clone::Clone::clone(&self.update), - bytes_used: ::core::clone::Clone::clone(&self.bytes_used), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for UpdateEntry { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "UpdateEntry", - "update", - &self.update, - "bytes_used", - &&self.bytes_used, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for UpdateEntry {} - #[automatically_derived] - impl ::core::cmp::PartialEq for UpdateEntry { - #[inline] - fn eq(&self, other: &UpdateEntry) -> bool { - self.update == other.update && self.bytes_used == other.bytes_used - } - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for UpdateEntry { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "UpdateEntry", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "update", - &self.update, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "bytes_used", - &self.bytes_used, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for UpdateEntry { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private228::Ok(__Field::__field0), - 1u64 => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - "update" => _serde::__private228::Ok(__Field::__field0), - "bytes_used" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private228::Result - where - __E: _serde::de::Error, - { - match __value { - b"update" => _serde::__private228::Ok(__Field::__field0), - b"bytes_used" => _serde::__private228::Ok(__Field::__field1), - _ => _serde::__private228::Ok(__Field::__ignore), - } - } - } - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private228::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private228::PhantomData, - lifetime: _serde::__private228::PhantomData<&'de ()>, - } - #[automatically_derived] - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = UpdateEntry; - fn expecting( - &self, - __formatter: &mut _serde::__private228::Formatter, - ) -> _serde::__private228::fmt::Result { - _serde::__private228::Formatter::write_str( - __formatter, - "struct UpdateEntry", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Update, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct UpdateEntry with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - u128, - >(&mut __seq)? { - _serde::__private228::Some(__value) => __value, - _serde::__private228::None => { - return _serde::__private228::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct UpdateEntry with 2 elements", - ), - ); - } - }; - _serde::__private228::Ok(UpdateEntry { - update: __field0, - bytes_used: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private228::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private228::Option = _serde::__private228::None; - let mut __field1: _serde::__private228::Option = _serde::__private228::None; - while let _serde::__private228::Some(__key) = _serde::de::MapAccess::next_key::< - __Field, - >(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private228::Option::is_some(&__field0) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field("update"), - ); - } - __field0 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private228::Option::is_some(&__field1) { - return _serde::__private228::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "bytes_used", - ), - ); - } - __field1 = _serde::__private228::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private228::Some(__field0) => __field0, - _serde::__private228::None => { - _serde::__private228::de::missing_field("update")? - } - }; - let __field1 = match __field1 { - _serde::__private228::Some(__field1) => __field1, - _serde::__private228::None => { - _serde::__private228::de::missing_field("bytes_used")? - } - }; - _serde::__private228::Ok(UpdateEntry { - update: __field0, - bytes_used: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["update", "bytes_used"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "UpdateEntry", - FIELDS, - __Visitor { - marker: _serde::__private228::PhantomData::, - lifetime: _serde::__private228::PhantomData, - }, - ) - } - } - }; - impl borsh::ser::BorshSerialize for UpdateEntry { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.update, writer)?; - borsh::BorshSerialize::serialize(&self.bytes_used, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for UpdateEntry { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - update: borsh::BorshDeserialize::deserialize_reader(reader)?, - bytes_used: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - pub(super) struct UpdateVotes { - pub(super) votes: BTreeMap, - pub(super) updates: BTreeMap, - } - #[automatically_derived] - impl ::core::clone::Clone for UpdateVotes { - #[inline] - fn clone(&self) -> UpdateVotes { - UpdateVotes { - votes: ::core::clone::Clone::clone(&self.votes), - updates: ::core::clone::Clone::clone(&self.updates), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for UpdateVotes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "UpdateVotes", - "votes", - &self.votes, - "updates", - &&self.updates, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for UpdateVotes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for UpdateVotes { - #[inline] - fn eq(&self, other: &UpdateVotes) -> bool { - self.votes == other.votes && self.updates == other.updates - } - } - #[borsh(crate = ":: near_sdk :: borsh")] - pub struct ProposedUpdates { - pub(super) vote_by_participant: IterableMap, - pub(super) entries: IterableMap, - pub(super) id: UpdateId, - } - #[automatically_derived] - impl ::core::fmt::Debug for ProposedUpdates { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "ProposedUpdates", - "vote_by_participant", - &self.vote_by_participant, - "entries", - &self.entries, - "id", - &&self.id, - ) - } - } - impl ::near_sdk::borsh::ser::BorshSerialize for ProposedUpdates { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize( - &self.vote_by_participant, - writer, - )?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.entries, writer)?; - ::near_sdk::borsh::BorshSerialize::serialize(&self.id, writer)?; - Ok(()) - } - } - impl ::near_sdk::borsh::de::BorshDeserialize for ProposedUpdates { - fn deserialize_reader<__R: ::near_sdk::borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - vote_by_participant: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - entries: ::near_sdk::borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - id: ::near_sdk::borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - impl Default for ProposedUpdates { - fn default() -> Self { - Self { - vote_by_participant: IterableMap::new( - StorageKey::ProposedUpdatesVotesV2, - ), - entries: IterableMap::new(StorageKey::ProposedUpdatesEntriesV2), - id: UpdateId::default(), - } - } - } - impl ProposedUpdates { - pub fn required_deposit(update: &Update) -> NearToken { - required_deposit(bytes_used(update)) - } - /// Propose an update given the new contract code and/or config. - pub fn propose(&mut self, update: Update) -> UpdateId { - let bytes_used = bytes_used(&update); - let id = self.id.generate(); - self.entries.insert(id, UpdateEntry { update, bytes_used }); - id - } - /// Records a vote by [`AccountId`] for the update with the given [`UpdateId`]. - /// - /// If the voter has already voted for a different update, that vote is automatically removed - /// (each participant can only vote for one update at a time). - /// - /// Returns `None` if the [`UpdateId`] doesn't exist. - pub fn vote(&mut self, id: &UpdateId, voter: AccountId) -> Option<()> { - self.remove_vote(&voter); - if !self.entries.contains_key(id) { - env::log_str( - &::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("no update with id {0:?} exists", id), - ); - res - }), - ); - return None; - } - self.vote_by_participant.insert(voter.clone(), *id); - Some(()) - } - pub fn do_update(&mut self, id: &UpdateId, gas: Gas) -> Option { - let entry = self.entries.remove(id)?; - self.entries.clear(); - self.vote_by_participant.clear(); - let mut promise = Promise::new(env::current_account_id()); - match entry.update { - Update::Contract(code) => { - promise = promise - .deploy_contract(code) - .function_call( - "migrate", - Vec::new(), - NearToken::from_near(0), - gas, - ); - } - Update::Config(config) => { - let new_config_gas_value = Gas::from_tgas( - config.contract_upgrade_deposit_tera_gas, - ); - promise = promise - .function_call( - "update_config", - serde_json::to_vec(&(&config,)).unwrap(), - NearToken::from_near(0), - new_config_gas_value, - ); - } - } - Some(promise) - } - /// Removes the vote for [`AccountId`]. - pub fn remove_vote(&mut self, voter: &AccountId) { - self.vote_by_participant.remove(voter); - } - /// Removes votes from the specified accounts. - pub fn remove_votes(&mut self, accounts_to_remove: &[AccountId]) { - accounts_to_remove.iter().for_each(|account| self.remove_vote(account)); - } - /// Removes votes from accounts that are not participants. - pub fn remove_non_participant_votes(&mut self, participants: &Participants) { - let non_participants: Vec = self - .vote_by_participant - .keys() - .filter(|voter| !participants.is_participant(voter)) - .cloned() - .collect(); - self.remove_votes(&non_participants); - } - pub(super) fn all_updates(&self) -> UpdateVotes { - let votes = self - .vote_by_participant - .iter() - .map(|(account, update_id)| (account.clone(), *update_id)) - .collect(); - let updates = self - .entries - .iter() - .map(|(update_id, entry)| (*update_id, (&entry.update).into_dto_type())) - .collect(); - UpdateVotes { votes, updates } - } - } - fn bytes_used(update: &Update) -> u128 { - let mut bytes_used = std::mem::size_of::() as u128; - bytes_used += 128 * std::mem::size_of::() as u128; - match update { - Update::Contract(code) => { - bytes_used += code.len() as u128; - } - Update::Config(config) => { - let bytes = serde_json::to_vec(&config).unwrap(); - bytes_used += bytes.len() as u128; - } - } - bytes_used - } - fn required_deposit(bytes_used: u128) -> NearToken { - env::storage_byte_cost().saturating_mul(bytes_used) - } -} -pub mod v3_0_2_state { - //! ## Overview - //! This module stores the previous contract state—the one you want to migrate from. - //! The goal is to describe the data layout _exactly_ as it existed before. - //! - //! ## Guideline - //! In theory, you could copy-paste every struct from the specific commit you're migrating from. - //! However, this approach (a) requires manual effort from a developer and (b) increases the binary size. - //! A better approach: only copy the structures that have changed and import the rest from the existing codebase. - use borsh::{BorshDeserialize, BorshSerialize}; - use mpc_attestation::attestation::Attestation; - use mpc_primitives::hash::LauncherDockerComposeHash; - use near_account_id::AccountId; - use near_sdk::{env, store::{IterableMap, LookupMap}}; - use std::collections::HashSet; - use crate::{ - node_migrations::NodeMigrations, - primitives::{ckd::CKDRequest, signature::{SignatureRequest, YieldIndex}}, - state::ProtocolContractState, - tee::{ - proposal::{AllowedDockerImageHashes, CodeHashesVotes}, - tee_state::NodeId, - }, - update::{Update, UpdateId}, - }; - struct Config { - /// If a key event attempt has not successfully completed within this many blocks, - /// it is considered failed. - pub key_event_timeout_blocks: u64, - /// The grace period duration for expiry of old mpc image hashes once a new one is added. - pub tee_upgrade_deadline_duration_seconds: u64, - } - #[automatically_derived] - impl ::core::fmt::Debug for Config { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Config", - "key_event_timeout_blocks", - &self.key_event_timeout_blocks, - "tee_upgrade_deadline_duration_seconds", - &&self.tee_upgrade_deadline_duration_seconds, - ) - } - } - impl borsh::ser::BorshSerialize for Config { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.key_event_timeout_blocks, writer)?; - borsh::BorshSerialize::serialize( - &self.tee_upgrade_deadline_duration_seconds, - writer, - )?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for Config { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - key_event_timeout_blocks: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - tee_upgrade_deadline_duration_seconds: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - impl From for crate::config::Config { - fn from(value: Config) -> Self { - crate::config::Config { - key_event_timeout_blocks: value.key_event_timeout_blocks, - tee_upgrade_deadline_duration_seconds: value - .tee_upgrade_deadline_duration_seconds, - ..Default::default() - } - } - } - /// Old version of [`UpdateEntry`] that included votes. - struct UpdateEntry { - update: Update, - votes: HashSet, - bytes_used: u128, - } - #[automatically_derived] - impl ::core::clone::Clone for UpdateEntry { - #[inline] - fn clone(&self) -> UpdateEntry { - UpdateEntry { - update: ::core::clone::Clone::clone(&self.update), - votes: ::core::clone::Clone::clone(&self.votes), - bytes_used: ::core::clone::Clone::clone(&self.bytes_used), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for UpdateEntry { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "UpdateEntry", - "update", - &self.update, - "votes", - &self.votes, - "bytes_used", - &&self.bytes_used, - ) - } - } - impl borsh::ser::BorshSerialize for UpdateEntry { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.update, writer)?; - borsh::BorshSerialize::serialize(&self.votes, writer)?; - borsh::BorshSerialize::serialize(&self.bytes_used, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for UpdateEntry { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - update: borsh::BorshDeserialize::deserialize_reader(reader)?, - votes: borsh::BorshDeserialize::deserialize_reader(reader)?, - bytes_used: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - /// Old version of [`ProposedUpdates`] that used the old [`UpdateEntry`] with votes. - pub struct ProposedUpdates { - vote_by_participant: IterableMap, - entries: IterableMap, - id: UpdateId, - } - #[automatically_derived] - impl ::core::fmt::Debug for ProposedUpdates { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "ProposedUpdates", - "vote_by_participant", - &self.vote_by_participant, - "entries", - &self.entries, - "id", - &&self.id, - ) - } - } - impl borsh::ser::BorshSerialize for ProposedUpdates { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.vote_by_participant, writer)?; - borsh::BorshSerialize::serialize(&self.entries, writer)?; - borsh::BorshSerialize::serialize(&self.id, writer)?; - Ok(()) - } - } - impl borsh::de::BorshDeserialize for ProposedUpdates { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - vote_by_participant: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - entries: borsh::BorshDeserialize::deserialize_reader(reader)?, - id: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - impl From for crate::update::ProposedUpdates { - fn from(old: ProposedUpdates) -> Self { - if !old.entries.is_empty() { - { - ::core::panicking::panic_fmt( - format_args!( - "Migration error: Found {0} pending update entries. Expected empty state as do_update() clears entries.", - old.entries.len(), - ), - ); - }; - } - if !old.vote_by_participant.is_empty() { - { - ::core::panicking::panic_fmt( - format_args!( - "Migration error: Found {0} pending votes. Expected empty state as do_update() clears votes.", - old.vote_by_participant.len(), - ), - ); - }; - } - Self { - vote_by_participant: IterableMap::new( - crate::storage_keys::StorageKey::ProposedUpdatesVotesV2, - ), - entries: IterableMap::new( - crate::storage_keys::StorageKey::ProposedUpdatesEntriesV2, - ), - id: old.id, - } - } - } - struct TeeState { - _allowed_docker_image_hashes: AllowedDockerImageHashes, - _allowed_launcher_compose_hashes: Vec, - _votes: CodeHashesVotes, - participants_attestations: IterableMap< - near_sdk::PublicKey, - (NodeId, Attestation), - >, - } - #[automatically_derived] - impl ::core::fmt::Debug for TeeState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "TeeState", - "_allowed_docker_image_hashes", - &self._allowed_docker_image_hashes, - "_allowed_launcher_compose_hashes", - &self._allowed_launcher_compose_hashes, - "_votes", - &self._votes, - "participants_attestations", - &&self.participants_attestations, - ) - } - } - impl borsh::de::BorshDeserialize for TeeState { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - _allowed_docker_image_hashes: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - _allowed_launcher_compose_hashes: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - _votes: borsh::BorshDeserialize::deserialize_reader(reader)?, - participants_attestations: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - pub struct MpcContract { - protocol_state: ProtocolContractState, - pending_signature_requests: LookupMap, - pending_ckd_requests: LookupMap, - proposed_updates: ProposedUpdates, - config: Config, - tee_state: TeeState, - accept_requests: bool, - node_migrations: NodeMigrations, - } - #[automatically_derived] - impl ::core::fmt::Debug for MpcContract { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "protocol_state", - "pending_signature_requests", - "pending_ckd_requests", - "proposed_updates", - "config", - "tee_state", - "accept_requests", - "node_migrations", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.protocol_state, - &self.pending_signature_requests, - &self.pending_ckd_requests, - &self.proposed_updates, - &self.config, - &self.tee_state, - &self.accept_requests, - &&self.node_migrations, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "MpcContract", - names, - values, - ) - } - } - impl borsh::de::BorshDeserialize for MpcContract { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - protocol_state: borsh::BorshDeserialize::deserialize_reader(reader)?, - pending_signature_requests: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - pending_ckd_requests: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - proposed_updates: borsh::BorshDeserialize::deserialize_reader(reader)?, - config: borsh::BorshDeserialize::deserialize_reader(reader)?, - tee_state: borsh::BorshDeserialize::deserialize_reader(reader)?, - accept_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, - node_migrations: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - impl From for crate::MpcContract { - fn from(value: MpcContract) -> Self { - let protocol_state = value.protocol_state; - let crate::ProtocolContractState::Running(running_state) = &protocol_state - else { - env::panic_str("Contract must be in running state when migrating."); - }; - let mut previous_tee_state = value.tee_state; - let threshold_parameters = &running_state.parameters.participants(); - let tee_state = crate::TeeState::with_mocked_participant_attestations( - threshold_parameters, - ); - Self { - protocol_state, - pending_signature_requests: value.pending_signature_requests, - pending_ckd_requests: value.pending_ckd_requests, - proposed_updates: value.proposed_updates.into(), - config: value.config.into(), - tee_state, - accept_requests: value.accept_requests, - node_migrations: value.node_migrations, - } - } - } -} -pub mod v3_2_0_state { - //! ## Overview - //! This module stores the previous contract state—the one you want to migrate from. - //! The goal is to describe the data layout _exactly_ as it existed before. - //! - //! ## Guideline - //! In theory, you could copy-paste every struct from the specific commit you're migrating from. - //! However, this approach (a) requires manual effort from a developer and (b) increases the binary size. - //! A better approach: only copy the structures that have changed and import the rest from the existing codebase. - use borsh::BorshDeserialize; - use mpc_attestation::attestation::Attestation; - use mpc_primitives::hash::LauncherDockerComposeHash; - use near_sdk::{env, store::{IterableMap, LookupMap}}; - use crate::{ - node_migrations::NodeMigrations, - primitives::{ckd::CKDRequest, signature::{SignatureRequest, YieldIndex}}, - state::ProtocolContractState, - tee::{ - proposal::{AllowedDockerImageHashes, CodeHashesVotes}, - tee_state::NodeId, - }, - update::ProposedUpdates, Config, - }; - struct TeeState { - _allowed_docker_image_hashes: AllowedDockerImageHashes, - _allowed_launcher_compose_hashes: Vec, - _votes: CodeHashesVotes, - participants_attestations: IterableMap< - near_sdk::PublicKey, - (NodeId, Attestation), - >, - } - #[automatically_derived] - impl ::core::fmt::Debug for TeeState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "TeeState", - "_allowed_docker_image_hashes", - &self._allowed_docker_image_hashes, - "_allowed_launcher_compose_hashes", - &self._allowed_launcher_compose_hashes, - "_votes", - &self._votes, - "participants_attestations", - &&self.participants_attestations, - ) - } - } - impl borsh::de::BorshDeserialize for TeeState { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - _allowed_docker_image_hashes: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - _allowed_launcher_compose_hashes: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - _votes: borsh::BorshDeserialize::deserialize_reader(reader)?, - participants_attestations: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - }) - } - } - pub struct MpcContract { - protocol_state: ProtocolContractState, - pending_signature_requests: LookupMap, - pending_ckd_requests: LookupMap, - proposed_updates: ProposedUpdates, - config: Config, - tee_state: TeeState, - accept_requests: bool, - node_migrations: NodeMigrations, - } - #[automatically_derived] - impl ::core::fmt::Debug for MpcContract { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "protocol_state", - "pending_signature_requests", - "pending_ckd_requests", - "proposed_updates", - "config", - "tee_state", - "accept_requests", - "node_migrations", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.protocol_state, - &self.pending_signature_requests, - &self.pending_ckd_requests, - &self.proposed_updates, - &self.config, - &self.tee_state, - &self.accept_requests, - &&self.node_migrations, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "MpcContract", - names, - values, - ) - } - } - impl borsh::de::BorshDeserialize for MpcContract { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - protocol_state: borsh::BorshDeserialize::deserialize_reader(reader)?, - pending_signature_requests: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - pending_ckd_requests: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - proposed_updates: borsh::BorshDeserialize::deserialize_reader(reader)?, - config: borsh::BorshDeserialize::deserialize_reader(reader)?, - tee_state: borsh::BorshDeserialize::deserialize_reader(reader)?, - accept_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, - node_migrations: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } - } - impl From for crate::MpcContract { - fn from(value: MpcContract) -> Self { - let protocol_state = value.protocol_state; - let crate::ProtocolContractState::Running(running_state) = &protocol_state - else { - env::panic_str("Contract must be in running state when migrating."); - }; - let mut previous_tee_state = value.tee_state; - previous_tee_state.participants_attestations.clear(); - let threshold_parameters = &running_state.parameters.participants(); - let tee_state = crate::TeeState::with_mocked_participant_attestations( - threshold_parameters, - ); - Self { - protocol_state, - pending_signature_requests: value.pending_signature_requests, - pending_ckd_requests: value.pending_ckd_requests, - proposed_updates: value.proposed_updates.into(), - config: value.config.into(), - tee_state, - accept_requests: value.accept_requests, - node_migrations: value.node_migrations, - } - } - } -} -mod dto_mapping { - //! This module provides convenience methods to map contract interface types - //! from [`contract_interface::types`] to internal types. - //! - //! These types are mapped with the [IntoContractType] trait. We can not use [`From`] - //! and [`Into`] due to the [*orphan rule*](https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules). - use contract_interface::types as dtos; - use mpc_attestation::{ - attestation::{ - Attestation, DstackAttestation, MockAttestation, VerifiedAttestation, - }, - collateral::{Collateral, QuoteCollateralV3}, - EventLog, TcbInfo, - }; - use k256::{ - elliptic_curve::sec1::{FromEncodedPoint as _, ToEncodedPoint as _}, - EncodedPoint, - }; - use curve25519_dalek::edwards::CompressedEdwardsY; - use near_account_id::AccountId; - use near_sdk::env::sha256_array; - use crate::{ - config::Config, crypto_shared::k256_types, update::{ProposedUpdates, Update}, - }; - use crate::errors::{ConversionError, Error}; - pub(crate) trait IntoContractType { - fn into_contract_type(self) -> ContractType; - } - pub(crate) trait IntoInterfaceType { - fn into_dto_type(self) -> InterfaceType; - } - #[allow(dead_code)] - pub(crate) trait TryIntoContractType { - type Error; - fn try_into_contract_type(self) -> Result; - } - pub(crate) trait TryIntoInterfaceType { - type Error; - fn try_into_dto_type(self) -> Result; - } - impl IntoContractType for dtos::Attestation { - fn into_contract_type(self) -> Attestation { - match self { - dtos::Attestation::Dstack(dstack_attestation) => { - Attestation::Dstack(dstack_attestation.into_contract_type()) - } - dtos::Attestation::Mock(mock_attestation) => { - Attestation::Mock(mock_attestation.into_contract_type()) - } - } - } - } - impl IntoContractType for dtos::MockAttestation { - fn into_contract_type(self) -> MockAttestation { - match self { - dtos::MockAttestation::Valid => MockAttestation::Valid, - dtos::MockAttestation::Invalid => MockAttestation::Invalid, - dtos::MockAttestation::WithConstraints { - mpc_docker_image_hash, - launcher_docker_compose_hash, - expiry_timestamp_seconds, - } => { - MockAttestation::WithConstraints { - mpc_docker_image_hash: mpc_docker_image_hash.map(Into::into), - launcher_docker_compose_hash: launcher_docker_compose_hash - .map(Into::into), - expiry_timestamp_seconds, - } - } - } - } - } - impl IntoContractType for dtos::DstackAttestation { - fn into_contract_type(self) -> DstackAttestation { - let dtos::DstackAttestation { quote, collateral, tcb_info } = self; - DstackAttestation { - quote: quote.into(), - collateral: collateral.into_contract_type(), - tcb_info: tcb_info.into_contract_type(), - } - } - } - impl IntoContractType for dtos::Collateral { - fn into_contract_type(self) -> Collateral { - let dtos::Collateral { - pck_crl_issuer_chain, - root_ca_crl, - pck_crl, - tcb_info_issuer_chain, - tcb_info, - tcb_info_signature, - qe_identity_issuer_chain, - qe_identity, - qe_identity_signature, - } = self; - Collateral::from(QuoteCollateralV3 { - pck_crl_issuer_chain, - root_ca_crl, - pck_crl, - tcb_info_issuer_chain, - tcb_info, - tcb_info_signature, - qe_identity_issuer_chain, - qe_identity, - qe_identity_signature, - }) - } - } - impl IntoContractType for dtos::TcbInfo { - fn into_contract_type(self) -> TcbInfo { - let dtos::TcbInfo { - mrtd, - rtmr0, - rtmr1, - rtmr2, - rtmr3, - os_image_hash, - compose_hash, - device_id, - app_compose, - event_log, - } = self; - let event_log = event_log - .into_iter() - .map(IntoContractType::into_contract_type) - .collect(); - TcbInfo { - mrtd, - rtmr0, - rtmr1, - rtmr2, - rtmr3, - os_image_hash, - compose_hash, - device_id, - app_compose, - event_log, - } - } - } - impl IntoContractType for dtos::EventLog { - fn into_contract_type(self) -> EventLog { - let dtos::EventLog { imr, event_type, digest, event, event_payload } = self; - EventLog { - imr, - event_type, - digest, - event, - event_payload, - } - } - } - impl IntoInterfaceType for VerifiedAttestation { - fn into_dto_type(self) -> dtos::VerifiedAttestation { - match self { - VerifiedAttestation::Mock(mock_attestation) => { - dtos::VerifiedAttestation::Mock(mock_attestation.into_dto_type()) - } - VerifiedAttestation::Dstack(validated_dstack_attestation) => { - dtos::VerifiedAttestation::Dtack(dtos::VerifiedDstackAttestation { - mpc_image_hash: validated_dstack_attestation - .mpc_image_hash - .into(), - launcher_compose_hash: validated_dstack_attestation - .launcher_compose_hash - .into(), - expiry_timestamp_seconds: validated_dstack_attestation - .expiration_timestamp_seconds, - }) - } - } - } - } - impl IntoInterfaceType for MockAttestation { - fn into_dto_type(self) -> dtos::MockAttestation { - match self { - MockAttestation::Valid => dtos::MockAttestation::Valid, - MockAttestation::Invalid => dtos::MockAttestation::Invalid, - MockAttestation::WithConstraints { - mpc_docker_image_hash, - launcher_docker_compose_hash, - expiry_timestamp_seconds, - } => { - dtos::MockAttestation::WithConstraints { - mpc_docker_image_hash: mpc_docker_image_hash.map(Into::into), - launcher_docker_compose_hash: launcher_docker_compose_hash - .map(Into::into), - expiry_timestamp_seconds, - } - } - } - } - } - impl IntoInterfaceType for &k256_types::PublicKey { - fn into_dto_type(self) -> dtos::Secp256k1PublicKey { - let mut bytes = [0u8; 64]; - bytes.copy_from_slice(&self.to_encoded_point(false).to_bytes()[1..]); - dtos::Secp256k1PublicKey::from(bytes) - } - } - impl TryIntoContractType for dtos::Secp256k1PublicKey { - type Error = Error; - fn try_into_contract_type(self) -> Result { - let mut bytes = [0u8; 65]; - bytes[1..].copy_from_slice(&self.0); - bytes[0] = 0x4; - let point = EncodedPoint::from_bytes(bytes) - .map_err(|err| { - ConversionError::DataConversion - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Failed to get EncodedPoint: {0}", err), - ); - res - }), - ) - })?; - k256_types::PublicKey::from_encoded_point(&point) - .into_option() - .ok_or( - ConversionError::DataConversion - .message("Failed to convert EncodedPoint to PublicKey"), - ) - } - } - impl IntoInterfaceType for &CompressedEdwardsY { - fn into_dto_type(self) -> dtos::Ed25519PublicKey { - dtos::Ed25519PublicKey::from(self.to_bytes()) - } - } - impl TryIntoInterfaceType for &near_sdk::PublicKey { - type Error = Error; - fn try_into_dto_type(self) -> Result { - match self.curve_type() { - near_sdk::CurveType::ED25519 => { - let mut bytes = [0u8; 32]; - bytes.copy_from_slice(&self.as_bytes()[1..]); - Ok(dtos::Ed25519PublicKey::from(bytes)) - } - curve_type => { - Err( - ConversionError::DataConversion - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("Wrong curve type was used: {0:?}", curve_type), - ); - res - }), - ), - ) - } - } - } - } - impl IntoContractType for &dtos::Ed25519PublicKey { - fn into_contract_type(self) -> near_sdk::PublicKey { - near_sdk::PublicKey::from_parts(near_sdk::CurveType::ED25519, self.0.into()) - .unwrap() - } - } - impl IntoContractType for &dtos::Secp256k1PublicKey { - fn into_contract_type(self) -> near_sdk::PublicKey { - near_sdk::PublicKey::from_parts( - near_sdk::CurveType::SECP256K1, - self.0.into(), - ) - .unwrap() - } - } - impl IntoInterfaceType for &near_sdk::PublicKey { - fn into_dto_type(self) -> dtos::PublicKey { - match self.curve_type() { - near_sdk::CurveType::SECP256K1 => { - let mut bytes = [0u8; 64]; - bytes.copy_from_slice(&self.as_bytes()[1..]); - dtos::PublicKey::from(dtos::Secp256k1PublicKey::from(bytes)) - } - near_sdk::CurveType::ED25519 => { - let mut bytes = [0u8; 32]; - bytes.copy_from_slice(&self.as_bytes()[1..]); - dtos::PublicKey::from(dtos::Ed25519PublicKey::from(bytes)) - } - } - } - } - impl IntoInterfaceType for &AccountId { - fn into_dto_type(self) -> dtos::AccountId { - dtos::AccountId(self.clone().into()) - } - } - impl IntoInterfaceType for &Update { - fn into_dto_type(self) -> dtos::UpdateHash { - match self { - Update::Contract(code) => dtos::UpdateHash::Code(sha256_array(code)), - Update::Config(config) => { - dtos::UpdateHash::Config( - sha256_array( - serde_json::to_vec(config) - .expect("serde serialization must succeed"), - ), - ) - } - } - } - } - impl IntoInterfaceType for &ProposedUpdates { - fn into_dto_type(self) -> dtos::ProposedUpdates { - let all = self.all_updates(); - let votes = all - .votes - .into_iter() - .map(|(account, update_id)| (account.into_dto_type(), update_id.0)) - .collect(); - let updates = all - .updates - .into_iter() - .map(|(update_id, update)| (update_id.0, update)) - .collect(); - dtos::ProposedUpdates { - votes, - updates, - } - } - } - impl From for Config { - fn from(config_ext: contract_interface::types::InitConfig) -> Self { - let mut config = super::Config::default(); - if let Some(v) = config_ext.key_event_timeout_blocks { - config.key_event_timeout_blocks = v; - } - if let Some(v) = config_ext.tee_upgrade_deadline_duration_seconds { - config.tee_upgrade_deadline_duration_seconds = v; - } - if let Some(v) = config_ext.contract_upgrade_deposit_tera_gas { - config.contract_upgrade_deposit_tera_gas = v; - } - if let Some(v) = config_ext.sign_call_gas_attachment_requirement_tera_gas { - config.sign_call_gas_attachment_requirement_tera_gas = v; - } - if let Some(v) = config_ext.ckd_call_gas_attachment_requirement_tera_gas { - config.ckd_call_gas_attachment_requirement_tera_gas = v; - } - if let Some(v) = config_ext - .return_signature_and_clean_state_on_success_call_tera_gas - { - config.return_signature_and_clean_state_on_success_call_tera_gas = v; - } - if let Some(v) = config_ext - .return_ck_and_clean_state_on_success_call_tera_gas - { - config.return_ck_and_clean_state_on_success_call_tera_gas = v; - } - if let Some(v) = config_ext.fail_on_timeout_tera_gas { - config.fail_on_timeout_tera_gas = v; - } - if let Some(v) = config_ext.clean_tee_status_tera_gas { - config.clean_tee_status_tera_gas = v; - } - if let Some(v) = config_ext.cleanup_orphaned_node_migrations_tera_gas { - config.cleanup_orphaned_node_migrations_tera_gas = v; - } - if let Some(v) = config_ext.remove_non_participant_update_votes_tera_gas { - config.remove_non_participant_update_votes_tera_gas = v; - } - config - } - } - impl From<&Config> for contract_interface::types::Config { - fn from(value: &Config) -> Self { - contract_interface::types::Config { - key_event_timeout_blocks: value.key_event_timeout_blocks, - tee_upgrade_deadline_duration_seconds: value - .tee_upgrade_deadline_duration_seconds, - contract_upgrade_deposit_tera_gas: value - .contract_upgrade_deposit_tera_gas, - sign_call_gas_attachment_requirement_tera_gas: value - .sign_call_gas_attachment_requirement_tera_gas, - ckd_call_gas_attachment_requirement_tera_gas: value - .ckd_call_gas_attachment_requirement_tera_gas, - return_signature_and_clean_state_on_success_call_tera_gas: value - .return_signature_and_clean_state_on_success_call_tera_gas, - return_ck_and_clean_state_on_success_call_tera_gas: value - .return_ck_and_clean_state_on_success_call_tera_gas, - fail_on_timeout_tera_gas: value.fail_on_timeout_tera_gas, - clean_tee_status_tera_gas: value.clean_tee_status_tera_gas, - cleanup_orphaned_node_migrations_tera_gas: value - .cleanup_orphaned_node_migrations_tera_gas, - remove_non_participant_update_votes_tera_gas: value - .remove_non_participant_update_votes_tera_gas, - } - } - } - impl From for Config { - fn from(value: contract_interface::types::Config) -> Self { - Config { - key_event_timeout_blocks: value.key_event_timeout_blocks, - tee_upgrade_deadline_duration_seconds: value - .tee_upgrade_deadline_duration_seconds, - contract_upgrade_deposit_tera_gas: value - .contract_upgrade_deposit_tera_gas, - sign_call_gas_attachment_requirement_tera_gas: value - .sign_call_gas_attachment_requirement_tera_gas, - ckd_call_gas_attachment_requirement_tera_gas: value - .ckd_call_gas_attachment_requirement_tera_gas, - return_signature_and_clean_state_on_success_call_tera_gas: value - .return_signature_and_clean_state_on_success_call_tera_gas, - return_ck_and_clean_state_on_success_call_tera_gas: value - .return_ck_and_clean_state_on_success_call_tera_gas, - fail_on_timeout_tera_gas: value.fail_on_timeout_tera_gas, - clean_tee_status_tera_gas: value.clean_tee_status_tera_gas, - cleanup_orphaned_node_migrations_tera_gas: value - .cleanup_orphaned_node_migrations_tera_gas, - remove_non_participant_update_votes_tera_gas: value - .remove_non_participant_update_votes_tera_gas, - } - } - } -} -use std::{collections::BTreeMap, time::Duration}; -use crate::{ - crypto_shared::{near_public_key_to_affine_point, types::CKDResponse}, - dto_mapping::{IntoContractType, IntoInterfaceType, TryIntoInterfaceType}, - errors::{Error, RequestError}, - primitives::ckd::{CKDRequest, CKDRequestArgs}, - state::ContractNotInitialized, storage_keys::StorageKey, - tee::tee_state::{TeeQuoteStatus, TeeState}, - update::{ProposeUpdateArgs, ProposedUpdates, Update, UpdateId}, -}; -use borsh::{BorshDeserialize, BorshSerialize}; -use config::Config; -use contract_interface::types as dtos; -use crypto_shared::{ - derive_key_secp256k1, derive_tweak, - kdf::{check_ec_signature, derive_public_key_edwards_point_ed25519}, - types::{PublicKeyExtended, PublicKeyExtendedConversionError, SignatureResponse}, -}; -use errors::{ - DomainError, InvalidParameters, InvalidState, PublicKeyError, RespondError, TeeError, -}; -use k256::elliptic_curve::PrimeField; -use mpc_attestation::attestation::Attestation; -use mpc_primitives::hash::LauncherDockerComposeHash; -use near_account_id::AccountId; -use near_sdk::{ - env::{self, ed25519_verify}, - log, near_bindgen, state::ContractState, store::{IterableMap, LookupMap}, - CryptoHash, Gas, GasWeight, NearToken, Promise, PromiseError, PromiseOrValue, -}; -use node_migrations::{BackupServiceInfo, DestinationNodeInfo, NodeMigrations}; -use primitives::{ - domain::{DomainConfig, DomainId, DomainRegistry, SignatureScheme}, - key_state::{AuthenticatedParticipantId, EpochId, KeyEventId, Keyset}, - signature::{SignRequest, SignRequestArgs, SignatureRequest, YieldIndex}, - thresholds::{Threshold, ThresholdParameters}, -}; -use state::{running::RunningContractState, ProtocolContractState}; -use tee::{ - proposal::MpcDockerImageHash, - tee_state::{NodeId, ParticipantInsertion, TeeValidationResult}, -}; -use utilities::{AccountIdExtV1, AccountIdExtV2}; -/// Register used to receive data id from `promise_await_data`. -/// Note: This is an implementation constant, not a configurable policy value. -const DATA_ID_REGISTER: u64 = 0; -/// Minimum deposit required for sign requests -const MINIMUM_SIGN_REQUEST_DEPOSIT: NearToken = NearToken::from_yoctonear(1); -/// Minimum deposit required for CKD requests -const MINIMUM_CKD_REQUEST_DEPOSIT: NearToken = NearToken::from_yoctonear(1); -impl Default for MpcContract { - fn default() -> Self { - env::panic_str("Calling default not allowed."); - } -} -impl ContractState for MpcContract {} -pub struct MpcContract { - protocol_state: ProtocolContractState, - pending_signature_requests: LookupMap, - pending_ckd_requests: LookupMap, - proposed_updates: ProposedUpdates, - config: Config, - tee_state: TeeState, - accept_requests: bool, - node_migrations: NodeMigrations, -} -#[automatically_derived] -impl ::core::fmt::Debug for MpcContract { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "protocol_state", - "pending_signature_requests", - "pending_ckd_requests", - "proposed_updates", - "config", - "tee_state", - "accept_requests", - "node_migrations", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.protocol_state, - &self.pending_signature_requests, - &self.pending_ckd_requests, - &self.proposed_updates, - &self.config, - &self.tee_state, - &self.accept_requests, - &&self.node_migrations, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "MpcContract", - names, - values, - ) - } -} -impl borsh::ser::BorshSerialize for MpcContract { - fn serialize<__W: borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), borsh::io::Error> { - borsh::BorshSerialize::serialize(&self.protocol_state, writer)?; - borsh::BorshSerialize::serialize(&self.pending_signature_requests, writer)?; - borsh::BorshSerialize::serialize(&self.pending_ckd_requests, writer)?; - borsh::BorshSerialize::serialize(&self.proposed_updates, writer)?; - borsh::BorshSerialize::serialize(&self.config, writer)?; - borsh::BorshSerialize::serialize(&self.tee_state, writer)?; - borsh::BorshSerialize::serialize(&self.accept_requests, writer)?; - borsh::BorshSerialize::serialize(&self.node_migrations, writer)?; - Ok(()) - } -} -impl borsh::de::BorshDeserialize for MpcContract { - fn deserialize_reader<__R: borsh::io::Read>( - reader: &mut __R, - ) -> ::core::result::Result { - Ok(Self { - protocol_state: borsh::BorshDeserialize::deserialize_reader(reader)?, - pending_signature_requests: borsh::BorshDeserialize::deserialize_reader( - reader, - )?, - pending_ckd_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, - proposed_updates: borsh::BorshDeserialize::deserialize_reader(reader)?, - config: borsh::BorshDeserialize::deserialize_reader(reader)?, - tee_state: borsh::BorshDeserialize::deserialize_reader(reader)?, - accept_requests: borsh::BorshDeserialize::deserialize_reader(reader)?, - node_migrations: borsh::BorshDeserialize::deserialize_reader(reader)?, - }) - } -} -#[must_use] -pub struct MpcContractExt { - pub(crate) promise_or_create_on: ::near_sdk::PromiseOrValue<::near_sdk::AccountId>, - pub(crate) deposit: ::near_sdk::NearToken, - pub(crate) static_gas: ::near_sdk::Gas, - pub(crate) gas_weight: ::near_sdk::GasWeight, -} -impl MpcContractExt { - pub fn with_attached_deposit(mut self, amount: ::near_sdk::NearToken) -> Self { - self.deposit = amount; - self - } - pub fn with_static_gas(mut self, static_gas: ::near_sdk::Gas) -> Self { - self.static_gas = static_gas; - self - } - pub fn with_unused_gas_weight(mut self, gas_weight: u64) -> Self { - self.gas_weight = ::near_sdk::GasWeight(gas_weight); - self - } -} -impl MpcContract { - /// API for calling this contract's functions in a subsequent execution. - pub fn ext(account_id: ::near_sdk::AccountId) -> MpcContractExt { - MpcContractExt { - promise_or_create_on: ::near_sdk::PromiseOrValue::Value(account_id), - deposit: ::near_sdk::NearToken::from_near(0), - static_gas: ::near_sdk::Gas::from_gas(0), - gas_weight: ::near_sdk::GasWeight::default(), - } - } - pub fn ext_on(promise: ::near_sdk::Promise) -> MpcContractExt { - MpcContractExt { - promise_or_create_on: ::near_sdk::PromiseOrValue::Promise(promise), - deposit: ::near_sdk::NearToken::from_near(0), - static_gas: ::near_sdk::Gas::from_gas(0), - gas_weight: ::near_sdk::GasWeight::default(), - } - } -} -const CONTRACT_SOURCE_METADATA: &'static str = "{\"version\":\"3.2.0\",\"link\":\"https://github.com/near/mpc\",\"standards\":[{\"standard\":\"nep330\",\"version\":\"1.3.0\"}],\"build_info\":null}"; -impl MpcContractExt { - pub fn contract_source_metadata(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("contract_source_metadata"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } -} -impl MpcContract { - pub fn contract_source_metadata() { - near_sdk::env::value_return(CONTRACT_SOURCE_METADATA.as_bytes()) - } -} -impl MpcContract { - pub(crate) fn public_key_extended( - &self, - domain_id: DomainId, - ) -> Result { - self.protocol_state.public_key(domain_id) - } - fn threshold(&self) -> Result { - self.protocol_state.threshold() - } - /// Returns true if the request was already pending - fn add_signature_request( - &mut self, - request: &SignatureRequest, - data_id: CryptoHash, - ) -> bool { - self.pending_signature_requests - .insert(request.clone(), YieldIndex { data_id }) - .is_some() - } - /// Returns true if the request was already pending - fn add_ckd_request(&mut self, request: &CKDRequest, data_id: CryptoHash) -> bool { - self.pending_ckd_requests - .insert(request.clone(), YieldIndex { data_id }) - .is_some() - } -} -impl MpcContractExt { - pub fn sign(self, request: SignRequestArgs) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput SignRequestArgs, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { request: &request }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("sign"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn public_key(self, domain_id: Option) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - domain_id: &'nearinput Option, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { domain_id: &domain_id }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("public_key"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn derived_public_key( - self, - path: String, - predecessor: Option, - domain_id: Option, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - path: &'nearinput String, - predecessor: &'nearinput Option, - domain_id: &'nearinput Option, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "path", - &self.path, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "predecessor", - &self.predecessor, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domain_id", - &self.domain_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - path: &path, - predecessor: &predecessor, - domain_id: &domain_id, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("derived_public_key"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn latest_key_version( - self, - signature_scheme: Option, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - signature_scheme: &'nearinput Option, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "signature_scheme", - &self.signature_scheme, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - signature_scheme: &signature_scheme, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("latest_key_version"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn request_app_private_key( - self, - request: CKDRequestArgs, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput CKDRequestArgs, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { request: &request }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("request_app_private_key"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } -} -impl MpcContract { - /// `key_version` must be less than or equal to the value at `latest_key_version` - /// To avoid overloading the network with too many requests, - /// we ask for a small deposit for each signature request. - pub fn sign(&mut self, request: SignRequestArgs) { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "sign: predecessor={0:?}, request={1:?}", - env::predecessor_account_id(), - request, - ), - ); - res - }) - .as_str(), - ); - let initial_storage = env::storage_usage(); - let request: SignRequest = request.try_into().unwrap(); - let domains = match self.protocol_state.domain_registry() { - Ok(domains) => domains, - Err(err) => env::panic_str(&err.to_string()), - }; - let Some(domain_config) = domains.get_domain_by_domain_id(request.domain_id) - else { - env::panic_str( - &InvalidParameters::DomainNotFound { - provided: request.domain_id, - } - .to_string(), - ); - }; - match domain_config.scheme { - SignatureScheme::Secp256k1 | SignatureScheme::V2Secp256k1 => { - let hash = *request.payload.as_ecdsa().expect("Payload is not Ecdsa"); - k256::Scalar::from_repr(hash.into()) - .into_option() - .expect("Ecdsa payload cannot be converted to Scalar"); - } - SignatureScheme::Ed25519 => { - request.payload.as_eddsa().expect("Payload is not EdDSA"); - } - SignatureScheme::Bls12381 => { - env::panic_str( - &InvalidParameters::InvalidDomainId - .message( - "Selected domain is used for Bls12381, which is not compatible with this function", - ) - .to_string(), - ); - } - } - let gas_required = Gas::from_tgas( - self.config.sign_call_gas_attachment_requirement_tera_gas, - ); - if env::prepaid_gas() < gas_required { - env::panic_str( - &InvalidParameters::InsufficientGas - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Provided: {0}, required: {1}", - env::prepaid_gas(), - gas_required, - ), - ); - res - }), - ) - .to_string(), - ); - } - let predecessor = env::predecessor_account_id(); - let deposit = env::attached_deposit(); - let storage_used = env::storage_usage() - initial_storage; - let storage_cost = env::storage_byte_cost() - .saturating_mul(u128::from(storage_used)); - let cost = std::cmp::max(storage_cost, MINIMUM_SIGN_REQUEST_DEPOSIT); - match deposit.checked_sub(cost) { - None => { - env::panic_str( - &InvalidParameters::InsufficientDeposit - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Require a deposit of {0} yoctonear, found: {1}", - cost.as_yoctonear(), - deposit.as_yoctonear(), - ), - ); - res - }), - ) - .to_string(), - ); - } - Some(diff) => { - if diff > NearToken::from_yoctonear(0) { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "refund excess deposit {0} to {1}", - diff, - predecessor, - ), - ); - res - }) - .as_str(), - ); - Promise::new(predecessor.clone()).transfer(diff).detach(); - } - } - } - let request = SignatureRequest::new( - request.domain_id, - request.payload, - &predecessor.as_v2_account_id(), - &request.path, - ); - if !self.accept_requests { - env::panic_str(&TeeError::TeeValidationFailed.to_string()) - } - let callback_gas = Gas::from_tgas( - self.config.return_signature_and_clean_state_on_success_call_tera_gas, - ); - let promise_index = env::promise_yield_create( - "return_signature_and_clean_state_on_success", - serde_json::to_vec(&(&request,)).unwrap(), - callback_gas, - GasWeight(0), - DATA_ID_REGISTER, - ); - let return_sig_id: CryptoHash = env::read_register(DATA_ID_REGISTER) - .expect("read_register failed") - .try_into() - .expect("conversion to CryptoHash failed"); - if self.add_signature_request(&request, return_sig_id) { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "signature request already present, overriding callback.", - ), - ); - res - }) - .as_str(), - ) - } - env::promise_return(promise_index); - } - /// This is the root public key combined from all the public keys of the participants. - /// The domain parameter specifies which domain we're querying the public key for; - /// the default is the first domain. - pub fn public_key( - &self, - domain_id: Option, - ) -> Result { - let domain_id = domain_id.unwrap_or_else(DomainId::legacy_ecdsa_id); - self.public_key_extended(domain_id).map(Into::into) - } - /// This is the derived public key of the caller given path and predecessor - /// if predecessor is not provided, it will be the caller of the contract. - /// - /// The domain parameter specifies which domain we're deriving the public key for; - /// the default is the first domain. - pub fn derived_public_key( - &self, - path: String, - predecessor: Option, - domain_id: Option, - ) -> Result { - let predecessor: AccountId = predecessor - .unwrap_or_else(|| env::predecessor_account_id().as_v2_account_id()); - let tweak = derive_tweak(&predecessor, &path); - let domain = domain_id.unwrap_or_else(DomainId::legacy_ecdsa_id); - let public_key = self.public_key_extended(domain)?; - let derived_public_key: dtos::PublicKey = match public_key { - PublicKeyExtended::Secp256k1 { near_public_key } => { - let derived_public_key = derive_key_secp256k1( - &near_public_key_to_affine_point(near_public_key), - &tweak, - ) - .map_err(PublicKeyError::from)?; - derived_public_key.into_dto_type().into() - } - PublicKeyExtended::Ed25519 { edwards_point, .. } => { - let derived_public_key_edwards_point = derive_public_key_edwards_point_ed25519( - &edwards_point, - &tweak, - ); - derived_public_key_edwards_point.compress().into_dto_type().into() - } - PublicKeyExtended::Bls12381 { public_key } => public_key, - }; - Ok(derived_public_key) - } - /// Key versions refer new versions of the root key that we may choose to generate on cohort - /// changes. Older key versions will always work but newer key versions were never held by - /// older signers. Newer key versions may also add new security features, like only existing - /// within a secure enclave. The signature_scheme parameter specifies which protocol - /// we're querying the latest version for. The default is Secp256k1. The default is **NOT** - /// to query across all protocols. - pub fn latest_key_version(&self, signature_scheme: Option) -> u32 { - self - .state() - .most_recent_domain_for_protocol(signature_scheme.unwrap_or_default()) - .unwrap() - .0 as u32 - } - /// To avoid overloading the network with too many requests, - /// we ask for a small deposit for each ckd request. - pub fn request_app_private_key(&mut self, request: CKDRequestArgs) { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "request_app_private_key: predecessor={0:?}, request={1:?}", - env::predecessor_account_id(), - request, - ), - ); - res - }) - .as_str(), - ); - let initial_storage = env::storage_usage(); - let domains = match self.protocol_state.domain_registry() { - Ok(domains) => domains, - Err(err) => env::panic_str(&err.to_string()), - }; - let Some(domain_config) = domains.get_domain_by_domain_id(request.domain_id) - else { - env::panic_str( - &InvalidParameters::DomainNotFound { - provided: request.domain_id, - } - .to_string(), - ); - }; - if domain_config.scheme != SignatureScheme::Bls12381 { - env::panic_str( - &InvalidParameters::InvalidDomainId - .message("Provided domain ID key type is not Bls12381") - .to_string(), - ); - } - let gas_required = Gas::from_tgas( - self.config.ckd_call_gas_attachment_requirement_tera_gas, - ); - if env::prepaid_gas() < gas_required { - env::panic_str( - &InvalidParameters::InsufficientGas - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Provided: {0}, required: {1}", - env::prepaid_gas(), - gas_required, - ), - ); - res - }), - ) - .to_string(), - ); - } - let predecessor = env::predecessor_account_id(); - let deposit = env::attached_deposit(); - let storage_used = env::storage_usage() - initial_storage; - let storage_cost = env::storage_byte_cost() - .saturating_mul(u128::from(storage_used)); - let cost = std::cmp::max(storage_cost, MINIMUM_CKD_REQUEST_DEPOSIT); - match deposit.checked_sub(cost) { - None => { - env::panic_str( - &InvalidParameters::InsufficientDeposit - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Require a deposit of {0} yoctonear, found: {1}", - cost.as_yoctonear(), - deposit.as_yoctonear(), - ), - ); - res - }), - ) - .to_string(), - ); - } - Some(diff) => { - if diff > NearToken::from_yoctonear(0) { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "refund excess deposit {0} to {1}", - diff, - predecessor, - ), - ); - res - }) - .as_str(), - ); - Promise::new(predecessor.clone()).transfer(diff).detach(); - } - } - } - let mpc_contract = self; - if !mpc_contract.accept_requests { - env::panic_str(&TeeError::TeeValidationFailed.to_string()) - } - let account_id = env::predecessor_account_id().as_v2_account_id(); - let request = CKDRequest::new( - request.app_public_key, - request.domain_id, - &account_id, - &request.derivation_path, - ); - let callback_gas = Gas::from_tgas( - mpc_contract.config.return_ck_and_clean_state_on_success_call_tera_gas, - ); - let promise_index = env::promise_yield_create( - "return_ck_and_clean_state_on_success", - serde_json::to_vec(&(&request,)).unwrap(), - callback_gas, - GasWeight(0), - DATA_ID_REGISTER, - ); - let return_ck_id: CryptoHash = env::read_register(DATA_ID_REGISTER) - .expect("read_register failed") - .try_into() - .expect("conversion to CryptoHash failed"); - if mpc_contract.add_ckd_request(&request, return_ck_id) { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("request already present, overriding callback."), - ); - res - }) - .as_str(), - ) - } - env::promise_return(promise_index); - } -} -impl MpcContractExt { - pub fn respond( - self, - request: SignatureRequest, - response: SignatureResponse, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput SignatureRequest, - response: &'nearinput SignatureResponse, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "response", - &self.response, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - request: &request, - response: &response, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("respond"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn respond_ckd( - self, - request: CKDRequest, - response: CKDResponse, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput CKDRequest, - response: &'nearinput CKDResponse, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "response", - &self.response, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - request: &request, - response: &response, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("respond_ckd"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn submit_participant_info( - self, - proposed_participant_attestation: dtos::Attestation, - tls_public_key: dtos::Ed25519PublicKey, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - proposed_participant_attestation: &'nearinput dtos::Attestation, - tls_public_key: &'nearinput dtos::Ed25519PublicKey, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "proposed_participant_attestation", - &self.proposed_participant_attestation, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "tls_public_key", - &self.tls_public_key, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - proposed_participant_attestation: &proposed_participant_attestation, - tls_public_key: &tls_public_key, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("submit_participant_info"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn get_attestation( - self, - tls_public_key: dtos::Ed25519PublicKey, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - tls_public_key: &'nearinput dtos::Ed25519PublicKey, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "tls_public_key", - &self.tls_public_key, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - tls_public_key: &tls_public_key, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("get_attestation"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_new_parameters( - self, - prospective_epoch_id: EpochId, - proposal: ThresholdParameters, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - prospective_epoch_id: &'nearinput EpochId, - proposal: &'nearinput ThresholdParameters, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "prospective_epoch_id", - &self.prospective_epoch_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "proposal", - &self.proposal, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - prospective_epoch_id: &prospective_epoch_id, - proposal: &proposal, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_new_parameters"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_add_domains(self, domains: Vec) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - domains: &'nearinput Vec, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domains", - &self.domains, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { domains: &domains }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_add_domains"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn start_keygen_instance(self, key_event_id: KeyEventId) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - key_event_id: &'nearinput KeyEventId, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key_event_id", - &self.key_event_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - key_event_id: &key_event_id, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("start_keygen_instance"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_pk( - self, - key_event_id: KeyEventId, - public_key: dtos::PublicKey, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - key_event_id: &'nearinput KeyEventId, - public_key: &'nearinput dtos::PublicKey, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key_event_id", - &self.key_event_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "public_key", - &self.public_key, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - key_event_id: &key_event_id, - public_key: &public_key, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_pk"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn start_reshare_instance( - self, - key_event_id: KeyEventId, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - key_event_id: &'nearinput KeyEventId, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key_event_id", - &self.key_event_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - key_event_id: &key_event_id, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("start_reshare_instance"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_reshared(self, key_event_id: KeyEventId) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - key_event_id: &'nearinput KeyEventId, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key_event_id", - &self.key_event_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - key_event_id: &key_event_id, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_reshared"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_cancel_resharing(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_cancel_resharing"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_cancel_keygen(self, next_domain_id: u64) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - next_domain_id: &'nearinput u64, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "next_domain_id", - &self.next_domain_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - next_domain_id: &next_domain_id, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_cancel_keygen"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_abort_key_event_instance( - self, - key_event_id: KeyEventId, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - key_event_id: &'nearinput KeyEventId, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key_event_id", - &self.key_event_id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - key_event_id: &key_event_id, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_abort_key_event_instance"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn propose_update(self, args: ProposeUpdateArgs) -> ::near_sdk::Promise { - let __args = { - #[borsh(crate = "::near_sdk::borsh")] - struct Input<'nearinput> { - args: &'nearinput ProposeUpdateArgs, - } - impl<'nearinput> ::near_sdk::borsh::ser::BorshSerialize - for Input<'nearinput> { - fn serialize<__W: ::near_sdk::borsh::io::Write>( - &self, - writer: &mut __W, - ) -> ::core::result::Result<(), ::near_sdk::borsh::io::Error> { - ::near_sdk::borsh::BorshSerialize::serialize(&self.args, writer)?; - Ok(()) - } - } - let __args = Input { args: &args }; - match near_sdk::borsh::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using Borsh.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("propose_update"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_update(self, id: UpdateId) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - id: &'nearinput UpdateId, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "id", - &self.id, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { id: &id }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_update"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn proposed_updates(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("proposed_updates"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn remove_update_vote(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("remove_update_vote"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn vote_code_hash(self, code_hash: MpcDockerImageHash) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - code_hash: &'nearinput MpcDockerImageHash, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "code_hash", - &self.code_hash, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { code_hash: &code_hash }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("vote_code_hash"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn get_tee_accounts(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("get_tee_accounts"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn verify_tee(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("verify_tee"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn remove_non_participant_update_votes(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("remove_non_participant_update_votes"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn clean_tee_status(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("clean_tee_status"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } -} -impl MpcContract { - pub fn respond( - &mut self, - request: SignatureRequest, - response: SignatureResponse, - ) -> Result<(), Error> { - let signer = Self::assert_caller_is_signer(); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "respond: signer={0}, request={1:?}", - &signer, - &request, - ), - ); - res - }) - .as_str(), - ); - self.assert_caller_is_attested_participant_and_protocol_active(); - if !self.protocol_state.is_running_or_resharing() { - return Err(InvalidState::ProtocolStateNotRunning.into()); - } - if !self.accept_requests { - return Err(TeeError::TeeValidationFailed.into()); - } - let domain = request.domain_id; - let public_key = self.public_key_extended(domain)?; - let signature_is_valid = match (&response, public_key) { - ( - SignatureResponse::Secp256k1(signature_response), - PublicKeyExtended::Secp256k1 { near_public_key }, - ) => { - let expected_public_key = derive_key_secp256k1( - &near_public_key_to_affine_point(near_public_key), - &request.tweak, - ) - .map_err(RespondError::from)?; - let payload_hash = request - .payload - .as_ecdsa() - .expect("Payload is not ECDSA"); - check_ec_signature( - &expected_public_key, - &signature_response.big_r.affine_point, - &signature_response.s.scalar, - payload_hash, - signature_response.recovery_id, - ) - .is_ok() - } - ( - SignatureResponse::Ed25519 { signature }, - PublicKeyExtended::Ed25519 { - edwards_point: public_key_edwards_point, - .. - }, - ) => { - let derived_public_key_edwards_point = derive_public_key_edwards_point_ed25519( - &public_key_edwards_point, - &request.tweak, - ); - let derived_public_key_32_bytes = *derived_public_key_edwards_point - .compress() - .as_bytes(); - let message = request.payload.as_eddsa().expect("Payload is not EdDSA"); - ed25519_verify( - signature.as_bytes(), - message, - &derived_public_key_32_bytes, - ) - } - (signature_response, public_key_requested) => { - return Err( - RespondError::SignatureSchemeMismatch - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Signature response from MPC: {0:?}. Key requested by user {1:?}", - signature_response, - public_key_requested, - ), - ); - res - }), - ), - ); - } - }; - if !signature_is_valid { - return Err(RespondError::InvalidSignature.into()); - } - if let Some(YieldIndex { data_id }) = self - .pending_signature_requests - .remove(&request) - { - env::promise_yield_resume(&data_id, serde_json::to_vec(&response).unwrap()); - Ok(()) - } else { - Err(InvalidParameters::RequestNotFound.into()) - } - } - pub fn respond_ckd( - &mut self, - request: CKDRequest, - response: CKDResponse, - ) -> Result<(), Error> { - let signer = Self::assert_caller_is_signer(); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "respond_ckd: signer={0}, request={1:?}", - &signer, - &request, - ), - ); - res - }) - .as_str(), - ); - if !self.protocol_state.is_running_or_resharing() { - return Err(InvalidState::ProtocolStateNotRunning.into()); - } - if !self.accept_requests { - return Err(TeeError::TeeValidationFailed.into()); - } - self.assert_caller_is_attested_participant_and_protocol_active(); - if let Some(YieldIndex { data_id }) = self.pending_ckd_requests.remove(&request) - { - env::promise_yield_resume(&data_id, serde_json::to_vec(&response).unwrap()); - Ok(()) - } else { - Err(InvalidParameters::RequestNotFound.into()) - } - } - /// (Prospective) Participants can submit their tee participant information through this - /// endpoint. - pub fn submit_participant_info( - &mut self, - proposed_participant_attestation: dtos::Attestation, - tls_public_key: dtos::Ed25519PublicKey, - ) -> Result<(), Error> { - let proposed_participant_attestation = proposed_participant_attestation - .into_contract_type(); - let account_key = env::signer_account_pk(); - let account_id = Self::assert_caller_is_signer(); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "submit_participant_info: signer={0}, proposed_participant_attestation={1:?}, account_key={2:?}", - account_id, - proposed_participant_attestation, - account_key, - ), - ); - res - }) - .as_str(), - ); - let initial_storage = env::storage_usage(); - let tee_upgrade_deadline_duration = Duration::from_secs( - self.config.tee_upgrade_deadline_duration_seconds, - ); - let attestation_insertion_result = self - .tee_state - .add_participant( - NodeId { - account_id: account_id.clone(), - tls_public_key: tls_public_key.into_contract_type(), - account_public_key: Some(account_key), - }, - proposed_participant_attestation, - tee_upgrade_deadline_duration, - ) - .map_err(|err| { - InvalidParameters::InvalidTeeRemoteAttestation - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("TeeQuoteStatus is invalid: {0}", err), - ); - res - }), - ) - })?; - let caller_is_not_participant = self.voter_account().is_err(); - let is_new_attestation = match attestation_insertion_result { - ParticipantInsertion::NewlyInsertedParticipant => true, - _ => false, - }; - let attestation_storage_must_be_paid_by_caller = is_new_attestation - || caller_is_not_participant; - if attestation_storage_must_be_paid_by_caller { - let storage_used = env::storage_usage() - initial_storage; - let cost = env::storage_byte_cost().saturating_mul(storage_used as u128); - let attached = env::attached_deposit(); - if attached < cost { - return Err( - InvalidParameters::InsufficientDeposit - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Attached {0}, Required {1}", - attached.as_yoctonear(), - cost.as_yoctonear(), - ), - ); - res - }), - ), - ); - } - if let Some(diff) = attached.checked_sub(cost) { - if diff > NearToken::from_yoctonear(0) { - Promise::new(account_id.as_v1_account_id()).transfer(diff).detach(); - } - } - } - Ok(()) - } - pub fn get_attestation( - &self, - tls_public_key: dtos::Ed25519PublicKey, - ) -> Result, Error> { - let tls_public_key = tls_public_key.into_contract_type(); - Ok( - self - .tee_state - .stored_attestations - .get(&tls_public_key) - .map(|node_attestation| { - node_attestation.verified_attestation.clone().into_dto_type() - }), - ) - } - /// Propose a new set of parameters (participants and threshold) for the MPC network. - /// If a threshold number of votes are reached on the exact same proposal, this will transition - /// the contract into the Resharing state. - /// - /// The epoch_id must be equal to 1 plus the current epoch ID (if Running) or prospective epoch - /// ID (if Resharing). Otherwise the vote is ignored. This is to prevent late transactions from - /// accidentally voting on outdated proposals. - pub fn vote_new_parameters( - &mut self, - prospective_epoch_id: EpochId, - proposal: ThresholdParameters, - ) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_new_parameters: signer={0}, proposal={1:?}", - env::signer_account_id(), - proposal, - ), - ); - res - }) - .as_str(), - ); - let tee_upgrade_deadline_duration = Duration::from_secs( - self.config.tee_upgrade_deadline_duration_seconds, - ); - let validation_result = self - .tee_state - .reverify_and_cleanup_participants( - proposal.participants(), - tee_upgrade_deadline_duration, - ); - let proposed_participants = proposal.participants(); - match validation_result { - TeeValidationResult::Full => { - if let Some(new_state) = self - .protocol_state - .vote_new_parameters(prospective_epoch_id, &proposal)? - { - self.protocol_state = new_state; - } - Ok(()) - } - TeeValidationResult::Partial { participants_with_valid_attestation } => { - let invalid_participants: Vec<_> = proposed_participants - .participants() - .iter() - .filter(|(account_id, _, _)| { - !participants_with_valid_attestation.is_participant(account_id) - }) - .collect(); - Err( - InvalidParameters::InvalidTeeRemoteAttestation - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "The following participants have invalid TEE status: {0:?}", - invalid_participants, - ), - ); - res - }), - ), - ) - } - } - } - /// Propose adding a new set of domains for the MPC network. - /// If a threshold number of votes are reached on the exact same proposal, this will transition - /// the contract into the Initializing state to generate keys for the new domains. - /// - /// The specified list of domains must have increasing and contiguous IDs, and the first ID - /// must be the same as the `next_domain_id` returned by state(). - pub fn vote_add_domains(&mut self, domains: Vec) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_add_domains: signer={0}, domains={1:?}", - env::signer_account_id(), - domains, - ), - ); - res - }) - .as_str(), - ); - if let Some(new_state) = self.protocol_state.vote_add_domains(domains)? { - self.protocol_state = new_state; - } - Ok(()) - } - /// Starts a new attempt to generate a key for the current domain. - /// This only succeeds if the signer is the leader (the participant with the lowest ID). - pub fn start_keygen_instance( - &mut self, - key_event_id: KeyEventId, - ) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "start_keygen_instance: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - self.assert_caller_is_attested_participant_and_protocol_active(); - self.protocol_state - .start_keygen_instance(key_event_id, self.config.key_event_timeout_blocks) - } - /// Casts a vote for `public_key` for the attempt identified by `key_event_id`. - /// - /// The effect of this method is either: - /// - Returns error (which aborts with no changes), if there is no active key generation - /// attempt (including if the attempt timed out), if the signer is not a participant, or if - /// the key_event_id corresponds to a different domain, different epoch, or different attempt - /// from the current key generation attempt. - /// - Returns Ok(()), with one of the following changes: - /// - A vote has been collected but we don't have enough votes yet. - /// - This vote is for a public key that disagrees from an earlier voted public key, causing - /// the attempt to abort; another call to `start` is then necessary. - /// - Everyone has now voted for the same public key; the state transitions into generating a - /// key for the next domain. - /// - Same as the last case, except that all domains have a generated key now, and the state - /// transitions into Running with the newly generated keys. - pub fn vote_pk( - &mut self, - key_event_id: KeyEventId, - public_key: dtos::PublicKey, - ) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_pk: signer={0}, key_event_id={1:?}, public_key={2:?}", - env::signer_account_id(), - key_event_id, - public_key, - ), - ); - res - }) - .as_str(), - ); - self.assert_caller_is_attested_participant_and_protocol_active(); - let extended_key = public_key - .try_into() - .map_err(|err: PublicKeyExtendedConversionError| { - InvalidParameters::MalformedPayload.message(err.to_string()) - })?; - if let Some(new_state) = self.protocol_state.vote_pk(key_event_id, extended_key)? - { - self.protocol_state = new_state; - } - Ok(()) - } - /// Starts a new attempt to reshare the key for the current domain. - /// This only succeeds if the signer is the leader (the participant with the lowest ID). - pub fn start_reshare_instance( - &mut self, - key_event_id: KeyEventId, - ) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "start_reshare_instance: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - self.assert_caller_is_attested_participant_and_protocol_active(); - self.protocol_state - .start_reshare_instance(key_event_id, self.config.key_event_timeout_blocks) - } - /// Casts a vote for the successful resharing of the attempt identified by `key_event_id`. - /// - /// The effect of this method is either: - /// - Returns error (which aborts with no changes), if there is no active key resharing attempt - /// (including if the attempt timed out), if the signer is not a participant, or if the - /// key_event_id corresponds to a different domain, different epoch, or different attempt - /// from the current key resharing attempt. - /// - Returns Ok(()), with one of the following changes: - /// - A vote has been collected but we don't have enough votes yet. - /// - Everyone has now voted; the state transitions into resharing the key for the next - /// domain. - /// - Same as the last case, except that all domains' keys have been reshared now, and the - /// state transitions into Running with the newly reshared keys. - pub fn vote_reshared(&mut self, key_event_id: KeyEventId) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_reshared: signer={0}, resharing_id={1:?}", - env::signer_account_id(), - key_event_id, - ), - ); - res - }) - .as_str(), - ); - self.assert_caller_is_attested_participant_and_protocol_active(); - if let Some(new_state) = self.protocol_state.vote_reshared(key_event_id)? { - self.protocol_state = new_state; - Promise::new(env::current_account_id()) - .function_call( - "remove_non_participant_update_votes".to_string(), - ::alloc::vec::Vec::new(), - NearToken::from_yoctonear(0), - Gas::from_tgas( - self.config.remove_non_participant_update_votes_tera_gas, - ), - ) - .detach(); - Promise::new(env::current_account_id()) - .function_call( - "clean_tee_status".to_string(), - ::alloc::vec::Vec::new(), - NearToken::from_yoctonear(0), - Gas::from_tgas(self.config.clean_tee_status_tera_gas), - ) - .detach(); - Promise::new(env::current_account_id()) - .function_call( - "cleanup_orphaned_node_migrations".to_string(), - ::alloc::vec::Vec::new(), - NearToken::from_yoctonear(0), - Gas::from_tgas(self.config.cleanup_orphaned_node_migrations_tera_gas), - ) - .detach(); - } - Ok(()) - } - /// Casts a vote to cancel the current key resharing. If a threshold number of unique - /// votes are collected to cancel the resharing, the contract state will revert back to the - /// previous running state. - /// - /// - This method is idempotent, meaning a single account can not make more than one vote. - /// - Only nodes from the previous running state are allowed to vote. - /// - /// Return value: - /// - [Ok] if the vote was successfully collected. - /// - [Err] if: - /// - The signer is not a participant in the previous running state. - /// - The contract is not in a resharing state. - pub fn vote_cancel_resharing(&mut self) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_cancel_resharing: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - if let Some(new_state) = self.protocol_state.vote_cancel_resharing()? { - self.protocol_state = new_state; - } - Ok(()) - } - /// Casts a vote to cancel key generation. Any keys that have already been generated - /// are kept and we transition into Running state; remaining domains are permanently deleted. - /// Deleted domain IDs cannot be reused again in future calls to vote_add_domains. - /// - /// A next_domain_id that matches that in the state's domains struct must be passed in. This is - /// to prevent stale requests from accidentally cancelling a future key generation state. - pub fn vote_cancel_keygen(&mut self, next_domain_id: u64) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_cancel_keygen: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - if let Some(new_state) = self.protocol_state.vote_cancel_keygen(next_domain_id)? - { - self.protocol_state = new_state; - } - Ok(()) - } - /// Casts a vote to abort the current key event instance. If succesful, the contract aborts the - /// instance and a new instance with the next attempt_id can be started. - pub fn vote_abort_key_event_instance( - &mut self, - key_event_id: KeyEventId, - ) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_abort_key_event_instance: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - self.assert_caller_is_attested_participant_and_protocol_active(); - self.protocol_state.vote_abort_key_event_instance(key_event_id) - } - /// Propose update to either code or config, but not both of them at the same time. - pub fn propose_update( - &mut self, - args: ProposeUpdateArgs, - ) -> Result { - let proposer = self.voter_or_panic().as_v1_account_id(); - let update: Update = args.try_into()?; - let attached = env::attached_deposit(); - let required = ProposedUpdates::required_deposit(&update); - if attached < required { - return Err( - InvalidParameters::InsufficientDeposit - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Attached {0}, Required {1}", - attached.as_yoctonear(), - required.as_yoctonear(), - ), - ); - res - }), - ), - ); - } - let id = self.proposed_updates.propose(update); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "propose_update: signer={0}, id={1:?}", - env::signer_account_id(), - id, - ), - ); - res - }) - .as_str(), - ); - if let Some(diff) = attached.checked_sub(required) { - if diff > NearToken::from_yoctonear(0) { - Promise::new(proposer).transfer(diff).detach(); - } - } - Ok(id) - } - /// Vote for a proposed update given the [`UpdateId`] of the update. - /// - /// Returns `Ok(true)` if the amount of voters surpassed the threshold and the update was - /// executed. Returns `Ok(false)` if the amount of voters did not surpass the threshold. - /// Returns [`Error`] if the update was not found or if the voter is not a participant - /// in the protocol. - pub fn vote_update(&mut self, id: UpdateId) -> Result { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_update: signer={0}, id={1:?}", - env::signer_account_id(), - id, - ), - ); - res - }) - .as_str(), - ); - let ProtocolContractState::Running(running_state) = &self.protocol_state else { - env::panic_str("protocol must be in running state"); - }; - let threshold = self.threshold()?; - let voter = self.voter_or_panic(); - if self.proposed_updates.vote(&id, voter).is_none() { - return Err(InvalidParameters::UpdateNotFound.into()); - } - let valid_votes_count = running_state - .parameters - .participants() - .participants() - .iter() - .filter(|(account_id, _, _)| { - self.proposed_updates - .vote_by_participant - .get(account_id) - .is_some_and(|voted_id| *voted_id == id) - }) - .count(); - if (valid_votes_count as u64) < threshold.value() { - return Ok(false); - } - let update_gas_deposit = Gas::from_tgas( - self.config.contract_upgrade_deposit_tera_gas, - ); - let Some(_promise) = self.proposed_updates.do_update(&id, update_gas_deposit) - else { - return Err(InvalidParameters::UpdateNotFound.into()); - }; - Ok(true) - } - /// returns all proposed updates - pub fn proposed_updates(&self) -> dtos::ProposedUpdates { - self.proposed_updates.into_dto_type() - } - /// Removes an update vote by the caller - /// panics if the contract is not in a running state or if the caller is not a participant - pub fn remove_update_vote(&mut self) { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "remove_update_vote: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - let ProtocolContractState::Running(_running_state) = &self.protocol_state else { - env::panic_str("protocol must be in running state"); - }; - let voter = self.voter_or_panic(); - self.proposed_updates.remove_vote(&voter); - } - pub fn vote_code_hash( - &mut self, - code_hash: MpcDockerImageHash, - ) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "vote_code_hash: signer={0}, code_hash={1:?}", - env::signer_account_id(), - code_hash, - ), - ); - res - }) - .as_str(), - ); - self.voter_or_panic(); - let threshold_parameters = match self.state().threshold_parameters() { - Ok(threshold_parameters) => threshold_parameters, - Err(ContractNotInitialized) => { - env::panic_str( - "Contract is not initialized. Can not vote for a new image hash before initialization.", - ) - } - }; - let participant = AuthenticatedParticipantId::new( - threshold_parameters.participants(), - )?; - let votes = self.tee_state.vote(code_hash.clone(), &participant); - let tee_upgrade_deadline_duration = Duration::from_secs( - self.config.tee_upgrade_deadline_duration_seconds, - ); - if votes >= self.threshold()?.value() { - self.tee_state - .whitelist_tee_proposal(code_hash, tee_upgrade_deadline_duration); - } - Ok(()) - } - /// Returns all accounts that have TEE attestations stored in the contract. - /// Note: This includes both current protocol participants and accounts that may have - /// submitted TEE information but are not currently part of the active participant set. - pub fn get_tee_accounts(&self) -> Vec { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format(format_args!("get_tee_accounts")); - res - }) - .as_str(), - ); - self.tee_state.get_tee_accounts() - } - /// Verifies if all current participants have an accepted TEE state. - /// Automatically enters a resharing, in case one or more participants do not have an accepted - /// TEE state. - /// Returns `false` and stops the contract from accepting new signature requests or responses, - /// in case less than `threshold` participants run in an accepted TEE State. - pub fn verify_tee(&mut self) -> Result { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("verify_tee: signer={0}", env::signer_account_id()), - ); - res - }) - .as_str(), - ); - self.voter_or_panic(); - let ProtocolContractState::Running(running_state) = &mut self.protocol_state - else { - return Err(InvalidState::ProtocolStateNotRunning.into()); - }; - let current_params = running_state.parameters.clone(); - let tee_upgrade_deadline_duration = Duration::from_secs( - self.config.tee_upgrade_deadline_duration_seconds, - ); - match self - .tee_state - .reverify_and_cleanup_participants( - current_params.participants(), - tee_upgrade_deadline_duration, - ) - { - TeeValidationResult::Full => { - self.accept_requests = true; - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("All participants have an accepted Tee status"), - ); - res - }) - .as_str(), - ); - Ok(true) - } - TeeValidationResult::Partial { participants_with_valid_attestation } => { - let threshold = current_params.threshold().value() as usize; - let remaining = participants_with_valid_attestation.len(); - if threshold > remaining { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Less than `threshold` participants are left with a valid TEE status. This requires manual intervention. We will not accept new signature requests as a safety precaution.", - ), - ); - res - }) - .as_str(), - ); - self.accept_requests = false; - return Ok(false); - } - self.accept_requests = true; - let new_threshold = threshold; - let threshold_parameters = ThresholdParameters::new( - participants_with_valid_attestation, - Threshold::new(new_threshold as u64), - ) - .expect("Require valid threshold parameters"); - current_params.validate_incoming_proposal(&threshold_parameters)?; - let res = running_state - .transition_to_resharing_no_checks(&threshold_parameters); - if let Some(resharing) = res { - self.protocol_state = ProtocolContractState::Resharing(resharing); - } - Ok(true) - } - } - } - /// Cleans update votes from non-participants after resharing. - /// Can be called by any participant or triggered automatically via promise. - pub fn remove_non_participant_update_votes(&mut self) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "remove_non_participant_update_votes: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - let participants = match &self.protocol_state { - ProtocolContractState::Running(state) => state.parameters.participants(), - _ => { - return Err(InvalidState::ProtocolStateNotRunning.into()); - } - }; - self.proposed_updates.remove_non_participant_votes(participants); - Ok(()) - } - /// Private endpoint to clean up TEE information for non-participants after resharing. - /// This can only be called by the contract itself via a promise. - pub fn clean_tee_status(&mut self) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "clean_tee_status: signer={0}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - let participants = match &self.protocol_state { - ProtocolContractState::Running(state) => state.parameters.participants(), - _ => { - return Err(InvalidState::ProtocolStateNotRunning.into()); - } - }; - self.tee_state.clean_non_participants(participants); - Ok(()) - } -} -impl MpcContractExt { - pub fn init( - self, - parameters: ThresholdParameters, - init_config: Option, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - parameters: &'nearinput ThresholdParameters, - init_config: &'nearinput Option, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "parameters", - &self.parameters, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "init_config", - &self.init_config, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - parameters: ¶meters, - init_config: &init_config, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("init"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn init_running( - self, - domains: Vec, - next_domain_id: u64, - keyset: Keyset, - parameters: ThresholdParameters, - init_config: Option, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - domains: &'nearinput Vec, - next_domain_id: &'nearinput u64, - keyset: &'nearinput Keyset, - parameters: &'nearinput ThresholdParameters, - init_config: &'nearinput Option, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "domains", - &self.domains, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "next_domain_id", - &self.next_domain_id, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "keyset", - &self.keyset, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "parameters", - &self.parameters, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "init_config", - &self.init_config, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - domains: &domains, - next_domain_id: &next_domain_id, - keyset: &keyset, - parameters: ¶meters, - init_config: &init_config, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("init_running"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn migrate(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("migrate"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn migrate_cleanup(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("migrate_cleanup"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn state(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("state"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn allowed_docker_image_hashes(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("allowed_docker_image_hashes"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn allowed_launcher_compose_hashes(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("allowed_launcher_compose_hashes"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn get_pending_request(self, request: &SignatureRequest) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput SignatureRequest, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { request: &request }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("get_pending_request"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn get_pending_ckd_request(self, request: &CKDRequest) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput CKDRequest, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { request: &request }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("get_pending_ckd_request"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn config(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("config"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn version(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("version"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn return_signature_and_clean_state_on_success( - self, - request: SignatureRequest, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput SignatureRequest, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { request: &request }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from( - "return_signature_and_clean_state_on_success", - ), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn return_ck_and_clean_state_on_success( - self, - request: CKDRequest, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - request: &'nearinput CKDRequest, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "request", - &self.request, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { request: &request }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("return_ck_and_clean_state_on_success"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn fail_on_timeout(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("fail_on_timeout"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn update_config(self, config: dtos::Config) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - config: &'nearinput dtos::Config, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "config", - &self.config, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { config: &config }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("update_config"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } -} -impl MpcContract { - pub fn init( - parameters: ThresholdParameters, - init_config: Option, - ) -> Result { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "init: signer={0}, parameters={1:?}, init_config={2:?}", - env::signer_account_id(), - parameters, - init_config, - ), - ); - res - }) - .as_str(), - ); - parameters.validate()?; - parameters.validate().unwrap(); - let initial_participants = parameters.participants(); - let tee_state = TeeState::with_mocked_participant_attestations( - initial_participants, - ); - Ok(Self { - protocol_state: ProtocolContractState::Running( - RunningContractState::new( - DomainRegistry::default(), - Keyset::new(EpochId::new(0), Vec::new()), - parameters, - ), - ), - pending_signature_requests: LookupMap::new( - StorageKey::PendingSignatureRequestsV2, - ), - pending_ckd_requests: LookupMap::new(StorageKey::PendingCKDRequests), - proposed_updates: ProposedUpdates::default(), - config: init_config.map(Into::into).unwrap_or_default(), - tee_state, - accept_requests: true, - node_migrations: NodeMigrations::default(), - }) - } - pub fn init_running( - domains: Vec, - next_domain_id: u64, - keyset: Keyset, - parameters: ThresholdParameters, - init_config: Option, - ) -> Result { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "init_running: signer={0}, domains={1:?}, keyset={2:?}, parameters={3:?}, init_config={4:?}", - env::signer_account_id(), - domains, - keyset, - parameters, - init_config, - ), - ); - res - }) - .as_str(), - ); - parameters.validate()?; - let domains = DomainRegistry::from_raw_validated(domains, next_domain_id)?; - let domain_ids_from_domains = domains - .domains() - .iter() - .map(|d| d.id) - .collect::>(); - let domain_ids_from_keyset = keyset - .domains - .iter() - .map(|k| k.domain_id) - .collect::>(); - if domain_ids_from_domains != domain_ids_from_keyset { - return Err(DomainError::DomainsMismatch.into()); - } - let initial_participants = parameters.participants(); - let tee_state = TeeState::with_mocked_participant_attestations( - initial_participants, - ); - Ok(MpcContract { - config: init_config.map(Into::into).unwrap_or_default(), - protocol_state: ProtocolContractState::Running( - RunningContractState::new(domains, keyset, parameters), - ), - pending_signature_requests: LookupMap::new( - StorageKey::PendingSignatureRequestsV2, - ), - pending_ckd_requests: LookupMap::new(StorageKey::PendingCKDRequests), - proposed_updates: Default::default(), - tee_state, - accept_requests: true, - node_migrations: NodeMigrations::default(), - }) - } - /// This will be called internally by the contract to migrate the state when a new contract - /// is deployed. This function should be changed every time state is changed to do the proper - /// migrate flow. - /// - /// If nothing is changed, then this function will just return the current state. If it fails - /// to read the state, then it will return an error. - pub fn migrate() -> Result { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format(format_args!("migrating contract")); - res - }) - .as_str(), - ); - Self::migrate_cleanup(); - match try_state_read::() { - Ok(Some(state)) => return Ok(state.into()), - Ok(None) => return Err(InvalidState::ContractStateIsMissing.into()), - Err(err) => { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "failed to deserialize state into 3_0_2 state: {0:?}", - err, - ), - ); - res - }) - .as_str(), - ); - } - }; - match try_state_read::() { - Ok(Some(state)) => return Ok(state.into()), - Ok(None) => return Err(InvalidState::ContractStateIsMissing.into()), - Err(err) => { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "failed to deserialize state into 3_2_0 state: {0:?}", - err, - ), - ); - res - }) - .as_str(), - ); - } - }; - match try_state_read::() { - Ok(Some(state)) => Ok(state), - Ok(None) => Err(InvalidState::ContractStateIsMissing.into()), - Err(err) => { - env::panic_str( - &::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "could not deserialize contract state: {0}", - err, - ), - ); - res - }), - ) - } - } - } - /// `Self::migrate` often runs out of the 300Tgas max gas limit, due to expensive cleanups - /// that are performed during the upgrade. - /// - /// Expensive operations that - pub fn migrate_cleanup() { - let mut participants_attestations: IterableMap< - near_sdk::PublicKey, - (NodeId, Attestation), - > = IterableMap::new(StorageKey::_DeprecatedTeeParticipantAttestation); - let mut entries = 0; - for k in participants_attestations.values() { - entries += 1; - } - match (&entries, &0) { - (left_val, right_val) => { - if *left_val == *right_val { - let kind = ::core::panicking::AssertKind::Ne; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::None, - ); - } - } - }; - participants_attestations.clear(); - } - pub fn state(&self) -> &ProtocolContractState { - &self.protocol_state - } - /// Returns all allowed code hashes in order from most recent to least recent allowed code hashes. The first element is the most recent allowed code hash. - pub fn allowed_docker_image_hashes(&self) -> Vec { - let tee_upgrade_deadline_duration = Duration::from_secs( - self.config.tee_upgrade_deadline_duration_seconds, - ); - let mut hashes: Vec = self - .tee_state - .get_allowed_mpc_docker_images(tee_upgrade_deadline_duration) - .into_iter() - .map(|allowed_image_hash| allowed_image_hash.image_hash) - .collect(); - hashes.reverse(); - hashes - } - pub fn allowed_launcher_compose_hashes(&self) -> Vec { - self.tee_state.allowed_launcher_compose_hashes.clone() - } - pub fn get_pending_request(&self, request: &SignatureRequest) -> Option { - self.pending_signature_requests.get(request).cloned() - } - pub fn get_pending_ckd_request(&self, request: &CKDRequest) -> Option { - self.pending_ckd_requests.get(request).cloned() - } - pub fn config(&self) -> dtos::Config { - dtos::Config::from(&self.config) - } - pub fn version() -> String { - "3.2.0".to_string() - } - /// Upon success, removes the signature from state and returns it. - /// If the signature request times out, removes the signature request from state and panics to - /// fail the original transaction - pub fn return_signature_and_clean_state_on_success( - &mut self, - request: SignatureRequest, - signature: Result, - ) -> PromiseOrValue { - match signature { - Ok(signature) => PromiseOrValue::Value(signature), - Err(_) => { - self.pending_signature_requests.remove(&request); - let fail_on_timeout_gas = Gas::from_tgas( - self.config.fail_on_timeout_tera_gas, - ); - let promise = Promise::new(env::current_account_id()) - .function_call( - "fail_on_timeout".to_string(), - ::alloc::vec::Vec::new(), - NearToken::from_near(0), - fail_on_timeout_gas, - ); - near_sdk::PromiseOrValue::Promise(promise.as_return()) - } - } - } - /// Upon success, removes the confidential key from state and returns it. - /// If the ckd request times out, removes the ckd request from state and panics to fail the - /// original transaction - pub fn return_ck_and_clean_state_on_success( - &mut self, - request: CKDRequest, - ck: Result, - ) -> PromiseOrValue { - match ck { - Ok(ck) => PromiseOrValue::Value(ck), - Err(_) => { - self.pending_ckd_requests.remove(&request); - let fail_on_timeout_gas = Gas::from_tgas( - self.config.fail_on_timeout_tera_gas, - ); - let promise = Promise::new(env::current_account_id()) - .function_call( - "fail_on_timeout".to_string(), - ::alloc::vec::Vec::new(), - NearToken::from_near(0), - fail_on_timeout_gas, - ); - near_sdk::PromiseOrValue::Promise(promise.as_return()) - } - } - } - pub fn fail_on_timeout() { - env::panic_str(&RequestError::Timeout.to_string()); - } - pub fn update_config(&mut self, config: dtos::Config) { - self.config = config.into(); - } - /// Get our own account id as a voter. Returns an error if we are not a participant. - fn voter_account(&self) -> Result { - if !Self::caller_is_signer() { - return Err(InvalidParameters::CallerNotSigner.into()); - } - let voter = env::signer_account_id().as_v2_account_id(); - self.protocol_state.authenticate_update_vote()?; - Ok(voter) - } - /// Returns true if the caller is the signer account. - fn caller_is_signer() -> bool { - let signer = env::signer_account_id(); - let predecessor = env::predecessor_account_id(); - signer == predecessor - } - /// Get our own account id as a voter. If we are not a participant, panic. - /// also ensures that the caller is the signer account. - fn voter_or_panic(&self) -> AccountId { - Self::assert_caller_is_signer(); - match self.voter_account() { - Ok(voter) => voter, - Err(err) => { - env::panic_str( - &::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!("not a voter, {0:?}", err), - ); - res - }), - ) - } - } - } - /// Ensures that the caller is an attested participant - /// in the currently active protocol phase. - /// - /// Active phases: - /// - `Initializing` → uses proposed participants from generating_key - /// - `Running` → uses current active participants - /// - `Resharing` → uses new participants from resharing proposal - /// - /// Panics if: - /// - The protocol is not active (e.g., NotInitialized) - /// - The caller is not attested or not in the relevant participants set - /// - The caller is not the signer account - fn assert_caller_is_attested_participant_and_protocol_active(&self) { - let participants = self.protocol_state.active_participants(); - Self::assert_caller_is_signer(); - let attestation_check = self - .tee_state - .is_caller_an_attested_participant(participants); - match attestation_check { - Ok(()) => {} - ref e => { - ::std::rt::panic_fmt( - format_args!( - "assertion failed: `{0:?}` does not match `{1}`: {2}", - e, - "Ok(())", - format_args!("Caller must be an attested participant"), - ), - ); - } - }; - } - /// Ensures the current call originates from the signer account itself. - /// Panics if `signer_account_id` and `predecessor_account_id` differ. - fn assert_caller_is_signer() -> AccountId { - let signer_id = env::signer_account_id(); - let predecessor_id = env::predecessor_account_id(); - match (&signer_id, &predecessor_id) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "Caller must be the signer account (signer: {0}, predecessor: {1})", - signer_id, - predecessor_id, - ), - ), - ); - } - } - }; - signer_id.as_v2_account_id() - } -} -impl MpcContractExt { - pub fn migration_info(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("migration_info"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn register_backup_service( - self, - backup_service_info: BackupServiceInfo, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - backup_service_info: &'nearinput BackupServiceInfo, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "backup_service_info", - &self.backup_service_info, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - backup_service_info: &backup_service_info, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("register_backup_service"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn start_node_migration( - self, - destination_node_info: DestinationNodeInfo, - ) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - destination_node_info: &'nearinput DestinationNodeInfo, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "destination_node_info", - &self.destination_node_info, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { - destination_node_info: &destination_node_info, - }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("start_node_migration"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn conclude_node_migration(self, keyset: &Keyset) -> ::near_sdk::Promise { - let __args = { - #[serde(crate = "::near_sdk::serde")] - struct Input<'nearinput> { - keyset: &'nearinput Keyset, - } - #[doc(hidden)] - #[allow( - non_upper_case_globals, - unused_attributes, - unused_qualifications, - clippy::absolute_paths, - )] - const _: () = { - use ::near_sdk::serde as _serde; - #[automatically_derived] - impl<'nearinput> _serde::Serialize for Input<'nearinput> { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private228::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Input", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "keyset", - &self.keyset, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - let __args = Input { keyset: &keyset }; - match near_sdk::serde_json::to_vec(&__args) { - Ok(serialized) => serialized, - Err(_) => { - ::near_sdk::env::panic_str( - "Failed to serialize the cross contract args using JSON.", - ) - } - } - }; - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("conclude_node_migration"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } - pub fn cleanup_orphaned_node_migrations(self) -> ::near_sdk::Promise { - let __args = ::alloc::vec::Vec::new(); - match self.promise_or_create_on { - ::near_sdk::PromiseOrValue::Promise(p) => p, - ::near_sdk::PromiseOrValue::Value(account_id) => { - ::near_sdk::Promise::new(account_id) - } - } - .function_call_weight( - ::std::string::String::from("cleanup_orphaned_node_migrations"), - __args, - self.deposit, - self.static_gas, - self.gas_weight, - ) - } -} -/// Methods for Migration service -impl MpcContract { - pub fn migration_info( - &self, - ) -> BTreeMap, Option)> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format(format_args!("migration_info")); - res - }) - .as_str(), - ); - self.node_migrations.get_all() - } - /// Registers or updates the backup service information for the caller account. - /// - /// The caller (`signer_account_id`) must be an existing or prospective participant. - /// Otherwise, the transaction will fail. - /// - /// # Notes - /// - A deposit requirement may be added in the future. - pub fn register_backup_service( - &mut self, - backup_service_info: BackupServiceInfo, - ) -> Result<(), Error> { - let account_id = Self::assert_caller_is_signer(); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "register_backup_service: signer={0:?}, backup_service_info={1:?}", - account_id, - backup_service_info, - ), - ); - res - }) - .as_str(), - ); - if !self.protocol_state.is_existing_or_prospective_participant(&account_id)? { - return Err( - errors::InvalidState::NotParticipant - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "account: {0} is not in the set of curent or prospective participants and not eligible to store backup service information", - account_id, - ), - ); - res - }), - ), - ); - } - self.node_migrations.set_backup_service_info(account_id, backup_service_info); - Ok(()) - } - /// Sets the destination node for the calling account. - /// - /// This function can only be called while the protocol is in a `Running` state. - /// The signer must be a current participant of the current epoch, otherwise an error is returned. - /// On success, the provided [`DestinationNodeInfo`] is stored in the contract state - /// under the signer’s account ID. - /// - /// # Errors - /// - [`InvalidState::ProtocolStateNotRunning`] if the protocol is not in the `Running` state. - /// - [`InvalidState::NotParticipant`] if the signer is not a current participant. - /// # Note: - /// - might require a deposit - pub fn start_node_migration( - &mut self, - destination_node_info: DestinationNodeInfo, - ) -> Result<(), Error> { - let account_id = Self::assert_caller_is_signer(); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "start_node_migration: signer={0:?}, destination_node_info={1:?}", - account_id, - destination_node_info, - ), - ); - res - }) - .as_str(), - ); - let ProtocolContractState::Running(running_state) = &self.protocol_state else { - return Err( - errors::InvalidState::ProtocolStateNotRunning - .message( - "migration of nodes is only possible while the protocol is in `Running` state." - .to_string(), - ), - ); - }; - if !running_state.is_participant(&account_id) { - return Err( - errors::InvalidState::NotParticipant - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "account: {0} is not in the set of curent participants and thus not eligible to initiate a node migration.", - account_id, - ), - ); - res - }), - ), - ); - } - self.node_migrations - .set_destination_node_info(account_id, destination_node_info); - Ok(()) - } - /// Finalizes a node migration for the calling account. - /// - /// This method can only be called while the protocol is in a `Running` state - /// and by an existing participant. On success, the participant’s information is - /// updated to the new destination node. - /// - /// # Errors - /// Returns the following errors: - /// - `InvalidState::ProtocolStateNotRunning`: if protocol is not in `Running` state - /// - `InvalidState::NotParticipant`: if caller is not a current participant - /// - `NodeMigrationError::KeysetMismatch`: if provided keyset does not match the expected keyset - /// - `NodeMigrationError::MigrationNotFound`: if no migration record exists for the caller - /// - `NodeMigrationError::AccountPublicKeyMismatch`: if caller’s public key does not match the expected destination node - /// - `InvalidParameters::InvalidTeeRemoteAttestation`: if destination node’s TEE quote is invalid - pub fn conclude_node_migration(&mut self, keyset: &Keyset) -> Result<(), Error> { - let account_id = Self::assert_caller_is_signer(); - let signer_pk = env::signer_account_pk(); - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "conclude_node_migration: signer={0:?}, signer_pk={1:?} keyset={2:?}", - account_id, - signer_pk, - keyset, - ), - ); - res - }) - .as_str(), - ); - let ProtocolContractState::Running(running_state) = &mut self.protocol_state - else { - return Err( - errors::InvalidState::ProtocolStateNotRunning - .message( - "migration of nodes is only possible while the protocol is in `Running` state." - .to_string(), - ), - ); - }; - if !running_state.is_participant(&account_id) { - return Err( - errors::InvalidState::NotParticipant - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "account: {0} is not in the set of curent participants and thus eligible to initiate a node migration.", - account_id, - ), - ); - res - }), - ), - ); - } - let expected_keyset = &running_state.keyset; - if expected_keyset != keyset { - return Err( - errors::NodeMigrationError::KeysetMismatch - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "keyset={0:?}, expected_keyset={1:?}", - keyset, - expected_keyset, - ), - ); - res - }), - ), - ); - } - let Some(expected_destination_node) = self - .node_migrations - .remove_migration(&account_id) else { - return Err(errors::NodeMigrationError::MigrationNotFound.into()); - }; - if expected_destination_node.signer_account_pk != signer_pk { - return Err( - errors::NodeMigrationError::AccountPublicKeyMismatch - .message( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "found {0:?}, expected {1:?}", - signer_pk, - expected_destination_node.signer_account_pk, - ), - ); - res - }), - ), - ); - } - let node_id = NodeId { - account_id: account_id.clone(), - account_public_key: Some( - expected_destination_node.signer_account_pk.clone(), - ), - tls_public_key: expected_destination_node - .destination_node_info - .sign_pk - .clone(), - }; - if !(match self - .tee_state - .reverify_participants( - &node_id, - Duration::from_secs(self.config.tee_upgrade_deadline_duration_seconds), - ) - { - TeeQuoteStatus::Valid => true, - _ => false, - }) { - return Err(errors::InvalidParameters::InvalidTeeRemoteAttestation.into()); - } - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "Moving Account {0:?} to {1:?}", - account_id, - expected_destination_node.destination_node_info, - ), - ); - res - }) - .as_str(), - ); - running_state - .parameters - .update_info(account_id, expected_destination_node.destination_node_info)?; - Ok(()) - } - pub fn cleanup_orphaned_node_migrations(&mut self) -> Result<(), Error> { - ::near_sdk::env::log_str( - ::alloc::__export::must_use({ - let res = ::alloc::fmt::format( - format_args!( - "cleanup_orphaned_node_migrations signer={0:?}", - env::signer_account_id(), - ), - ); - res - }) - .as_str(), - ); - let backup_services: Vec = self - .node_migrations - .backup_services_info() - .keys() - .cloned() - .collect(); - for account_id in &backup_services { - if !self.protocol_state.is_existing_or_prospective_participant(account_id)? { - self.node_migrations.remove_account_data(account_id); - } - } - Ok(()) - } -} -fn try_state_read() -> Result, std::io::Error> { - env::storage_read(b"STATE").map(|data| T::try_from_slice(&data)).transpose() -} From 07b937d57c91b3a978461308006db8bf9de09b14 Mon Sep 17 00:00:00 2001 From: Daniel Sharifi Date: Mon, 12 Jan 2026 12:36:15 +0100 Subject: [PATCH 8/8] remove commented out code --- crates/contract/src/v3_0_2_state.rs | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/crates/contract/src/v3_0_2_state.rs b/crates/contract/src/v3_0_2_state.rs index 0c5bbfe2f..1a7634f68 100644 --- a/crates/contract/src/v3_0_2_state.rs +++ b/crates/contract/src/v3_0_2_state.rs @@ -103,33 +103,6 @@ struct TeeState { participants_attestations: IterableMap, } -// #[derive(Debug, BorshDeserialize)] -// enum ProtocolContractState { -// NotInitialized, -// Initializing, -// Running(RunningContractState), -// Resharing, -// } - -// #[derive(Debug, BorshDeserialize)] -// pub struct RunningContractState { -// /// The domains for which we have a key ready for signature processing. -// pub domains: DomainRegistry, -// /// The keys that are currently in use; for each domain provides an unique identifier for a -// /// distributed key, so that the nodes can identify which local keyshare to use. -// pub keyset: Keyset, -// /// The current participants and threshold. -// pub parameters: ThresholdParameters, -// /// Votes for proposals for a new set of participants and threshold. -// pub parameters_votes: ThresholdParametersVotes, -// /// Votes for proposals to add new domains. -// pub add_domains_votes: AddDomainsVotes, -// /// The previous epoch id for a resharing state that was cancelled. -// /// This epoch id is tracked, as the next time the state transitions to resharing, -// /// we can't reuse a previously cancelled epoch id. -// pub previously_cancelled_resharing_epoch_id: Option, -// } - #[derive(Debug, BorshDeserialize)] pub struct MpcContract { protocol_state: ProtocolContractState,