Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change extension bytes data to base58 encoded #232

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 43 additions & 158 deletions blockbuster/src/programs/token_extensions/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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)]
Expand All @@ -216,114 +187,6 @@ pub struct ShadowMetadata {
pub additional_metadata: Vec<(String, String)>,
}

impl Serialize for ShadowAeCiphertext {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
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<E>(self, v: &[u8]) -> Result<Self::Value, E>
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<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_bytes(ShadowElGamalCiphertextVisitor)
}
}

impl Default for ShadowElGamalCiphertext {
fn default() -> Self {
ShadowElGamalCiphertext([0u8; ELGAMAL_CIPHERTEXT_LEN])
}
}
kespinola marked this conversation as resolved.
Show resolved Hide resolved

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<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
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<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_tuple(AE_CIPHERTEXT_LEN, ShadowAeCiphertextVisitor)
}
}

impl Serialize for ShadowElGamalCiphertext {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(&self.0)
}
}

impl From<AeCiphertext> for ShadowAeCiphertext {
fn from(original: AeCiphertext) -> Self {
ShadowAeCiphertext(original.0)
}
}

impl From<ElGamalCiphertext> for ShadowElGamalCiphertext {
fn from(original: ElGamalCiphertext) -> Self {
ShadowElGamalCiphertext(original.0)
}
}

impl From<ElGamalPubkey> for ShadowElGamalPubkey {
fn from(original: ElGamalPubkey) -> Self {
ShadowElGamalPubkey(original.0)
}
}

impl From<CpiGuard> for ShadowCpiGuard {
fn from(original: CpiGuard) -> Self {
ShadowCpiGuard {
Expand All @@ -343,7 +206,7 @@ impl From<DefaultAccountState> for ShadowDefaultAccountState {
impl From<ConfidentialTransferFeeAmount> for ShadowConfidentialTransferFeeAmount {
fn from(original: ConfidentialTransferFeeAmount) -> Self {
ShadowConfidentialTransferFeeAmount {
withheld_amount: original.withheld_amount.into(),
withheld_amount: original.withheld_amount.to_base58(),
}
}
}
Expand Down Expand Up @@ -384,7 +247,7 @@ impl From<TokenGroup> 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,
}
Expand All @@ -394,8 +257,8 @@ impl From<TokenGroup> for ShadowTokenGroup {
impl From<TokenGroupMember> 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,
}
}
Expand Down Expand Up @@ -482,11 +345,11 @@ impl From<ConfidentialTransferAccount> 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,
Expand All @@ -504,9 +367,9 @@ impl From<ConfidentialTransferFeeConfig> 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(),
}
}
}
Expand All @@ -523,3 +386,25 @@ impl From<TokenMetadata> 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()
}
}
2 changes: 1 addition & 1 deletion digital_asset_types/src/dao/scopes/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,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)
Expand Down
4 changes: 2 additions & 2 deletions digital_asset_types/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
19 changes: 14 additions & 5 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,25 @@ 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:
POSTGRES_USER: solana # The PostgreSQL user (useful to connect to the database)
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
kespinola marked this conversation as resolved.
Show resolved Hide resolved
solana:
image: ghcr.io/metaplex-foundation/plerkle-test-validator:v1.9.0-1.75.0-v1.18.11
volumes:
Expand All @@ -113,5 +122,5 @@ services:
- "8899:8899"
- "9900:9900"
volumes:
grafana_data: { }
graphite_data: { }
grafana_data: {}
graphite_data: {}
Loading