diff --git a/blockbuster/src/programs/token_extensions/extension.rs b/blockbuster/src/programs/token_extensions/extension.rs index 6dba2b57c..816238cba 100644 --- a/blockbuster/src/programs/token_extensions/extension.rs +++ b/blockbuster/src/programs/token_extensions/extension.rs @@ -21,28 +21,12 @@ use spl_token_2022::extension::{ transfer_fee::{TransferFee, TransferFeeAmount, TransferFeeConfig}, transfer_hook::TransferHook, }; -use std::fmt; use spl_token_group_interface::state::{TokenGroup, TokenGroupMember}; use spl_token_metadata_interface::state::TokenMetadata; -const AE_CIPHERTEXT_LEN: usize = 36; -const UNIT_LEN: usize = 32; -const RISTRETTO_POINT_LEN: usize = UNIT_LEN; -pub(crate) const DECRYPT_HANDLE_LEN: usize = RISTRETTO_POINT_LEN; -pub(crate) const PEDERSEN_COMMITMENT_LEN: usize = RISTRETTO_POINT_LEN; -const ELGAMAL_PUBKEY_LEN: usize = RISTRETTO_POINT_LEN; -const ELGAMAL_CIPHERTEXT_LEN: usize = PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN; type PodAccountState = u8; pub type UnixTimestamp = PodI64; -pub type EncryptedBalance = ShadowElGamalCiphertext; -pub type DecryptableBalance = ShadowAeCiphertext; -pub type EncryptedWithheldAmount = ShadowElGamalCiphertext; - -use serde::{ - de::{self, SeqAccess, Visitor}, - Deserializer, Serializer, -}; /// Bs58 encoded public key string. Used for storing Pubkeys in a human readable format. /// Ideally we'd store them as is in the DB and later convert them to bs58 for display on the API. @@ -53,19 +37,6 @@ use serde::{ /// - `Pubkey` doesn't implement something like `schemars::JsonSchema` so we can't convert them back to the rust struct either. type PublicKeyString = String; -struct ShadowAeCiphertextVisitor; - -struct ShadowElGamalCiphertextVisitor; - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct ShadowAeCiphertext(pub [u8; AE_CIPHERTEXT_LEN]); - -#[derive(Clone, Copy, Debug, PartialEq, Zeroable)] -pub struct ShadowElGamalCiphertext(pub [u8; ELGAMAL_CIPHERTEXT_LEN]); - -#[derive(Clone, Copy, Debug, Default, Zeroable, PartialEq, Eq, Serialize, Deserialize)] -pub struct ShadowElGamalPubkey(pub [u8; ELGAMAL_PUBKEY_LEN]); - #[derive(Clone, Copy, Debug, Default, PartialEq, Zeroable, Serialize, Deserialize)] pub struct ShadowCpiGuard { pub lock_cpi: PodBool, @@ -164,14 +135,14 @@ pub struct ShadowConfidentialTransferMint { pub auditor_elgamal_pubkey: OptionalNonZeroElGamalPubkey, } -#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct ShadowConfidentialTransferAccount { pub approved: PodBool, - pub elgamal_pubkey: ShadowElGamalPubkey, - pub pending_balance_lo: EncryptedBalance, - pub pending_balance_hi: EncryptedBalance, - pub available_balance: EncryptedBalance, - pub decryptable_available_balance: DecryptableBalance, + pub elgamal_pubkey: String, + pub pending_balance_lo: String, + pub pending_balance_hi: String, + pub available_balance: String, + pub decryptable_available_balance: String, pub allow_confidential_credits: PodBool, pub allow_non_confidential_credits: PodBool, pub pending_balance_credit_counter: PodU64, @@ -180,16 +151,16 @@ pub struct ShadowConfidentialTransferAccount { pub actual_pending_balance_credit_counter: PodU64, } -#[derive(Clone, Copy, Debug, Default, PartialEq, Zeroable, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct ShadowConfidentialTransferFeeConfig { pub authority: OptionalNonZeroPubkey, - pub withdraw_withheld_authority_elgamal_pubkey: ShadowElGamalPubkey, + pub withdraw_withheld_authority_elgamal_pubkey: String, pub harvest_to_mint_enabled: PodBool, - pub withheld_amount: EncryptedWithheldAmount, + pub withheld_amount: String, } pub struct ShadowConfidentialTransferFeeAmount { - pub withheld_amount: EncryptedWithheldAmount, + pub withheld_amount: String, } #[derive(Clone, Copy, Debug, Default, PartialEq, Zeroable, Serialize, Deserialize)] @@ -216,114 +187,6 @@ pub struct ShadowMetadata { pub additional_metadata: Vec<(String, String)>, } -impl Serialize for ShadowAeCiphertext { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_bytes(&self.0) - } -} - -impl<'de> Visitor<'de> for ShadowElGamalCiphertextVisitor { - type Value = ShadowElGamalCiphertext; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a byte array of length ELGAMAL_CIPHERTEXT_LEN") - } - - fn visit_bytes(self, v: &[u8]) -> Result - where - E: de::Error, - { - if v.len() == ELGAMAL_CIPHERTEXT_LEN { - let mut arr = [0u8; ELGAMAL_CIPHERTEXT_LEN]; - arr.copy_from_slice(v); - Ok(ShadowElGamalCiphertext(arr)) - } else { - Err(E::invalid_length(v.len(), &self)) - } - } -} - -impl<'de> Deserialize<'de> for ShadowElGamalCiphertext { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_bytes(ShadowElGamalCiphertextVisitor) - } -} - -impl Default for ShadowElGamalCiphertext { - fn default() -> Self { - ShadowElGamalCiphertext([0u8; ELGAMAL_CIPHERTEXT_LEN]) - } -} - -impl Default for ShadowAeCiphertext { - fn default() -> Self { - ShadowAeCiphertext([0u8; AE_CIPHERTEXT_LEN]) - } -} - -impl<'de> Visitor<'de> for ShadowAeCiphertextVisitor { - type Value = ShadowAeCiphertext; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("a byte array of length AE_CIPHERTEXT_LEN") - } - - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - let mut arr = [0u8; AE_CIPHERTEXT_LEN]; - for (i, item) in arr.iter_mut().enumerate().take(AE_CIPHERTEXT_LEN) { - *item = seq - .next_element()? - .ok_or(de::Error::invalid_length(i, &self))?; - } - Ok(ShadowAeCiphertext(arr)) - } -} - -impl<'de> Deserialize<'de> for ShadowAeCiphertext { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_tuple(AE_CIPHERTEXT_LEN, ShadowAeCiphertextVisitor) - } -} - -impl Serialize for ShadowElGamalCiphertext { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_bytes(&self.0) - } -} - -impl From for ShadowAeCiphertext { - fn from(original: AeCiphertext) -> Self { - ShadowAeCiphertext(original.0) - } -} - -impl From for ShadowElGamalCiphertext { - fn from(original: ElGamalCiphertext) -> Self { - ShadowElGamalCiphertext(original.0) - } -} - -impl From for ShadowElGamalPubkey { - fn from(original: ElGamalPubkey) -> Self { - ShadowElGamalPubkey(original.0) - } -} - impl From for ShadowCpiGuard { fn from(original: CpiGuard) -> Self { ShadowCpiGuard { @@ -343,7 +206,7 @@ impl From for ShadowDefaultAccountState { impl From for ShadowConfidentialTransferFeeAmount { fn from(original: ConfidentialTransferFeeAmount) -> Self { ShadowConfidentialTransferFeeAmount { - withheld_amount: original.withheld_amount.into(), + withheld_amount: original.withheld_amount.to_base58(), } } } @@ -384,7 +247,7 @@ impl From for ShadowTokenGroup { fn from(original: TokenGroup) -> Self { ShadowTokenGroup { update_authority: original.update_authority, - mint: bs58::encode(original.mint).into_string(), + mint: original.mint.to_string(), size: original.size, max_size: original.max_size, } @@ -394,8 +257,8 @@ impl From for ShadowTokenGroup { impl From for ShadowTokenGroupMember { fn from(original: TokenGroupMember) -> Self { ShadowTokenGroupMember { - mint: bs58::encode(original.mint).into_string(), - group: bs58::encode(original.group).into_string(), + mint: original.mint.to_string(), + group: original.group.to_string(), member_number: original.member_number, } } @@ -482,11 +345,11 @@ impl From for ShadowConfidentialTransferAccount { fn from(original: ConfidentialTransferAccount) -> Self { ShadowConfidentialTransferAccount { approved: original.approved, - elgamal_pubkey: original.elgamal_pubkey.into(), - pending_balance_lo: original.pending_balance_lo.into(), - pending_balance_hi: original.pending_balance_hi.into(), - available_balance: original.available_balance.into(), - decryptable_available_balance: original.decryptable_available_balance.into(), + elgamal_pubkey: original.elgamal_pubkey.to_base58(), + pending_balance_lo: original.pending_balance_lo.to_base58(), + pending_balance_hi: original.pending_balance_hi.to_base58(), + available_balance: original.available_balance.to_base58(), + decryptable_available_balance: original.decryptable_available_balance.to_base58(), allow_confidential_credits: original.allow_confidential_credits, allow_non_confidential_credits: original.allow_non_confidential_credits, pending_balance_credit_counter: original.pending_balance_credit_counter, @@ -504,9 +367,9 @@ impl From for ShadowConfidentialTransferFeeConfig authority: original.authority, withdraw_withheld_authority_elgamal_pubkey: original .withdraw_withheld_authority_elgamal_pubkey - .into(), + .to_base58(), harvest_to_mint_enabled: original.harvest_to_mint_enabled, - withheld_amount: original.withheld_amount.into(), + withheld_amount: original.withheld_amount.to_base58(), } } } @@ -523,3 +386,25 @@ impl From for ShadowMetadata { } } } + +trait FromBytesToBase58 { + fn to_base58(&self) -> String; +} + +impl FromBytesToBase58 for ElGamalPubkey { + fn to_base58(&self) -> String { + bs58::encode(self.0).into_string() + } +} + +impl FromBytesToBase58 for ElGamalCiphertext { + fn to_base58(&self) -> String { + bs58::encode(self.0).into_string() + } +} + +impl FromBytesToBase58 for AeCiphertext { + fn to_base58(&self) -> String { + bs58::encode(self.0).into_string() + } +} diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index c241c4c4e..553c73f6e 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -761,7 +761,7 @@ pub async fn get_nft_editions( Pagination::Page { page } => (Some(*page as u32), None, None, None), Pagination::Cursor(_) => { if let Some(last_asset) = nft_editions.last() { - let cursor_str = bs58::encode(last_asset.edition_address.clone()).into_string(); + let cursor_str = last_asset.edition_address.clone(); (None, None, None, Some(cursor_str)) } else { (None, None, None, None) diff --git a/digital_asset_types/tests/common.rs b/digital_asset_types/tests/common.rs index 6f40f610e..20989cf45 100644 --- a/digital_asset_types/tests/common.rs +++ b/digital_asset_types/tests/common.rs @@ -234,12 +234,12 @@ pub fn create_asset_grouping( asset_grouping::ActiveModel { asset_id: Set(asset_id.clone()), group_key: Set(String::from("collection")), - group_value: Set(Some(bs58::encode(collection).into_string())), + group_value: Set(Some(collection.to_string())), ..Default::default() }, asset_grouping::Model { asset_id, - group_value: Some(bs58::encode(collection).into_string()), + group_value: Some(collection.to_string()), seq: Some(0), id: row_num, group_key: "collection".to_string(), diff --git a/docker-compose.yaml b/docker-compose.yaml index 292f1ead7..4f5bfd93f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -87,8 +87,17 @@ services: ports: - "6379:6379" db: - image: 'postgres:14' - command: [ "postgres", "-c", "log_statement=all", "-c", "log_destination=stderr" ,"-c","max_connections=200" ] + image: "postgres:14" + command: + [ + "postgres", + "-c", + "log_statement=all", + "-c", + "log_destination=stderr", + "-c", + "max_connections=200", + ] ports: - 5432:5432 environment: @@ -96,7 +105,7 @@ services: POSTGRES_PASSWORD: solana # The PostgreSQL password (useful to connect to the database) POSTGRES_DB: solana volumes: - - ./db-data/:/var/lib/postgresql/data/:rw + - ./db-data/:/var/lib/postgresql/data/:z solana: image: ghcr.io/metaplex-foundation/plerkle-test-validator:v1.9.0-1.75.0-v1.18.11 volumes: @@ -113,5 +122,5 @@ services: - "8899:8899" - "9900:9900" volumes: - grafana_data: { } - graphite_data: { } + grafana_data: {} + graphite_data: {} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap index 75c59b24b..5c42e8689 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs expression: response +snapshot_kind: text --- { "interface": "FungibleToken", @@ -89,107 +90,9 @@ expression: response }, "confidential_transfer_fee_config": { "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", - "withheld_amount": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], + "withheld_amount": "1111111111111111111111111111111111111111111111111111111111111111", "harvest_to_mint_enabled": true, - "withdraw_withheld_authority_elgamal_pubkey": [ - 28, - 55, - 230, - 67, - 59, - 115, - 4, - 221, - 130, - 115, - 122, - 228, - 13, - 155, - 139, - 243, - 196, - 159, - 91, - 14, - 108, - 73, - 168, - 213, - 51, - 40, - 179, - 229, - 6, - 144, - 28, - 87 - ] + "withdraw_withheld_authority_elgamal_pubkey": "2u9rVXG8n3sN1ChKwrkQZaWoPapzC49iBXd2Y9Kpg5cJ" } } }