-
Notifications
You must be signed in to change notification settings - Fork 116
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/675 on chain ouis devaddrs #431
base: master
Are you sure you want to change the base?
Conversation
The Data Credits Key is not SubDao specific.
The solana_sdk provides a `read_keypair_file` function, but it returns a Result with a Box<dyn Error>. Rather than recreate all those functions for a wrapped Keypair, I thought to start with an easy conversion from one to the other. So you can read the keypair with the solana_sdk, then very quickly turn it into a helium-lib keypair. Bring the discussion!!!
The module is named boosting so there is hopefully less confusion with the existance of `helium_anchor_lang::hexboosting` that is autogenerated.
You can directly read a helium_lib::Keypair from a file that is a solana keypair.
we can not go all the way back to 0.28 because of solana-sdk. So we go back as far as we can without causing problems for upstream things like oracles.
min_priority_fee: u64, | ||
) -> Result<u64, Error> { | ||
let client_url = client.as_ref().url(); | ||
if client_url.contains("mainnet.helius") { |
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.
would this break if running against helius testnet; would it be safe to if client_url.contains("helius")
?
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.
helius has no priority fee api on testnet
// Only take the most recent 20 maximum fees: | ||
max_per_slot.sort_by(|a, b| a.0.cmp(&b.0).reverse()); | ||
let mut max_per_slot: Vec<_> = max_per_slot.into_iter().take(20).map(|x| x.1).collect(); | ||
max_per_slot.sort(); |
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.
this need the second sort? this is b/c we sorted previously by time and then resorting the value itself here after the map?
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.
yeah, further below we calculate the median so need them in order
.first() | ||
{ | ||
ix.data = solana_sdk::compute_budget::ComputeBudgetInstruction::set_compute_unit_limit( | ||
1900000, |
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.
what determines optimal values here? should these be consts or configurable?
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.
This is just a hard coded value of compute units used for the simulation of the tx. The max you can have is 2000000 so we have a bit of wiggle room before the max. Actual compute units is pulled off the simulated response.
|
||
let blockhash_actual = match blockhash { | ||
Some(hash) => hash, | ||
None => client.as_ref().get_latest_blockhash().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.
when should this latest blockhash be requested with the specified commitment config and when is this less qualified response acceptable?
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.
When simulating things you're ok with using the base condition but when you're forming transactions of instructions you intend to broadcast you should use a finalized or confirmed blockhash
// Simulate the transaction to get the actual compute used | ||
let simulation_result = client.as_ref().simulate_transaction(&snub_tx).await?; | ||
if let Some(err) = simulation_result.value.err { | ||
println!("Error: {}", err); |
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.
haven't noticed if we're using println! anywhere else in helium-lib
- is there a convention for doing this in a more "generic" way in a library and then only using the println macro in the actual cli bin code?
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.
that im not sure, we could probably remove these printlns
fully as it returns a result with a error
.await? | ||
.ok_or_else(|| Error::account_not_found())?; | ||
|
||
client |
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.
these unused results are just validations that a key is found on chain, yes?
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.
Yeah, instruction cant be built/ran without those keys so just sanity checking they exist. Not sure if this is a good or bad pattern so lemme know?
} | ||
|
||
pub async fn update<C: AsRef<SolanaRpcClient>>( | ||
_client: &C, |
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.
looking at these functions it looks to me like the pattern is that they all return an associated instruction that performs the action verb the function is named for? perhaps it's the inclusion of the client argument that i would expect these functions to actually perform that action verb but i don't know that i see any of them using the client argument? is it needed or part of a trait impl that expects a client in the off chance that the instruction requires a chain lookup to set some value?
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 I just included the client incase logic in the fns needed to be changed. The client is mainly used to ensure pdas/keys on chain exist for the current instruction
} | ||
|
||
pub async fn ensure_exists<C: AsRef<SolanaRpcClient>>( | ||
client: &C, |
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.
okay, i see the client is being used here but is it needed in all of these instructions to satisfy a trait or just convention?
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.
Was just included for consistency/incase logic need to change. And the cli is passing client to all the fns it call for convenience. I have no good argument for keeping it if we dont want it
) -> Vec<(Vec<Instruction>, Vec<usize>)> { | ||
// Change return type | ||
let mut transactions = Vec::new(); | ||
let compute_ixs = vec![ |
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 recall earlier seeing this function called and then checking to see if it only had these two compute instructions in it; would it make sense or help in any way here to return a result or option here and instead check to ensure that the instructions
argument is not empty and return Err/None early instead of returning and the vec/tuple regardless and having to check at the call site if it's actually a meaningful set of instructions?
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 copied this code from the helium v3 implementation and after looking at it I think that tx.len() == 2 check in the other code is redundant. I dont think we'd ever end up with a transaction of only compute_ixs based on the logic in pack.rs. Going to remove that tx.len() == 2 check.
let mut transactions = Vec::new(); | ||
let compute_ixs = vec![ | ||
ComputeBudgetInstruction::set_compute_unit_limit(200000), | ||
ComputeBudgetInstruction::set_compute_unit_price(1), |
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.
no priority fee calculation based on the passed in instructions?
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.
auto_compute_limit_and_price does further down
0031f22
to
25147f3
Compare
No description provided.