-
Notifications
You must be signed in to change notification settings - Fork 0
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
feat: Crescent and Osmosis LPs tokens prices #152
base: main
Are you sure you want to change the base?
Conversation
9cc187a
to
1411d1b
Compare
I did a bunch of rewrites of the code in this PR, I'll squash and reorganize the commits at the end so you can review it easier 😅 |
No problem I didn't really start since the PR is in draft. |
The liquidity module conflicts with the new Crescent gRPC.
It basically holds a Value and an Error. This option type is json serializable.
@@ -380,3 +380,9 @@ func (s *TestSuite) TestChainsOnlineStatuses() { | |||
}) | |||
} | |||
} | |||
|
|||
func (s *TestSuite) TestDenoms() { | |||
denoms, err := s.ctx.Router.DB.Denoms(context.Background()) |
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.
With this setup, you can expect one denom :
err := s.ctx.CnsDB.AddChain(utils.ChainWithoutPublicEndpoints)
require.NoError(t, err)
app := usecase.NewApp(sdkServiceClients) | ||
osmosisClient := usecase.NewOsmosisGrpcClient("osmosis:9090") | ||
|
||
crescentClient := usecase.NewCrescentGrpcClient("crescent:9090") |
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.
IMO these GRPC clients shouldn't be located in the usecase
package, because they don't contain business code. Moreover they can't be tested efficiently. I suggest to move them in a specific package like poclient
, for instance grpcclient
?
In addition, it's weird to have both OsmosisClient
interface and implementation in the same package
@@ -20,6 +23,7 @@ func newApp(t *testing.T, setup func(mocks)) *usecase.App { | |||
t: t, | |||
sdkServiceClients: NewMockSDKServiceClients(ctrl), | |||
sdkServiceClient: NewMockSDKServiceClient(ctrl), | |||
denomPricer: NewMockDenomPricer(ctrl), |
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.
For the tests, you'll need to feed mocks.crescentClient
and mocks.osmosisClient
.
type PriceOracle interface { | ||
GetPrice(ctx context.Context, symbol string) (poclient.Price, error) | ||
} | ||
|
||
type DenomTracer interface { | ||
DenomTrace(ctx context.Context, chainName, traceHash string) (tracelistener.IBCDenomTraceRow, error) | ||
} | ||
|
||
type Denomer interface { | ||
Denom(ctx context.Context, denomName string) (cns.Denom, error) | ||
} |
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 assume you will move those interfaces in ports.go
, or else you won't have the generated mocks.
} | ||
|
||
func (d *DatabaseDenomer) Denom(ctx context.Context, denomName string) (cns.Denom, error) { | ||
denoms, err := d.db.Denoms(ctx) |
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.
Typically usecase
should never call the database directly like that, or else you will have to setup a local database for the test. What you need is a DB
interface, like I started to work with in EmerisHQ/demeris-backend#777
demeris-api-server/usecase/ports.go
Lines 14 to 20 in eaed1f3
type DB interface { | |
Chains(ctx context.Context) ([]cns.Chain, error) | |
Balances(ctx context.Context, addresses []string) ([]tracelistener.BalanceRow, error) | |
Delegations(ctx context.Context, addresses []string) ([]database.DelegationResponse, error) | |
VerifiedDenoms(context.Context) (map[string]cns.DenomList, error) | |
DenomTrace(ctx context.Context, chain string, hash string) (tracelistener.IBCDenomTraceRow, error) | |
} |
} | ||
} | ||
|
||
func (p *PriceOracleDenomPricer) DenomPrice(ctx context.Context, chainName, denomName string) (sdktypes.Dec, error) { |
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.
Because dependency injection is done manually with this pattern (once I tried to use wire
but it was clearly over-engineered, so I stepped back), I tend to keep the number of services small. So typically here, I would have attached DenomPrice
to App
.
That said this is just a suggestion, if you prefer like that that's problably fine.
// "osmosis" -> [ {pool1}, {error pool2}, {pool3} ] | ||
// "crescent" -> [ {pool1}, {pool2}, {pool3} ] | ||
// "chainx" -> {error chainx} | ||
type PoolPricesResult map[StrategyID]options.O[[]options.O[PoolPrice]] |
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'm mixed with the JSON output of this type.
First, I tend to never use a map for a type intended to be marshaled into JSON, because the order of keys isn't stable.
Secondly, despite I like the one-line usage of this new options
package, I'm not fan of the value/error dichotomy once marshaled into JSON.
As a client of this endpoint, I have to choose to check the presence of value
or error
, and let's say I choose error
, then I assume there's must be a value
. It can be simpler I think. In addition, when there's an error, you can't add any additional information.
Suggestion : in case of error, we only add an error
field embedded in the struct. The client just checks the presence of the error
field. I tried to transform the data in the screenshot below with this different format (and I also removed the map) :
{
"pool_results": [
{
"chain":"crescent",
"pools": [
{
"symbol": "pool8",
"supply": "0",
"price": "0"
},
{
"symbol": "pool9",
"supply": "0",
"price": "0",
"error": "getting denom price: getting price for denom bCRE: symbol not found: BCREUSDT"
}
]
},
{
"chain":"osmosis",
"error":"error getting pool prices for strategy osmosis: cannot get pools, rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 10.64.208.2:9090: connect: connection refused\""
}
]
}
WDYT?
Overview of this PR:
Future work: