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

Enable out-of-order transaction processing for asset table #77

Merged
merged 36 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ff389cc
Fix docker preparation script to build SPL
danenbm May 24, 2023
9299d79
Update owner and delegate in asset table when collection or creator v…
danenbm May 24, 2023
02d4a05
Modify program transformers to upsert in asset table
danenbm May 25, 2023
63b1e48
Update mint and decompress to be able to upsert asset info out of order
danenbm May 26, 2023
bee5977
Add second sequence number for compression status fields
danenbm May 26, 2023
69f9cc3
Reduce logging in docker
danenbm May 26, 2023
1dfdfd0
Comment out compressed_seq before regenerating Sea ORM objects
danenbm May 26, 2023
ba6b323
Merge branch 'main' into danenbm/update-asset
danenbm May 30, 2023
507b393
Add migration for asset specification
danenbm Jun 1, 2023
634030d
Update README
danenbm Jun 1, 2023
07b6712
Rename PNFT and regenerate Sea ORM types
danenbm Jun 2, 2023
238b043
Apply usage of compressed_seq after regenerating Sea ORM types
danenbm Jun 2, 2023
aa6fe0d
Merge branch 'main' into danenbm/update-asset
danenbm Jun 15, 2023
9eae93b
Add owner delegate sequence number for owner and delegate fields.
danenbm Jun 16, 2023
d4fa87d
Regenerating database types
danenbm Jun 16, 2023
060a2a0
Update handling for non null constrained asset table
danenbm Jun 20, 2023
9e06391
Update tests to use new Sea ORM types
danenbm Jun 20, 2023
b9427cd
Use owner_and_delegate_seq to separate upserts
danenbm Jun 20, 2023
0b030f2
Adding was_decompressed flag to replace compressed_seq
danenbm Jun 20, 2023
d42fca0
Regenerating Sea ORM types
danenbm Jun 20, 2023
ed8f03b
Update code to use was_decompressed flag
danenbm Jun 20, 2023
b1a349e
Fix new boolean SQL conditions
danenbm Jun 20, 2023
4c6e51d
Update comment
danenbm Jun 21, 2023
4c0e259
Remove column updates in asset table during mint for items not in model
danenbm Jun 21, 2023
2b4e5e6
Clippy fixes in ingester main
danenbm Jun 22, 2023
ff0e987
Merge branch 'main' into danenbm/update-asset
danenbm Jun 22, 2023
843dd6b
Cleanup debug comment
danenbm Jun 22, 2023
f13f7d5
Merge branch 'main' into danenbm/update-asset
danenbm Jun 22, 2023
2713a18
Allow for sequence number to be NULL (needed after decompress now)
danenbm Jun 22, 2023
f7a5143
Add leaf specific sequence number to protect that field in asset table
danenbm Jun 23, 2023
bf2d2bc
Revert "Allow for sequence number to be NULL (needed after decompress…
danenbm Jun 23, 2023
eeb56ac
Merge branch 'main' into danenbm/update-asset
danenbm Jun 27, 2023
7c9e1c1
Merge branch 'main' into danenbm/update-asset
danenbm Jun 28, 2023
5b7a33d
Update nft_ingester/src/program_transformers/bubblegum/redeem.rs
danenbm Jul 10, 2023
365a9bc
Merge branch 'main' into danenbm/update-asset
danenbm Jul 17, 2023
1de90db
Merge branch 'main' into danenbm/update-asset
danenbm Jul 21, 2023
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Then with a local `DATABASE_URL` var exported like this `export DATABASE_URL=pos

If you need to install `sea-orm-cli` run `cargo install sea-orm-cli`.

Note: The current SeaORM types were generated using version 0.9.3 so unless you want to upgrade you can install using `cargo install sea-orm-cli --version 0.9.3`.

Also note: The migration `m20230224_093722_performance_improvements` needs to be commented out of the migration lib.rs in order for the Sea ORM `Relations` to generate correctly.
danenbm marked this conversation as resolved.
Show resolved Hide resolved

#### Developing Locally
*Prerequisites*
* A Postgres Server running with the database setup according to ./init.sql
Expand Down
29 changes: 19 additions & 10 deletions digital_asset_types/src/dao/generated/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ impl EntityName for Entity {
pub struct Model {
pub id: Vec<u8>,
pub alt_id: Option<Vec<u8>>,
pub specification_version: SpecificationVersions,
pub specification_asset_class: SpecificationAssetClass,
pub specification_version: Option<SpecificationVersions>,
pub specification_asset_class: Option<SpecificationAssetClass>,
pub owner: Option<Vec<u8>>,
pub owner_type: OwnerType,
pub delegate: Option<Vec<u8>>,
Expand All @@ -30,19 +30,22 @@ pub struct Model {
pub supply_mint: Option<Vec<u8>>,
pub compressed: bool,
pub compressible: bool,
pub seq: i64,
pub seq: Option<i64>,
pub tree_id: Option<Vec<u8>>,
pub leaf: Option<Vec<u8>>,
pub nonce: i64,
pub nonce: Option<i64>,
pub royalty_target_type: RoyaltyTargetType,
pub royalty_target: Option<Vec<u8>>,
pub royalty_amount: i32,
pub asset_data: Option<Vec<u8>>,
pub created_at: Option<DateTimeWithTimeZone>,
pub burnt: bool,
pub slot_updated: i64,
pub slot_updated: Option<i64>,
pub data_hash: Option<String>,
pub creator_hash: Option<String>,
pub owner_delegate_seq: Option<i64>,
pub was_decompressed: bool,
pub leaf_seq: Option<i64>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
Expand Down Expand Up @@ -72,6 +75,9 @@ pub enum Column {
SlotUpdated,
DataHash,
CreatorHash,
OwnerDelegateSeq,
WasDecompressed,
LeafSeq,
}

#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
Expand Down Expand Up @@ -101,8 +107,8 @@ impl ColumnTrait for Column {
match self {
Self::Id => ColumnType::Binary.def(),
Self::AltId => ColumnType::Binary.def().null(),
Self::SpecificationVersion => SpecificationVersions::db_type(),
Self::SpecificationAssetClass => SpecificationAssetClass::db_type(),
Self::SpecificationVersion => SpecificationVersions::db_type().null(),
Self::SpecificationAssetClass => SpecificationAssetClass::db_type().null(),
Self::Owner => ColumnType::Binary.def().null(),
Self::OwnerType => OwnerType::db_type(),
Self::Delegate => ColumnType::Binary.def().null(),
Expand All @@ -111,19 +117,22 @@ impl ColumnTrait for Column {
Self::SupplyMint => ColumnType::Binary.def().null(),
Self::Compressed => ColumnType::Boolean.def(),
Self::Compressible => ColumnType::Boolean.def(),
Self::Seq => ColumnType::BigInteger.def(),
Self::Seq => ColumnType::BigInteger.def().null(),
Self::TreeId => ColumnType::Binary.def().null(),
Self::Leaf => ColumnType::Binary.def().null(),
Self::Nonce => ColumnType::BigInteger.def(),
Self::Nonce => ColumnType::BigInteger.def().null(),
Self::RoyaltyTargetType => RoyaltyTargetType::db_type(),
Self::RoyaltyTarget => ColumnType::Binary.def().null(),
Self::RoyaltyAmount => ColumnType::Integer.def(),
Self::AssetData => ColumnType::Binary.def().null(),
Self::CreatedAt => ColumnType::TimestampWithTimeZone.def().null(),
Self::Burnt => ColumnType::Boolean.def(),
Self::SlotUpdated => ColumnType::BigInteger.def(),
Self::SlotUpdated => ColumnType::BigInteger.def().null(),
Self::DataHash => ColumnType::Char(Some(50u32)).def().null(),
Self::CreatorHash => ColumnType::Char(Some(50u32)).def().null(),
Self::OwnerDelegateSeq => ColumnType::BigInteger.def().null(),
Self::WasDecompressed => ColumnType::Boolean.def(),
Self::LeafSeq => ColumnType::BigInteger.def().null(),
}
}
}
Expand Down
120 changes: 60 additions & 60 deletions digital_asset_types/src/dao/generated/sea_orm_active_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,8 @@ use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(
rs_type = "String",
db_type = "Enum",
enum_name = "specification_versions"
)]
pub enum SpecificationVersions {
#[sea_orm(string_value = "unknown")]
Unknown,
#[sea_orm(string_value = "v0")]
V0,
#[sea_orm(string_value = "v1")]
V1,
#[sea_orm(string_value = "v2")]
V2,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(
rs_type = "String",
db_type = "Enum",
enum_name = "royalty_target_type"
)]
pub enum RoyaltyTargetType {
#[sea_orm(string_value = "creators")]
Creators,
#[sea_orm(string_value = "fanout")]
Fanout,
#[sea_orm(string_value = "single")]
Single,
#[sea_orm(string_value = "unknown")]
Unknown,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "task_status")]
pub enum TaskStatus {
#[sea_orm(string_value = "failed")]
Failed,
#[sea_orm(string_value = "pending")]
Pending,
#[sea_orm(string_value = "running")]
Running,
#[sea_orm(string_value = "success")]
Success,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "chain_mutability")]
pub enum ChainMutability {
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "mutability")]
pub enum Mutability {
#[sea_orm(string_value = "immutable")]
Immutable,
#[sea_orm(string_value = "mutable")]
Expand All @@ -58,18 +14,8 @@ pub enum ChainMutability {
Unknown,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "owner_type")]
pub enum OwnerType {
#[sea_orm(string_value = "single")]
Single,
#[sea_orm(string_value = "token")]
Token,
#[sea_orm(string_value = "unknown")]
Unknown,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "mutability")]
pub enum Mutability {
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "chain_mutability")]
pub enum ChainMutability {
#[sea_orm(string_value = "immutable")]
Immutable,
#[sea_orm(string_value = "mutable")]
Expand All @@ -96,6 +42,18 @@ pub enum V1AccountAttachments {
Unknown,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "task_status")]
pub enum TaskStatus {
#[sea_orm(string_value = "failed")]
Failed,
#[sea_orm(string_value = "pending")]
Pending,
#[sea_orm(string_value = "running")]
Running,
#[sea_orm(string_value = "success")]
Success,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(
rs_type = "String",
db_type = "Enum",
Expand All @@ -116,10 +74,52 @@ pub enum SpecificationAssetClass {
Print,
#[sea_orm(string_value = "PRINTABLE_NFT")]
PrintableNft,
#[sea_orm(string_value = "PROGRAMMABLE_NFT")]
ProgrammableNft,
#[sea_orm(string_value = "TRANSFER_RESTRICTED_NFT")]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can remove later

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that, because we won't ever use it?

TransferRestrictedNft,
#[sea_orm(string_value = "unknown")]
Unknown,
#[sea_orm(string_value = "PNFT")]
ProgrammableNft,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(
rs_type = "String",
db_type = "Enum",
enum_name = "specification_versions"
)]
pub enum SpecificationVersions {
#[sea_orm(string_value = "unknown")]
Unknown,
#[sea_orm(string_value = "v0")]
V0,
#[sea_orm(string_value = "v1")]
V1,
#[sea_orm(string_value = "v2")]
V2,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(
rs_type = "String",
db_type = "Enum",
enum_name = "royalty_target_type"
)]
pub enum RoyaltyTargetType {
#[sea_orm(string_value = "creators")]
Creators,
#[sea_orm(string_value = "fanout")]
Fanout,
#[sea_orm(string_value = "single")]
Single,
#[sea_orm(string_value = "unknown")]
Unknown,
}
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "owner_type")]
pub enum OwnerType {
#[sea_orm(string_value = "single")]
Single,
#[sea_orm(string_value = "token")]
Token,
#[sea_orm(string_value = "unknown")]
Unknown,
}
44 changes: 29 additions & 15 deletions digital_asset_types/src/dapi/common/asset.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::dao::sea_orm_active_enums::SpecificationVersions;
use crate::dao::FullAsset;
use crate::dao::Pagination;
use crate::dao::{asset, asset_authority, asset_creators, asset_data, asset_grouping};
use crate::dao::FullAsset;

use crate::rpc::filter::{AssetSortBy, AssetSortDirection, AssetSorting};
use crate::rpc::response::{AssetError, AssetList};
Expand Down Expand Up @@ -221,9 +221,11 @@ pub fn v1_content_from_json(asset_data: &asset_data::Model) -> Result<Content, D

pub fn get_content(asset: &asset::Model, data: &asset_data::Model) -> Result<Content, DbErr> {
match asset.specification_version {
SpecificationVersions::V1 => v1_content_from_json(data),
SpecificationVersions::V0 => v1_content_from_json(data),
_ => Err(DbErr::Custom("Version Not Implemented".to_string())),
Some(SpecificationVersions::V1) | Some(SpecificationVersions::V0) => {
v1_content_from_json(data)
}
Some(_) => Err(DbErr::Custom("Version Not Implemented".to_string())),
None => Err(DbErr::Custom("Specification version not found".to_string())),
}
}

Expand Down Expand Up @@ -258,11 +260,19 @@ pub fn to_grouping(groups: Vec<asset_grouping::Model>) -> Vec<Group> {
.collect()
}

pub fn get_interface(asset: &asset::Model) -> Interface {
Interface::from((
&asset.specification_version,
&asset.specification_asset_class,
))
pub fn get_interface(asset: &asset::Model) -> Result<Interface, DbErr> {
Ok(Interface::from((
asset
.specification_version
.as_ref()
.ok_or(DbErr::Custom("Specification version not found".to_string()))?,
asset
.specification_asset_class
.as_ref()
.ok_or(DbErr::Custom(
"Specification asset class not found".to_string(),
))?,
)))
}

//TODO -> impl custom erro type
Expand All @@ -277,15 +287,15 @@ pub fn asset_to_rpc(asset: FullAsset) -> Result<RpcAsset, DbErr> {
let rpc_authorities = to_authority(authorities);
let rpc_creators = to_creators(creators);
let rpc_groups = to_grouping(groups);
let interface = get_interface(&asset);
let interface = get_interface(&asset)?;
let content = get_content(&asset, &data)?;
let mut chain_data_selector_fn = jsonpath_lib::selector(&data.chain_data);
let chain_data_selector = &mut chain_data_selector_fn;
let basis_points = safe_select(chain_data_selector, "$.primary_sale_happened")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let edition_nonce = safe_select(chain_data_selector, "$.edition_nonce")
.and_then(|v| v.as_u64());
let edition_nonce =
safe_select(chain_data_selector, "$.edition_nonce").and_then(|v| v.as_u64());

Ok(RpcAsset {
interface: interface.clone(),
Expand All @@ -296,8 +306,12 @@ pub fn asset_to_rpc(asset: FullAsset) -> Result<RpcAsset, DbErr> {
compression: Some(Compression {
eligible: asset.compressible,
compressed: asset.compressed,
leaf_id: asset.nonce,
seq: asset.seq,
leaf_id: asset
.nonce
.ok_or(DbErr::Custom("Nonce not found".to_string()))?,
seq: asset
.seq
.ok_or(DbErr::Custom("Seq not found".to_string()))?,
tree: asset
.tree_id
.map(|s| bs58::encode(s).into_string())
Expand Down Expand Up @@ -337,7 +351,7 @@ pub fn asset_to_rpc(asset: FullAsset) -> Result<RpcAsset, DbErr> {
},
supply: match interface {
Interface::V1NFT => Some(Supply {
edition_nonce: edition_nonce,
edition_nonce,
print_current_supply: 0,
print_max_supply: 0,
}),
Expand Down
17 changes: 11 additions & 6 deletions digital_asset_types/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub fn create_asset_data(
)
}

#[allow(clippy::too_many_arguments)]
pub fn create_asset(
id: Vec<u8>,
owner: Vec<u8>,
Expand All @@ -97,8 +98,8 @@ pub fn create_asset(
compressed: bool,
compressible: bool,
tree_id: Option<Vec<u8>>,
specification_version: SpecificationVersions,
nonce: i64,
specification_version: Option<SpecificationVersions>,
nonce: Option<i64>,
leaf: Option<Vec<u8>>,
royalty_target_type: RoyaltyTargetType,
royalty_target: Option<Vec<u8>>,
Expand Down Expand Up @@ -134,22 +135,25 @@ pub fn create_asset(
supply_mint,
compressed,
compressible,
seq: 0,
seq: Some(0),
tree_id,
specification_version,
nonce,
leaf,
royalty_target_type,
royalty_target,
royalty_amount,
asset_data: Some(id.clone()),
asset_data: Some(id),
burnt: false,
created_at: None,
specification_asset_class: SpecificationAssetClass::Nft,
slot_updated: 0,
specification_asset_class: Some(SpecificationAssetClass::Nft),
slot_updated: Some(0),
data_hash: None,
alt_id: None,
creator_hash: None,
owner_delegate_seq: Some(0),
was_decompressed: false,
leaf_seq: Some(0),
},
)
}
Expand Down Expand Up @@ -204,6 +208,7 @@ pub fn create_asset_authority(
)
}

#[allow(dead_code)]
pub fn create_asset_grouping(
asset_id: Vec<u8>,
collection: Pubkey,
Expand Down
Loading