Skip to content

Commit

Permalink
fix: no duplicate nft_transfers when initiated through the API by onl…
Browse files Browse the repository at this point in the history
…y doing a transfer_charge and letting creation of the nft_transfer happen through the indexers
  • Loading branch information
kespinola committed Jul 6, 2023
1 parent f2d030a commit f91b3fb
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 34 deletions.
1 change: 1 addition & 0 deletions api/src/entities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ pub mod nft_transfers;
pub mod project_wallets;
pub mod purchases;
pub mod sea_orm_active_enums;
pub mod transfer_charges;
1 change: 0 additions & 1 deletion api/src/entities/nft_transfers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub struct Model {
pub sender: String,
pub recipient: String,
pub created_at: DateTimeWithTimeZone,
pub credits_deduction_id: Option<Uuid>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
Expand Down
2 changes: 1 addition & 1 deletion api/src/entities/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ pub use super::{
drops::Entity as Drops, metadata_json_attributes::Entity as MetadataJsonAttributes,
metadata_json_files::Entity as MetadataJsonFiles, metadata_jsons::Entity as MetadataJsons,
nft_transfers::Entity as NftTransfers, project_wallets::Entity as ProjectWallets,
purchases::Entity as Purchases,
purchases::Entity as Purchases, transfer_charges::Entity as TransferCharges,
};
16 changes: 16 additions & 0 deletions api/src/entities/transfer_charges.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.5

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "transfer_charges")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub credits_deduction_id: Option<Uuid>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}
24 changes: 6 additions & 18 deletions api/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::{
prelude::{CollectionMints, Purchases},
project_wallets, purchases,
sea_orm_active_enums::{Blockchain, CreationStatus},
transfer_charges,
},
proto::{
nft_events::Event as NftEvent,
Expand Down Expand Up @@ -163,7 +164,6 @@ impl Processor {
sender: Set(payload.sender),
recipient: Set(payload.recipient),
created_at: Set(Utc::now().into()),
credits_deduction_id: Set(None),
..Default::default()
};

Expand Down Expand Up @@ -210,7 +210,6 @@ impl Processor {
sender: Set(mint.owner),
recipient: Set(new_owner.clone()),
created_at: Set(created_at),
credits_deduction_id: Set(None),
..Default::default()
};

Expand Down Expand Up @@ -392,22 +391,14 @@ impl Processor {
let conn = self.db.get();
let transfer_id = Uuid::from_str(&id)?;

let (nft_transfer, collection_mint) = nft_transfers::Entity::find_by_id(transfer_id)
.find_also_related(collection_mints::Entity)
let transfer_charge = transfer_charges::Entity::find()
.filter(transfer_charges::Column::CreditsDeductionId.eq(transfer_id))
.one(conn)
.await?
.context("failed to load nft transfer from db")?;
.context("failed to load transfer charge from db")?;

let collection_mint = collection_mint.context("collection mint not found")?;

let mut collection_mint_am: collection_mints::ActiveModel = collection_mint.into();
let mut nft_transfer_am: nft_transfers::ActiveModel = nft_transfer.clone().into();

if let TransferResult::Success(signature) = payload {
collection_mint_am.owner = Set(nft_transfer.recipient.clone());
nft_transfer_am.tx_signature = Set(Some(signature));

let deduction_id = nft_transfer
if let TransferResult::Success(_) = payload {
let deduction_id = transfer_charge
.credits_deduction_id
.context("deduction id not found")?;

Expand All @@ -416,9 +407,6 @@ impl Processor {
.await?;
}

collection_mint_am.update(conn).await?;
nft_transfer_am.insert(conn).await?;

Ok(())
}
}
Expand Down
26 changes: 12 additions & 14 deletions api/src/mutations/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use crate::{
db::Connection,
entities::{
collection_mints::{self, CollectionMint},
collections, customer_wallets, drops, nft_transfers,
collections, customer_wallets, drops,
prelude::{Collections, CustomerWallets, Drops},
sea_orm_active_enums::{Blockchain, CreationStatus},
transfer_charges,
},
proto::{self, NftEventKey, TransferPolygonAsset},
Actions, AppContext, OrganizationId, UserID,
Expand Down Expand Up @@ -95,17 +96,13 @@ impl Mutation {
.await?
.ok_or(Error::new("Sender wallet is not managed by Hub"))?;

let nft_transfer_am = nft_transfers::ActiveModel {
tx_signature: Set(None),
collection_mint_id: Set(collection_mint_model.id),
sender: Set(owner_address.clone()),
recipient: Set(recipient.clone()),
let transfer_charges_am = transfer_charges::ActiveModel {
..Default::default()
};

let nft_transfer_model = nft_transfer_am.insert(conn).await?;
let transfer_charge_model = transfer_charges_am.insert(conn).await?;
let event_key = NftEventKey {
id: nft_transfer_model.id.to_string(),
id: transfer_charge_model.id.to_string(),
user_id: user_id.to_string(),
project_id: drop.project_id.to_string(),
};
Expand Down Expand Up @@ -149,7 +146,7 @@ impl Mutation {
balance,
org_id,
user_id,
nft_transfer_model.id,
transfer_charge_model.id,
collection.blockchain,
)
.await?;
Expand Down Expand Up @@ -188,14 +185,15 @@ async fn submit_pending_deduction(

let deduction_id = id.ok_or(Error::new("Organization does not have enough credits"))?;

let nft_transfer_model = nft_transfers::Entity::find_by_id(transfer_id)
let transfer_charge_model = transfer_charges::Entity::find()
.filter(transfer_charges::Column::Id.eq(transfer_id))
.one(db.get())
.await?
.ok_or(Error::new("drop not found"))?;
.ok_or(Error::new("transfer charge not found"))?;

let mut nft_transfer: nft_transfers::ActiveModel = nft_transfer_model.into();
nft_transfer.credits_deduction_id = Set(Some(deduction_id.0));
nft_transfer.update(db.get()).await?;
let mut transfer_charge: transfer_charges::ActiveModel = transfer_charge_model.into();
transfer_charge.credits_deduction_id = Set(Some(deduction_id.0));
transfer_charge.update(db.get()).await?;

Ok(())
}
Expand Down
6 changes: 6 additions & 0 deletions migration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ mod m20230518_034021_set_default_timestamp;
mod m20230606_121315_add_collection_mint_id_to_nft_transfers;
mod m20230620_160452_make_address_nullable_on_collection_mints;
mod m20230626_111748_customer_wallets_table;
mod m20230706_130934_create_transfer_charges_table;
mod m20230706_133356_backfill_transfer_charges;
mod m20230706_134402_drop_column_credits_deduction_id_from_nft_transfers;

pub struct Migrator;

Expand Down Expand Up @@ -89,6 +92,9 @@ impl MigratorTrait for Migrator {
Box::new(m20230606_121315_add_collection_mint_id_to_nft_transfers::Migration),
Box::new(m20230620_160452_make_address_nullable_on_collection_mints::Migration),
Box::new(m20230626_111748_customer_wallets_table::Migration),
Box::new(m20230706_130934_create_transfer_charges_table::Migration),
Box::new(m20230706_133356_backfill_transfer_charges::Migration),
Box::new(m20230706_134402_drop_column_credits_deduction_id_from_nft_transfers::Migration),
]
}
}
44 changes: 44 additions & 0 deletions migration/src/m20230706_130934_create_transfer_charges_table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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
.create_table(
Table::create()
.table(TransferCharges::Table)
.if_not_exists()
.col(
ColumnDef::new(TransferCharges::Id)
.uuid()
.not_null()
.primary_key()
.extra("default gen_random_uuid()".to_string()),
)
.col(
ColumnDef::new(TransferCharges::CreditsDeductionId)
.uuid()
.null(),
)
.to_owned(),
)
.await
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(TransferCharges::Table).to_owned())
.await
}
}

/// Learn more at https://docs.rs/sea-query#iden
#[derive(Iden)]
enum TransferCharges {
Table,
Id,
CreditsDeductionId,
}
34 changes: 34 additions & 0 deletions migration/src/m20230706_133356_backfill_transfer_charges.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use sea_orm::{ConnectionTrait, Statement};
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> {
let db = manager.get_connection();

let stmt = Statement::from_string(
manager.get_database_backend(),
r#"INSERT INTO transfer_charges(credits_deduction_id) SELECT credits_deduction_id FROM nft_transfers;"#.to_string(),
);

db.execute(stmt).await?;

Ok(())
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let db = manager.get_connection();

let stmt = Statement::from_string(
manager.get_database_backend(),
r#"DELETE FROM transfer_charges;"#.to_string(),
);

db.execute(stmt).await?;

Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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(NftTransfers::Table)
.drop_column(NftTransfers::CreditsDeductionId)
.to_owned(),
)
.await
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.alter_table(
Table::alter()
.table(NftTransfers::Table)
.add_column_if_not_exists(
ColumnDef::new(NftTransfers::CreditsDeductionId)
.uuid()
.null(),
)
.to_owned(),
)
.await
}
}

/// Learn more at https://docs.rs/sea-query#iden
#[derive(Iden)]
enum NftTransfers {
Table,
CreditsDeductionId,
}

0 comments on commit f91b3fb

Please sign in to comment.