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

Feat/675 on chain ouis devaddrs #431

Open
wants to merge 45 commits into
base: master
Choose a base branch
from

Conversation

bryzettler
Copy link

No description provided.

michaeldjeffrey and others added 30 commits October 29, 2024 09:18
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") {
Copy link
Contributor

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")?

Copy link
Author

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();
Copy link
Contributor

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?

Copy link
Author

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,
Copy link
Contributor

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?

Copy link
Author

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?,
Copy link
Contributor

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?

Copy link
Author

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);
Copy link
Contributor

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?

Copy link
Author

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
Copy link
Contributor

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?

Copy link
Author

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?

helium-lib/src/iot_routing_manager.rs Outdated Show resolved Hide resolved
}

pub async fn update<C: AsRef<SolanaRpcClient>>(
_client: &C,
Copy link
Contributor

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?

Copy link
Author

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,
Copy link
Contributor

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?

Copy link
Author

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![
Copy link
Contributor

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?

Copy link
Author

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.

Cargo.toml Outdated Show resolved Hide resolved
helium-lib/src/client.rs Outdated Show resolved Hide resolved
helium-lib/src/client.rs Outdated Show resolved Hide resolved
helium-lib/src/client.rs Show resolved Hide resolved
helium-lib/src/client.rs Outdated Show resolved Hide resolved
let mut transactions = Vec::new();
let compute_ixs = vec![
ComputeBudgetInstruction::set_compute_unit_limit(200000),
ComputeBudgetInstruction::set_compute_unit_price(1),
Copy link
Member

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?

Copy link
Author

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

helium-lib/src/solana_transaction_utils/pack.rs Outdated Show resolved Hide resolved
helium-lib/src/solana_transaction_utils/priority_fee.rs Outdated Show resolved Hide resolved
helium-lib/src/solana_transaction_utils/priority_fee.rs Outdated Show resolved Hide resolved
helium-lib/src/utils.rs Outdated Show resolved Hide resolved
@bryzettler bryzettler force-pushed the feat/675-on-chain-ouis-devaddrs branch from 0031f22 to 25147f3 Compare December 20, 2024 19:15
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.

4 participants