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

BigInt basics + balance sheet report #11

Merged
merged 41 commits into from
Nov 20, 2024
Merged

Conversation

sophialittlejohn
Copy link
Collaborator

@sophialittlejohn sophialittlejohn commented Oct 31, 2024

Description

This pull request...

  • creates BigInt wrappers: Currency, Token, Rate, Perquintill. Wrapper classes can perform basic arithmetic: add, sub, mul div and stay typed and convertable to decimal, string, bigint or float
  • adds infrastructure for report generation including caching
  • adds first report using generation: balance sheet including filters

Tests:

  • BigInt.test.ts wrapper tests: conversion and arithmetic
  • Report.test.ts Balance sheet report generation

#15

@sophialittlejohn sophialittlejohn changed the title BigInt basics BigInt basics + reports basics Oct 31, 2024
@sophialittlejohn sophialittlejohn changed the title BigInt basics + reports basics BigInt basics + balance sheet rerport Nov 6, 2024
@sophialittlejohn sophialittlejohn changed the title BigInt basics + balance sheet rerport BigInt basics + balance sheet report Nov 6, 2024
@sophialittlejohn sophialittlejohn marked this pull request as ready for review November 13, 2024 17:34
return this._add<T>(-val)
}

_mul<T>(value: bigint | (T extends BigIntWrapper ? T : never)): T {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think these will only be useful if they operate on the decimal representation. We may want something like currency = tokens.mul(price). I think it should be multiplying by e.g. 1.1234 and not by 1.1234e18

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point, I added a case to Currency.mul(), if a Price is passed to the multiply function it will divide by the Prices decimals and then multiply. We could optionally also expose the _mulPrice function to make it more clear

toFloat() {
return this.toDecimal().toNumber()
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice to have would be to also have gt, lt and eq

src/Pool.ts Outdated
Comment on lines 15 to 17
reports() {
return new Reports(this._root, this.id)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it should either be a query or a property. Property makes the most sense I think. await pool.reports.balanceSheet()

}),
])

return ReportService.generate(processors.balanceSheet, this.poolId, { poolSnapshots, trancheSnapshots }, filter)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the ReportService does more harm than good. The poolSnapshots, trancheSnapshots queries are already cached, so it's really only memoizing the process function. If poolSnapshots or trancheSnapshots return new data, this wouldn't necessarily be reflected in the result, because the ReportService might have a cached result. I would just call the process function directly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can you please elaborate how you think the ReportService does harm? It seems like you're mostly just addressing the caching ability?

The cache is only valid for 5 minutes and it auto cleared after, I can reduce the time. And you got it right, the process function is exactly the one I'm trying to avoid being called n times every time its requested. I think the cache becomes even more relevant as the data set grows. We could be processing hundreds of thousands of data points multiple times as the user clicks into a graph (and switches in between graphs)

From a UX perspective we shouldn't just be updating data in a table without the user noticing. What we should do is let the user know that fresh data is available so they can click to update when ready. Kind of like how when you're reviewing PR and someone pushes something new

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Maybe we could implement a strategy that would invalidate the cache if there's new data available from the subquery

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes that would be the way to go. You'd want a "useMemo" and not a "useQuery". However, neither is necessary, because once the body of this function gets wrapped in a _query, you can pass the cacheKey to that and the result will be cached. Then the process function won't be called more than once, when it receives the same filters and the data is still the same.

The UX idea is a nice one and we can definitely take that into account when we start working on hooks and integrating into the App, but that's a userland problem. The SDK just provides the queries that users can await or subscribe to. They can choose how to display it and how the UI responds to updates.

We could, for example, have a hook that queues new data and waits for user interaction before returning the new data.

const { data, hasFreshData, refresh } = useObservableWithRefresh(...)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You haven't elaborated how the caching does more harm than good, would be great if you could provide some clarity

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The UX idea is a nice one and we can definitely take that into account when we start working on hooks and integrating into the App, but that's a userland problem. The SDK just provides the queries that users can await or subscribe to. They can choose how to display it and how the UI responds to updates.

while it does sound like a hooks challenge, to me it's also a problem we want to solve in the SDK first, it will influence how we push data updates through to the end user of the SDK

return ReportService.generate(processors.balanceSheet, this.poolId, { poolSnapshots, trancheSnapshots }, filter)
}

async poolSnapshots(filter?: PoolSnapshotFilter) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
async poolSnapshots(filter?: PoolSnapshotFilter) {
poolSnapshots(filter?: PoolSnapshotFilter) {

}

async poolSnapshots(filter?: PoolSnapshotFilter) {
return this._root._queryCentrifugeApi(['poolSnapshots'], poolSnapshotsQuery, { filter }, poolSnapshotsPostProcess)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I pushed a change to the queries branch to get rid of the key argument. The result will just be cached by the graphql query and variables

@sophialittlejohn sophialittlejohn marked this pull request as draft November 15, 2024 00:56
@sophialittlejohn
Copy link
Collaborator Author

converting back to draft to work on websocket implementation

@sophialittlejohn sophialittlejohn marked this pull request as ready for review November 19, 2024 23:59
@sophialittlejohn sophialittlejohn merged commit 89d1890 into queries Nov 20, 2024
@sophialittlejohn sophialittlejohn deleted the bigint-types branch November 20, 2024 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants