-
Notifications
You must be signed in to change notification settings - Fork 83
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
[FA migration] Dynamically process FA mapping #698
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #698 +/- ##
=======================================
+ Coverage 50.0% 50.2% +0.1%
=======================================
Files 251 253 +2
Lines 28335 28575 +240
=======================================
+ Hits 14181 14352 +171
- Misses 14154 14223 +69 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
few comments but overall looks good
rust/processor/src/db/postgres/migrations/2025-01-23-164631_coin_infos_for_migration/up.sql
Outdated
Show resolved
Hide resolved
let mut fa_extractor = FungibleAssetExtractor::new(); | ||
fa_extractor | ||
.bootstrap_coin_to_fa_mapping(self.db_pool.clone()) | ||
.await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe instead just call the bootstrapping method in the new method/merge the new and bootstrap methods? And just pass the db pool into the new method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i thought about it but it's the norm to have new not async. In this case it's probably a nonissue but I can imagine some cases (e.g. singleton) where that delineation avoids bugs.
#[derive(Clone, Debug, Deserialize, FieldCount, Identifiable, Insertable, Serialize)] | ||
#[diesel(primary_key(coin_type))] | ||
#[diesel(table_name = coin_to_fungible_asset_mappings)] | ||
pub struct CoinToFungibleAssetMapping { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to duplicate this struct for tests lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess they include whatever here for testing. If it's not here then it won't be used in tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the current paradigm is for those models with inserted at column, seems like this table doesn't, then we can probably reuse the model struct defined in the db.
pub trait CoinToFungibleAssetMappingConvertible { | ||
fn from_raw(raw: RawCoinToFungibleAssetMapping) -> Self; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think we need an explicit trait just for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. I'm just following the existing paradigm. I agree that it feels a bit redundant vs just using From. Let's keep discussing in slack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point @just-in-chang yeah since we don't do any batch conversion,and will have distinct structs for parquet and postgres models I think we can simply use From here instead. I can do as a part of refactoring I am doing
impl CoinToFungibleAssetMappingConvertible for CoinToFungibleAssetMapping { | ||
fn from_raw(raw: RawCoinToFungibleAssetMapping) -> Self { | ||
Self { | ||
coin_type: raw.coin_type, | ||
fungible_asset_metadata_address: raw.fungible_asset_metadata_address, | ||
last_transaction_version: raw.last_transaction_version, | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having a custom trait, u could just impl From<RawCoinToFungibleAssetMapping> for CoinToFungibleAssetMapping
and call .into()
when needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm seems like all the other models have a trait like this lol... dunno why but ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup.
...ocessor/src/db/common/models/fungible_asset_models/raw_v2_coin_to_fungible_asset_mappings.rs
Outdated
Show resolved
Hide resolved
...ocessor/src/db/common/models/fungible_asset_models/raw_v2_coin_to_fungible_asset_mappings.rs
Outdated
Show resolved
Hide resolved
rust/sdk-processor/src/steps/parquet_fungible_asset_processor/parquet_fa_extractor.rs
Outdated
Show resolved
Hide resolved
rust/sdk-processor/src/steps/fungible_asset_processor/fungible_asset_extractor.rs
Outdated
Show resolved
Hide resolved
let mut kv_mapping: CoinToFungibleAssetMappings = AHashMap::new(); | ||
for mapping in data { | ||
kv_mapping.extend(mapping); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can try .into_par_iter().fold() https://docs.rs/rayon/latest/rayon/iter/struct.Fold.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm this is also the existing paradigm let's fix it together in a different PR lol.
// TODO: make this more generic to load all fields, then we should be able to run tests for all processor in one test case. | ||
|
||
* this is created b/c there is inserted_at field which isn't defined in the Event struct, we can't just load the events directly without specifying the fields. | ||
* TODO: make this more generic to load all fields, then we should be able to run tests for all processor in one test case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: TODO comment can be removed
#[derive(Clone, Debug, Deserialize, FieldCount, Identifiable, Insertable, Serialize)] | ||
#[diesel(primary_key(coin_type))] | ||
#[diesel(table_name = coin_to_fungible_asset_mappings)] | ||
pub struct CoinToFungibleAssetMapping { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the current paradigm is for those models with inserted at column, seems like this table doesn't, then we can probably reuse the model struct defined in the db.
} | ||
} | ||
|
||
/// Get the asset_type_v1 (coin type) from either the mapping or the constant mapping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: comment was a bit confusing to me. either the dynamic mapping table or the static ?
pub trait CoinToFungibleAssetMappingConvertible { | ||
fn from_raw(raw: RawCoinToFungibleAssetMapping) -> Self; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point @just-in-chang yeah since we don't do any batch conversion,and will have distinct structs for parquet and postgres models I think we can simply use From here instead. I can do as a part of refactoring I am doing
ee8e9b5
to
6b65601
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left few nits but could also just address these in a separate PR cuz they aren't specific to the changes here
pub trait FungibleAssetToCoinMappingConvertible { | ||
fn from_raw(raw: RawFungibleAssetToCoinMapping) -> Self; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets just get rid of this cuz we're stopping with this pattern
impl FungibleAssetToCoinMappingConvertible for FungibleAssetToCoinMapping { | ||
fn from_raw(raw: RawFungibleAssetToCoinMapping) -> Self { | ||
Self { | ||
fungible_asset_metadata_address: raw.fungible_asset_metadata_address, | ||
coin_type: raw.coin_type, | ||
last_transaction_version: raw.last_transaction_version, | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -355,6 +395,11 @@ impl ProcessorTrait for FungibleAssetProcessor { | |||
.map(CurrentUnifiedFungibleAssetBalance::from_raw) | |||
.collect(); | |||
|
|||
let postgres_fa_to_coin_mappings: Vec<FungibleAssetToCoinMapping> = fa_to_coin_mappings | |||
.into_iter() | |||
.map(FungibleAssetToCoinMapping::from_raw) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of the trait we can just Into::into
b2b4775
to
4928c52
Compare
Summary
We were getting the FA mapping via a hardcoded list of top 100 coins. Now we want to generate this dynamically. The idea is to:
This strategy works because the mapping is guaranteed to be idempotent.
Also to be absolutely correct we're still using the constants file. Only if it can't find it in the constants file will we look in the dynamic mapping.
[WARNING] This only applies to processors built on top of SDK because we can't easily persist a mapping with the old code.
Backfill
Genesis because we need to create the mapping table
Testnet: 0
Mainnet: 0
Testing