-
Notifications
You must be signed in to change notification settings - Fork 6
Relayer performs Pyth updates on demand #276
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
base: dev
Are you sure you want to change the base?
Relayer performs Pyth updates on demand #276
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Installed near-sandbox into /home/runner/work/contracts/contracts/target/debug/build/near-sandbox-utils-2ad3b5a56a37a3e2/out/.near/near-sandbox-2.8.0/near-sandbox Gas ReportSnapshot Limits
Estimated snapshot limit: 9628
Estimated snapshot limit: 11494 Action Gas Descriptors
Gas ReportEstimated allocation limit: 0 Action Gas Descriptors
|
|
We should always push on demand. Negating to push it (especially on chains with minimal updates essentially undermines the smoothing & confidence. Code quote: /// Do not push price updates to Pyth oracle if the last push was less
/// than this long ago, even if requested.
#[arg(
id = "pyth-refresh-secs",
long = "pyth-refresh-secs",
env = "PYTH_REFRESH_SECS",
value_parser = duration_from_secs,
default_value = "25"
)]
pub refresh: Duration, |
|
NIT: not sure what this name even means - perhaps was a constant for the sake of avoiding magic numbers, yet still magic. |
|
This forces an iterative style error since it fails fast. I'd suggest to collect all the rejected methods first, then error with an array of indices & names. Otherwise, there could be Code quote: for (index, call) in calls.into_iter().enumerate() {
if !contract_data.allowed_methods.contains(&call.method_name) {
return Err(FunctionCallRejectionReason::UnknownFunctionName {
index,
function_name: call.method_name.clone(),
});
} |
|
Ditto here Perhaps also create a util func Code quote: if !accounts.allowed_contract_data.contains_key(receiver_id) {
return Err(PayloadRejectionReason::UnknownTransactionReceiverId {
account_id: receiver_id.clone(),
});
} |
|
I think you're accounting for gas even on the rejected calls here. |
|
This is not required if the pyth client is an actor |
|
This is quite brittle - i'd suggest to use some types from wormhole, they're available as a crate Code quote: for id in price_ids {
request = request.query(&[("ids[]", id)]);
} |
carrion256
left a comment
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.
@carrion256 reviewed 14 of 14 files at r1, all commit messages.
Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @peer2f00l)
peer2f00l
left a comment
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.
Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @carrion256)
service/relayer/src/app/args.rs line 59 at r1 (raw file):
Previously, carrion256 (carrion256) wrote…
We should always push on demand. Negating to push it (especially on chains with minimal updates essentially undermines the smoothing & confidence.
I can agree with this to an extent. The intent of this feature is to make sure that if many different users are simultaneously requesting price updates for the same ID that we only update it once (since only one update is necessary to satisfy an unlimited number of simultaneous requests). So, at least, I think it would be fair to reduce the default refresh duration down to something like 3-5 seconds.
service/relayer/src/app/mod.rs line 102 at r1 (raw file):
Previously, carrion256 (carrion256) wrote…
NIT: not sure what this name even means - perhaps was a constant for the sake of avoiding magic numbers, yet still magic.
Tera as in Teragas (Tgas)
service/relayer/src/app/mod.rs line 269 at r1 (raw file):
Previously, carrion256 (carrion256) wrote…
This forces an iterative style error since it fails fast. I'd suggest to collect all the rejected methods first, then error with an array of indices & names. Otherwise, there could be
Ncalls that can be rejected, yet hidden by this one.
Done.
service/relayer/src/app/mod.rs line 362 at r1 (raw file):
Previously, carrion256 (carrion256) wrote…
I think you're accounting for gas even on the rejected calls here.
Shouldn't matter - in the version of the code this comment was made on errors short circuit (so it doesn't matter), or in the new version it will return the list of errors late (still won't matter).
service/relayer/src/client/pyth.rs line 24 at r1 (raw file):
Previously, carrion256 (carrion256) wrote…
This is not required if the pyth client is an actor
Assuming by "actor" you mean "sends and receives information exclusively via message-passing" I'm not sure how this follows.
service/relayer/src/client/pyth.rs line 86 at r1 (raw file):
Previously, carrion256 (carrion256) wrote…
This is quite brittle - i'd suggest to use some types from wormhole, they're available as a crate
I don't see a crate that does this...
service/relayer/src/client/pyth.rs line 86 at r1 (raw file):
Previously, carrion256 (carrion256) wrote…
This is quite brittle - i'd suggest to use some types from pyth, they're available as a crate
I was not able to find an official Pyth crate that supports this. Doesn't seem worth adding a whole dependency for a single deserialization operation.
|
Previously, peer2f00l (peer2) wrote…
Let's reduce it down to three seconds, as we are perhaps prematurely optimising for gas here on a cheap chain. |
|
Previously, peer2f00l (peer2) wrote…
My point that an Arc is an anti pattern which introduces a lot of locking at scale. It usually means that there's poor separation of concerns within asynchronous boundaries and it's better to keep state locally by using different concurrency primitives, if at all. Otherwise, i wouldn't block this pull request but eventually we have tech debt if the relayer requires some real scale (20+ tx/s) as this will eventually lock. |
|
Previously, peer2f00l (peer2) wrote…
Here, i've found it https://github.com/pyth-network/pyth-crosschain/blob/main/apps/hermes/client/rust/src/lib.rs The problem is not related to complexity of implementation or binary sizes, the problem is maintenance, I'd personally prefer that the core team who run the pyth protocol maintain an integration for me. This allows us to focus within our domain rather than any implementation drift. This means we can just get updates by dependabot and update the relayer when the API changes rather than wait for prices to stop updating, which opens us up to economic attacks in the middle of the night. |
carrion256
left a comment
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.
@carrion256 reviewed 1 of 4 files at r2.
Reviewable status: 9 of 14 files reviewed, 5 unresolved discussions (waiting on @peer2f00l)
This change is