From 8eaff3966dc7330912704252f889868205d1d4c0 Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Fri, 19 Jul 2024 15:44:07 +0200 Subject: [PATCH] fix: u64 out of range for bigint postgres column type --- .../src/dao/generated/asset.rs | 2 +- .../src/dao/generated/tokens.rs | 2 +- digital_asset_types/tests/common.rs | 4 +- migration/src/lib.rs | 2 + ...161232_change_supply_columns_to_numeric.rs | 47 +++++++++++++++++++ program_transformers/src/asset_upserts.rs | 5 +- program_transformers/src/bubblegum/db.rs | 5 +- .../src/mpl_core_program/v1_asset.rs | 3 +- program_transformers/src/token/mod.rs | 4 +- .../src/token_metadata/master_edition.rs | 3 +- .../src/token_metadata/v1_asset.rs | 18 +++---- 11 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 migration/src/m20240718_161232_change_supply_columns_to_numeric.rs diff --git a/digital_asset_types/src/dao/generated/asset.rs b/digital_asset_types/src/dao/generated/asset.rs index e4f4ab0ac..f70e0b383 100644 --- a/digital_asset_types/src/dao/generated/asset.rs +++ b/digital_asset_types/src/dao/generated/asset.rs @@ -26,7 +26,7 @@ pub struct Model { pub owner_type: OwnerType, pub delegate: Option>, pub frozen: bool, - pub supply: i64, + pub supply: Decimal, pub supply_mint: Option>, pub compressed: bool, pub compressible: bool, diff --git a/digital_asset_types/src/dao/generated/tokens.rs b/digital_asset_types/src/dao/generated/tokens.rs index 35fcad502..326b8d968 100644 --- a/digital_asset_types/src/dao/generated/tokens.rs +++ b/digital_asset_types/src/dao/generated/tokens.rs @@ -15,7 +15,7 @@ impl EntityName for Entity { #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Serialize, Deserialize)] pub struct Model { pub mint: Vec, - pub supply: i64, + pub supply: Decimal, pub decimals: i32, pub token_program: Vec, pub mint_authority: Option>, diff --git a/digital_asset_types/tests/common.rs b/digital_asset_types/tests/common.rs index f5b4664bc..0dcad71ef 100644 --- a/digital_asset_types/tests/common.rs +++ b/digital_asset_types/tests/common.rs @@ -116,7 +116,7 @@ pub fn create_asset( owner_type: Set(owner_type.clone()), delegate: Set(delegate.clone()), frozen: Set(frozen), - supply: Set(supply), + supply: Set(supply.into()), supply_mint: Set(supply_mint.clone()), compressed: Set(compressed), compressible: Set(compressible), @@ -135,7 +135,7 @@ pub fn create_asset( owner_type, delegate, frozen, - supply, + supply: supply.into(), supply_mint, compressed, compressible, diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 9b4689126..7cee77f5e 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -42,6 +42,7 @@ mod m20240313_120101_add_mpl_core_plugins_columns; mod m20240319_120101_add_mpl_core_enum_vals; mod m20240320_120101_add_mpl_core_info_items; mod m20240520_120101_add_mpl_core_external_plugins_columns; +mod m20240718_161232_change_supply_columns_to_numeric; pub mod model; @@ -93,6 +94,7 @@ impl MigratorTrait for Migrator { Box::new(m20240319_120101_add_mpl_core_enum_vals::Migration), Box::new(m20240320_120101_add_mpl_core_info_items::Migration), Box::new(m20240520_120101_add_mpl_core_external_plugins_columns::Migration), + Box::new(m20240718_161232_change_supply_columns_to_numeric::Migration), ] } } diff --git a/migration/src/m20240718_161232_change_supply_columns_to_numeric.rs b/migration/src/m20240718_161232_change_supply_columns_to_numeric.rs new file mode 100644 index 000000000..e7adc3522 --- /dev/null +++ b/migration/src/m20240718_161232_change_supply_columns_to_numeric.rs @@ -0,0 +1,47 @@ +use crate::model::table::{Asset, Tokens}; +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .modify_column(ColumnDef::new(Asset::Supply).decimal_len(20, 0).not_null()) + .to_owned(), + ) + .await?; + manager + .alter_table( + Table::alter() + .table(Tokens::Table) + .modify_column(ColumnDef::new(Tokens::Supply).decimal_len(20, 0).not_null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .modify_column(ColumnDef::new(Asset::Supply).big_integer().not_null()) + .to_owned(), + ) + .await?; + + manager + .alter_table( + Table::alter() + .table(Tokens::Table) + .modify_column(ColumnDef::new(Tokens::Supply).big_integer().not_null()) + .to_owned(), + ) + .await + } +} diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index a82923a9f..5561ff5fd 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -10,6 +10,7 @@ use { TransactionTrait, }, serde_json::value::Value, + sqlx::types::Decimal, }; pub struct AssetTokenAccountColumns { @@ -54,7 +55,7 @@ pub async fn upsert_assets_token_account_columns, - pub supply: u64, + pub supply: Decimal, pub supply_mint: Option>, pub slot_updated_mint_account: u64, } @@ -65,7 +66,7 @@ pub async fn upsert_assets_mint_account_columns Result<(), DbErr> { let active_model = asset::ActiveModel { id: Set(columns.mint), - supply: Set(columns.supply as i64), + supply: Set(columns.supply), supply_mint: Set(columns.supply_mint), slot_updated_mint_account: Set(Some(columns.slot_updated_mint_account as i64)), ..Default::default() diff --git a/program_transformers/src/bubblegum/db.rs b/program_transformers/src/bubblegum/db.rs index 0c0922775..b086c6de8 100644 --- a/program_transformers/src/bubblegum/db.rs +++ b/program_transformers/src/bubblegum/db.rs @@ -11,6 +11,7 @@ use { mpl_bubblegum::types::{Collection, Creator}, sea_orm::{ entity::{ActiveValue, ColumnTrait, EntityTrait}, + prelude::*, query::{JsonValue, QueryFilter, QuerySelect, QueryTrait}, sea_query::query::OnConflict, ConnectionTrait, DbBackend, TransactionTrait, @@ -269,7 +270,7 @@ pub async fn upsert_asset_with_compression_info( id: Vec, compressed: bool, compressible: bool, - supply: i64, + supply: u64, supply_mint: Option>, ) -> ProgramTransformerResult<()> where @@ -279,7 +280,7 @@ where id: ActiveValue::Set(id), compressed: ActiveValue::Set(compressed), compressible: ActiveValue::Set(compressible), - supply: ActiveValue::Set(supply), + supply: ActiveValue::Set(Decimal::from(supply)), supply_mint: ActiveValue::Set(supply_mint), ..Default::default() }; diff --git a/program_transformers/src/mpl_core_program/v1_asset.rs b/program_transformers/src/mpl_core_program/v1_asset.rs index 67145086c..bfebe88e7 100644 --- a/program_transformers/src/mpl_core_program/v1_asset.rs +++ b/program_transformers/src/mpl_core_program/v1_asset.rs @@ -24,6 +24,7 @@ use { heck::ToSnakeCase, sea_orm::{ entity::{ActiveValue, ColumnTrait, EntityTrait}, + prelude::*, query::{JsonValue, QueryFilter, QueryTrait}, sea_query::query::OnConflict, sea_query::Expr, @@ -309,7 +310,7 @@ pub async fn save_v1_asset( ) .await?; - let supply = 1; + let supply = Decimal::from(1); // Note: these need to be separate for Token Metadata but here could be one upsert. upsert_assets_mint_account_columns( diff --git a/program_transformers/src/token/mod.rs b/program_transformers/src/token/mod.rs index 7cb70c4fa..d46360317 100644 --- a/program_transformers/src/token/mod.rs +++ b/program_transformers/src/token/mod.rs @@ -110,7 +110,7 @@ pub async fn handle_token_program_account<'a, 'b>( mint: ActiveValue::Set(account_key.clone()), token_program: ActiveValue::Set(account_owner), slot_updated: ActiveValue::Set(account_info.slot as i64), - supply: ActiveValue::Set(m.supply as i64), + supply: ActiveValue::Set(m.supply.into()), decimals: ActiveValue::Set(m.decimals as i32), close_authority: ActiveValue::Set(None), extension_data: ActiveValue::Set(None), @@ -155,7 +155,7 @@ pub async fn handle_token_program_account<'a, 'b>( AssetMintAccountColumns { mint: account_key.clone(), supply_mint: Some(account_key), - supply: m.supply, + supply: m.supply.into(), slot_updated_mint_account: account_info.slot, }, db, diff --git a/program_transformers/src/token_metadata/master_edition.rs b/program_transformers/src/token_metadata/master_edition.rs index 7f76fa4b0..791368af6 100644 --- a/program_transformers/src/token_metadata/master_edition.rs +++ b/program_transformers/src/token_metadata/master_edition.rs @@ -10,6 +10,7 @@ use { }, sea_orm::{ entity::{ActiveModelTrait, ActiveValue, EntityTrait, RelationTrait}, + prelude::*, query::{JoinType, QuerySelect, QueryTrait}, sea_query::query::OnConflict, ConnectionTrait, DatabaseTransaction, DbBackend, @@ -86,7 +87,7 @@ pub async fn save_master_edition( if let Some((_me, Some(asset))) = master_edition { let mut updatable: asset::ActiveModel = asset.into(); - updatable.supply = ActiveValue::Set(1); + updatable.supply = ActiveValue::Set(Decimal::from(1)); updatable.specification_asset_class = ActiveValue::Set(Some(SpecificationAssetClass::Nft)); updatable.update(txn).await?; } diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index 59f4edd42..7c45b68b7 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -30,13 +30,14 @@ use { sea_query::query::OnConflict, ConnectionTrait, DbBackend, DbErr, TransactionTrait, }, - solana_sdk::{pubkey, pubkey::Pubkey}, + solana_sdk::pubkey, + sqlx::types::Decimal, tracing::warn, }; pub async fn burn_v1_asset( conn: &T, - id: Pubkey, + id: pubkey::Pubkey, slot: u64, ) -> ProgramTransformerResult<()> { let slot_i = slot as i64; @@ -62,7 +63,7 @@ pub async fn burn_v1_asset( } const RETRY_INTERVALS: &[u64] = &[0, 5, 10]; -static WSOL_PUBKEY: Pubkey = pubkey!("So11111111111111111111111111111111111111112"); +static WSOL_PUBKEY: pubkey::Pubkey = pubkey!("So11111111111111111111111111111111111111112"); pub async fn index_and_fetch_mint_data( conn: &T, @@ -84,7 +85,7 @@ pub async fn index_and_fetch_mint_data( AssetMintAccountColumns { mint: mint_pubkey_vec.clone(), supply_mint: Some(token.mint.clone()), - supply: token.supply as u64, + supply: token.supply, slot_updated_mint_account: token.slot_updated as u64, }, conn, @@ -189,13 +190,12 @@ pub async fn save_v1_asset( index_and_fetch_mint_data(conn, mint_pubkey_vec.clone()).await?; // get supply of token, default to 1 since most cases will be NFTs. Token mint ingester will properly set supply if token_result is None - let supply = token.map(|t| t.supply).unwrap_or(1); - + let supply = token.map(|t| t.supply).unwrap_or_else(|| Decimal::from(1)); // Map unknown ownership types based on the supply. if ownership_type == OwnerType::Unknown { - ownership_type = match supply.cmp(&1) { - std::cmp::Ordering::Equal => OwnerType::Single, - std::cmp::Ordering::Greater => OwnerType::Token, + ownership_type = match supply { + s if s == Decimal::from(1) => OwnerType::Single, + s if s > Decimal::from(1) => OwnerType::Token, _ => OwnerType::Unknown, }; };