#![allow(clippy::too_many_arguments)]
use crate::idl::arcium::{
accounts::{MXEAccount, MxeRecoveryAccount},
types::{AbortReason, ExecutionFailure, KeyRecoveryFailureReason, MxeStatus, SetUnset},
};
use anchor_lang::{
declare_program,
prelude::AccountMeta,
solana_program::instruction::Instruction,
};
use arcium::types::{
ArxNodeConfig,
CallbackAccount,
CallbackInstruction,
ComputationReference,
NodeMetadata,
NodeRef,
};
use std::hash::{Hash, Hasher};
pub const RESCUE_KEY_COUNT: usize = 5;
declare_program!(arcium);
#[cfg(feature = "staking")]
declare_program!(arcium_staking);
impl Hash for ComputationReference {
fn hash<H: Hasher>(&self, state: &mut H) {
self.computation_offset.hash(state);
self.priority_fee.hash(state);
}
}
impl Eq for ComputationReference {}
impl PartialEq for ComputationReference {
fn eq(&self, other: &Self) -> bool {
self.computation_offset == other.computation_offset
&& self.priority_fee == other.priority_fee
}
}
impl PartialEq for NodeMetadata {
fn eq(&self, other: &Self) -> bool {
self.location == other.location && self.ip == other.ip && self.peer_id == other.peer_id
}
}
impl PartialEq for ArxNodeConfig {
fn eq(&self, other: &Self) -> bool {
self.authority == other.authority && self.callback_authority == other.callback_authority
}
}
impl PartialEq for NodeRef {
fn eq(&self, other: &Self) -> bool {
self.offset == other.offset && self.current_total_rewards == other.current_total_rewards
}
}
impl PartialEq for MxeStatus {
fn eq(&self, other: &Self) -> bool {
matches!(
(self, other),
(MxeStatus::Active, MxeStatus::Active) | (MxeStatus::Migration, MxeStatus::Migration)
)
}
}
impl MXEAccount {
pub fn x25519_pubkey(&self) -> Option<[u8; 32]> {
match &self.utility_pubkeys {
SetUnset::Set(keys) => Some(keys.x25519_pubkey),
SetUnset::Unset(keys, set_vec) => {
if set_vec.iter().all(|&b| b) {
Some(keys.x25519_pubkey)
} else {
None
}
}
}
}
pub fn ed25519_verifying_key(&self) -> Option<[u8; 32]> {
match &self.utility_pubkeys {
SetUnset::Set(keys) => Some(keys.ed25519_verifying_key),
SetUnset::Unset(keys, set_vec) => {
if set_vec.iter().all(|&b| b) {
Some(keys.ed25519_verifying_key)
} else {
None
}
}
}
}
pub fn elgamal_pubkey(&self) -> Option<[u8; 32]> {
match &self.utility_pubkeys {
SetUnset::Set(keys) => Some(keys.elgamal_pubkey),
SetUnset::Unset(keys, set_vec) => {
if set_vec.iter().all(|&b| b) {
Some(keys.elgamal_pubkey)
} else {
None
}
}
}
}
}
impl ExecutionFailure {
pub fn discriminator(&self) -> u8 {
match self {
ExecutionFailure::Serialization => 0,
ExecutionFailure::Router => 1,
ExecutionFailure::Circuit => 2,
ExecutionFailure::Inputs => 3,
ExecutionFailure::ProtocolInit => 4,
ExecutionFailure::ProtocolRun => 5,
ExecutionFailure::OutputTooLarge => 6,
ExecutionFailure::TrustedDealer => 7,
ExecutionFailure::Abort(AbortReason::InvalidMAC) => 50,
ExecutionFailure::Abort(AbortReason::ExpectedSentShare) => 51,
ExecutionFailure::Abort(AbortReason::ExpectedFieldElement) => 52,
ExecutionFailure::Abort(AbortReason::ExpectedAbort) => 53,
ExecutionFailure::Abort(AbortReason::MalformedData) => 54,
ExecutionFailure::Abort(AbortReason::ComputationFailed) => 55,
ExecutionFailure::Abort(AbortReason::InternalError) => 56,
ExecutionFailure::Abort(AbortReason::PreprocessingStreamError) => 57,
ExecutionFailure::Abort(AbortReason::DivisionByZero) => 58,
ExecutionFailure::Abort(AbortReason::NoSignature) => 59,
ExecutionFailure::Abort(AbortReason::InvalidSignature) => 60,
ExecutionFailure::Abort(AbortReason::PrimitiveError) => 61,
ExecutionFailure::Abort(AbortReason::InvalidBatchLength) => 62,
ExecutionFailure::Abort(AbortReason::QuadraticNonResidue) => 63,
ExecutionFailure::Abort(AbortReason::BitConversionError) => 64,
ExecutionFailure::Abort(AbortReason::ChannelClosed) => 65,
ExecutionFailure::Abort(AbortReason::TimeoutElapsed) => 66,
ExecutionFailure::KeyRecoveryFailure(KeyRecoveryFailureReason::KeysDigestMismatch) => {
100
}
ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::X25519PubkeyMismatch,
) => 101,
ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::Ed25519VerifyingKeyMismatch,
) => 102,
ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::ElGamalPubkeyMismatch,
) => 103,
ExecutionFailure::KeyRecoveryFailure(KeyRecoveryFailureReason::TooManyCorruptPeers) => {
104
}
ExecutionFailure::KeyRecoveryFailure(KeyRecoveryFailureReason::NoPubkeysSet) => 105,
ExecutionFailure::KeyRecoveryFailure(KeyRecoveryFailureReason::Serialization) => 106,
}
}
pub fn from_discriminator(discriminator: u8) -> Option<Self> {
match discriminator {
0 => Some(ExecutionFailure::Serialization),
1 => Some(ExecutionFailure::Router),
2 => Some(ExecutionFailure::Circuit),
3 => Some(ExecutionFailure::Inputs),
4 => Some(ExecutionFailure::ProtocolInit),
5 => Some(ExecutionFailure::ProtocolRun),
6 => Some(ExecutionFailure::OutputTooLarge),
7 => Some(ExecutionFailure::TrustedDealer),
50 => Some(ExecutionFailure::Abort(AbortReason::InvalidMAC)),
51 => Some(ExecutionFailure::Abort(AbortReason::ExpectedSentShare)),
52 => Some(ExecutionFailure::Abort(AbortReason::ExpectedFieldElement)),
53 => Some(ExecutionFailure::Abort(AbortReason::ExpectedAbort)),
54 => Some(ExecutionFailure::Abort(AbortReason::MalformedData)),
55 => Some(ExecutionFailure::Abort(AbortReason::ComputationFailed)),
56 => Some(ExecutionFailure::Abort(AbortReason::InternalError)),
57 => Some(ExecutionFailure::Abort(
AbortReason::PreprocessingStreamError,
)),
58 => Some(ExecutionFailure::Abort(AbortReason::DivisionByZero)),
59 => Some(ExecutionFailure::Abort(AbortReason::NoSignature)),
60 => Some(ExecutionFailure::Abort(AbortReason::InvalidSignature)),
61 => Some(ExecutionFailure::Abort(AbortReason::PrimitiveError)),
62 => Some(ExecutionFailure::Abort(AbortReason::InvalidBatchLength)),
63 => Some(ExecutionFailure::Abort(AbortReason::QuadraticNonResidue)),
64 => Some(ExecutionFailure::Abort(AbortReason::BitConversionError)),
65 => Some(ExecutionFailure::Abort(AbortReason::ChannelClosed)),
66 => Some(ExecutionFailure::Abort(AbortReason::TimeoutElapsed)),
100 => Some(ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::KeysDigestMismatch,
)),
101 => Some(ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::X25519PubkeyMismatch,
)),
102 => Some(ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::Ed25519VerifyingKeyMismatch,
)),
103 => Some(ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::ElGamalPubkeyMismatch,
)),
104 => Some(ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::TooManyCorruptPeers,
)),
105 => Some(ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::NoPubkeysSet,
)),
106 => Some(ExecutionFailure::KeyRecoveryFailure(
KeyRecoveryFailureReason::Serialization,
)),
_ => None,
}
}
}
impl MxeRecoveryAccount {
pub fn n_peers_submitted_shares(&self) -> usize {
self.shares
.iter()
.filter(|&s| *s != [[0u8; 32]; RESCUE_KEY_COUNT])
.count()
}
}
impl CallbackInstruction {
pub fn to_instruction(&self, ix_data: &[u8]) -> Instruction {
let mut data = Vec::with_capacity(self.discriminator.len() + ix_data.len());
data.extend_from_slice(&self.discriminator);
data.extend_from_slice(ix_data);
Instruction {
program_id: self.program_id,
accounts: self.accounts.iter().map(|acc| acc.into()).collect(),
data,
}
}
}
impl From<&CallbackAccount> for AccountMeta {
fn from(acc: &CallbackAccount) -> Self {
AccountMeta {
pubkey: acc.pubkey,
is_signer: false,
is_writable: acc.is_writable,
}
}
}
#[cfg(feature = "staking")]
impl From<arcium_staking::types::Epoch> for arcium::types::Epoch {
fn from(val: arcium_staking::types::Epoch) -> Self {
arcium::types::Epoch(val.0)
}
}
#[cfg(feature = "staking")]
impl From<arcium::types::Epoch> for arcium_staking::types::Epoch {
fn from(val: arcium::types::Epoch) -> Self {
arcium_staking::types::Epoch(val.0)
}
}
#[repr(u8)]
pub enum BLSDomainSeparator {
Success = 0,
Failure = 1,
PoP = 2,
}