Skip to content

Commit

Permalink
feat(api): add showBurnt option to GetByMethodOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
armyhaylenko committed Jan 28, 2025
1 parent e9777ab commit ae1a8a9
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 5 deletions.
3 changes: 3 additions & 0 deletions entities/src/api_req_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ pub struct GetByMethodsOptions {
pub show_zero_balance: bool,
#[serde(default)]
pub show_fungible: bool,
#[serde(default)]
pub show_burnt: Option<bool>,
}

impl From<&SearchAssetsOptions> for Options {
Expand Down Expand Up @@ -591,6 +593,7 @@ impl From<SearchAssetsOptions> for GetByMethodsOptions {
show_inscription: value.show_inscription,
show_zero_balance: value.show_zero_balance,
show_fungible: false,
show_burnt: None,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions nft_ingester/src/api/dapi/converters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ impl TryFrom<GetAssetsByOwner> for SearchAssetsQuery {
validate_pubkey(asset_owner.owner_address).map(|k| k.to_bytes().to_vec())?,
),
supply: Some(AssetSupply::Greater(0)),
burnt: asset_owner.options.show_burnt,
..Default::default()
})
}
Expand Down
161 changes: 161 additions & 0 deletions nft_ingester/tests/api_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2090,6 +2090,167 @@ mod tests {
);
}

#[tokio::test]
#[tracing_test::traced_test]
async fn test_get_only_non_burnt_assets_by_owner() {
let cnt = 20;
let cli = Cli::default();
let (env, generated_assets) =
setup::TestEnvironment::create_burnt(&cli, cnt, SLOT_UPDATED).await;
let api = nft_ingester::api::api_impl::DasApi::<
MaybeProofChecker,
JsonWorker,
JsonWorker,
MockAccountBalanceGetter,
RaydiumTokenPriceFetcher,
Storage,
>::new(
env.pg_env.client.clone(),
env.rocks_env.storage.clone(),
Arc::new(ApiMetricsConfig::new()),
None,
None,
50,
None,
None,
JsonMiddlewareConfig::default(),
Arc::new(MockAccountBalanceGetter::new()),
None,
Arc::new(RaydiumTokenPriceFetcher::default()),
NATIVE_MINT_PUBKEY.to_string(),
);
let tasks = JoinSet::new();
let mutexed_tasks = Arc::new(Mutex::new(tasks));

let ref_value = generated_assets.owners[8].clone();
let payload = GetAssetsByOwner {
owner_address: ref_value.owner.value.map(|owner| owner.to_string()).unwrap_or_default(),
sort_by: None,
limit: None,
page: None,
before: None,
after: None,
cursor: None,
options: GetByMethodsOptions {
show_unverified_collections: true,
show_burnt: Some(false),
..Default::default()
},
};

let res = api.get_assets_by_owner(payload, mutexed_tasks.clone()).await.unwrap();
let res_obj: AssetList = serde_json::from_value(res).unwrap();

// in the setup all assets were created as burnt
// meaning that if we do not explicitly specify show_burnt
// in the options, the response will be empty
assert_eq!(res_obj.total, 0, "total should be 0");
assert_eq!(res_obj.items.len(), 0, "items length should be 0");
}

#[tokio::test]
#[tracing_test::traced_test]
async fn test_get_only_burnt_assets_by_owner() {
let cnt = 20;
let cli = Cli::default();
let (env, generated_assets) =
setup::TestEnvironment::create_burnt(&cli, cnt, SLOT_UPDATED).await;
let api = nft_ingester::api::api_impl::DasApi::<
MaybeProofChecker,
JsonWorker,
JsonWorker,
MockAccountBalanceGetter,
RaydiumTokenPriceFetcher,
Storage,
>::new(
env.pg_env.client.clone(),
env.rocks_env.storage.clone(),
Arc::new(ApiMetricsConfig::new()),
None,
None,
50,
None,
None,
JsonMiddlewareConfig::default(),
Arc::new(MockAccountBalanceGetter::new()),
None,
Arc::new(RaydiumTokenPriceFetcher::default()),
NATIVE_MINT_PUBKEY.to_string(),
);
let tasks = JoinSet::new();
let mutexed_tasks = Arc::new(Mutex::new(tasks));

let ref_value = generated_assets.owners[8].clone();
let payload = GetAssetsByOwner {
owner_address: ref_value.owner.value.map(|owner| owner.to_string()).unwrap_or_default(),
sort_by: None,
limit: None,
page: None,
before: None,
after: None,
cursor: None,
options: GetByMethodsOptions {
show_unverified_collections: true,
show_burnt: Some(true),
..Default::default()
},
};

let res = api.get_assets_by_owner(payload, mutexed_tasks.clone()).await.unwrap();
let res_obj: AssetList = serde_json::from_value(res).unwrap();

assert_eq!(res_obj.total, 1, "total should be 1");
assert_eq!(res_obj.items.len(), 1, "items length should be 1");
}

#[tokio::test]
#[tracing_test::traced_test]
async fn test_search_assets_excluding_burnt_assets() {
let cnt = 20;
let cli = Cli::default();
let (env, _generated_assets) =
setup::TestEnvironment::create_burnt(&cli, cnt, SLOT_UPDATED).await;
let api = nft_ingester::api::api_impl::DasApi::<
MaybeProofChecker,
JsonWorker,
JsonWorker,
MockAccountBalanceGetter,
RaydiumTokenPriceFetcher,
Storage,
>::new(
env.pg_env.client.clone(),
env.rocks_env.storage.clone(),
Arc::new(ApiMetricsConfig::new()),
None,
None,
50,
None,
None,
JsonMiddlewareConfig::default(),
Arc::new(MockAccountBalanceGetter::new()),
None,
Arc::new(RaydiumTokenPriceFetcher::default()),
NATIVE_MINT_PUBKEY.to_string(),
);
let tasks = JoinSet::new();
let mutexed_tasks = Arc::new(Mutex::new(tasks));
let limit = 20;
let payload = SearchAssets {
burnt: Some(false),
limit: Some(limit),
options: SearchAssetsOptions {
show_unverified_collections: true,
..Default::default()
},
..Default::default()
};
let res = api.search_assets(payload, mutexed_tasks.clone()).await.unwrap();
assert!(res.is_object());
let res_obj: AssetList = serde_json::from_value(res).unwrap();
assert_eq!(res_obj.total, 0, "total should be 0");
assert_eq!(res_obj.items.len(), 0, "assets length should be 0");
}

#[tokio::test]
#[tracing_test::traced_test]
async fn test_get_assets_by_group() {
Expand Down
3 changes: 2 additions & 1 deletion postgre-client/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub struct AssetSortedIndex {
pub sorting_id: String,
}

#[derive(Default)]
#[derive(Default, Debug)]
pub struct SearchAssetsFilter {
pub specification_version: Option<SpecificationVersions>,
pub specification_asset_class: Option<SpecificationAssetClass>,
Expand All @@ -92,6 +92,7 @@ pub struct SearchAssetsFilter {
pub token_type: Option<TokenType>,
}

#[derive(Debug)]
pub enum AssetSupply {
Greater(u64),
Equal(u64),
Expand Down
2 changes: 1 addition & 1 deletion rocks-db/benches/misc_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn bincode_decode_benchmark(c: &mut Criterion) {
let slot = 100;
let assets = pubkeys
.iter()
.map(|pk| setup::rocks::create_test_dynamic_data(*pk, slot, "solana".to_string()))
.map(|pk| setup::rocks::create_test_dynamic_data(*pk, slot, "solana".to_string(), false))
.map(|a| serialize(&a).unwrap())
.collect::<Vec<_>>();

Expand Down
18 changes: 18 additions & 0 deletions tests/setup/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ impl<'a> TestEnvironment<'a> {
.await
}

pub async fn create_burnt(
cli: &'a Cli,
cnt: usize,
slot: u64,
) -> (TestEnvironment<'a>, rocks::GeneratedAssets) {
Self::create_and_setup_from_closures(
cli,
cnt,
slot,
RocksTestEnvironmentSetup::static_data_for_nft,
RocksTestEnvironmentSetup::with_authority,
RocksTestEnvironmentSetup::test_owner,
RocksTestEnvironmentSetup::dynamic_data_burnt,
RocksTestEnvironmentSetup::collection_without_authority,
)
.await
}

#[allow(clippy::too_many_arguments)]
pub async fn create_and_setup_from_closures(
cli: &'a Cli,
Expand Down
22 changes: 19 additions & 3 deletions tests/setup/src/rocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,18 @@ impl RocksTestEnvironmentSetup {
pub fn dynamic_data(pubkeys: &[Pubkey], slot: u64) -> Vec<AssetDynamicDetails> {
pubkeys
.iter()
.map(|pubkey| create_test_dynamic_data(*pubkey, slot, DEFAULT_TEST_URL.to_owned()))
.map(|pubkey| {
create_test_dynamic_data(*pubkey, slot, DEFAULT_TEST_URL.to_owned(), false)
})
.collect()
}

pub fn dynamic_data_burnt(pubkeys: &[Pubkey], slot: u64) -> Vec<AssetDynamicDetails> {
pubkeys
.iter()
.map(|pubkey| {
create_test_dynamic_data(*pubkey, slot, DEFAULT_TEST_URL.to_owned(), true)
})
.collect()
}

Expand Down Expand Up @@ -280,15 +291,20 @@ impl RocksTestEnvironmentSetup {
pub const DEFAULT_PUBKEY_OF_ONES: Pubkey = Pubkey::new_from_array([1u8; 32]);
pub const PUBKEY_OF_TWOS: Pubkey = Pubkey::new_from_array([2u8; 32]);

pub fn create_test_dynamic_data(pubkey: Pubkey, slot: u64, url: String) -> AssetDynamicDetails {
pub fn create_test_dynamic_data(
pubkey: Pubkey,
slot: u64,
url: String,
is_burnt: bool,
) -> AssetDynamicDetails {
AssetDynamicDetails {
pubkey,
is_compressible: Updated::new(slot, None, false),
is_compressed: Updated::new(slot, None, false),
is_frozen: Updated::new(slot, None, false),
supply: Some(Updated::new(slot, None, 1)),
seq: None,
is_burnt: Updated::new(slot, None, false),
is_burnt: Updated::new(slot, None, is_burnt),
was_decompressed: Some(Updated::new(slot, None, false)),
onchain_data: None,
creators: Updated::new(slot, None, vec![generate_test_creator()]),
Expand Down

0 comments on commit ae1a8a9

Please sign in to comment.