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: Solana Vault Swaps Elections #5355

Open
wants to merge 25 commits into
base: feat/solana-program-swaps-close-accounts
Choose a base branch
from

Conversation

ramizhasan111
Copy link
Contributor

@ramizhasan111 ramizhasan111 commented Oct 24, 2024

Pull Request

Closes: PRO-1521 , PRO-1522

Checklist

Please conduct a thorough self-review before opening the PR.

  • I am confident that the code works.
  • I have written sufficient tests.
  • I have written and tested required migrations.
  • I have updated documentation where appropriate.

Summary

note: please ignore some of the naming around Contract Swaps. That will be fixed before merging.

@ramizhasan111 ramizhasan111 changed the base branch from main to feat/solana-program-swaps-close-accounts October 24, 2024 15:40
@ramizhasan111 ramizhasan111 changed the base branch from feat/solana-program-swaps-close-accounts to feat/closing-solana-swap-accounts October 24, 2024 15:49
@ramizhasan111 ramizhasan111 changed the base branch from feat/closing-solana-swap-accounts to feat/solana-program-swaps-close-accounts October 25, 2024 11:59
@ramizhasan111 ramizhasan111 marked this pull request as ready for review October 25, 2024 12:13
engine/src/witness/sol.rs Outdated Show resolved Hide resolved
foreign-chains/solana/sol-prim/src/consts.rs Outdated Show resolved Hide resolved
state-chain/runtime/src/chainflip/solana_elections.rs Outdated Show resolved Hide resolved
pub confirm_closed_accounts: BTreeSet<Account>,
}

pub struct SolanaVaultSwapAccounts<
Copy link
Contributor

Choose a reason for hiding this comment

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

there are no tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

wanted to first nail down the approach based on the reviews before writing any tests

Comment on lines 200 to 202
for vote in active_votes {
counts.entry(vote).and_modify(|count| *count += 1).or_insert(1);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

will this actually work? If nodes are querying at different times then their votes may not be identical, and therefore wouldn't come to consensus

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree - we need to count each account addition/removal individually and then keep only the additions/removals that have consensus votes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I originally wanted to have engines vote on individual accounts but the way Bitmap Components work doesn't allow that (we cant vote for more than one bitmap component in a single vote). So I instead took the route of coming to consensus over the whole list. But I can see that it is possible we cant come to a consensus over the whole list. Will modify the consensus to parse the votes and count votes for individual accounts.

Copy link
Contributor

Choose a reason for hiding this comment

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

The bitmap should generally only be used for when we expect identical votes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated the consensus.

Comment on lines +31 to +35
pub trait SolanaVaultSwapAccountsHook<Account, SwapDetails, E> {
fn close_accounts(accounts: Vec<Account>) -> Result<(), E>;
fn initiate_vault_swap(swap_details: SwapDetails);
fn get_number_of_available_sol_nonce_accounts() -> usize;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think we should be coupling this so tightly to Solana.

Can we not follow the same patterns/conventions as we previously have, with the hooks defined externally rather than in the pallet?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since this is a solana specific Electoral system for a specific use-case, I dont see any problem having a custom hook.

Can we not follow the same patterns/conventions as we previously have, with the hooks defined externally rather than in the pallet?

not sure what you mean here? this follows the pattern we use in other electoral systems where we define a hook alongside the electoral system (which the electoral system uses to call into) and then implement the hook at the runtime level where we initialize the electoral system.

Copy link
Collaborator

Choose a reason for hiding this comment

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

What I mean is that this electoral system includes a lot of non-election/consensus related logic inside of itself. ie. the interfaces for other electoral systems is defined in term of hooks that trigger externally-defined logic. However here the 'hooks' are not really hooks: they are accessors to specific external functionality, and the logic for how to process those things is internal to the election. We're mixing contexts.

Rather than get_number_of_available_sol_nonce_accounts and initiate_vault_swap, I think it should just have a single hook that says something like on_account_change(added, removed); and the logic of what to do with that information should be defined externally.

Copy link
Contributor Author

@ramizhasan111 ramizhasan111 Oct 31, 2024

Choose a reason for hiding this comment

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

Given that its a custom election which is not intended to be re-used, I dont see why we cant have some custom logic in it especially if that logic is closely tied to what the election is about. We can rename the trait to not indicate that it is a hook but a general trait that calls some external code. The idea of injecting a trait that provides external code access is general enough here and the ElectoralSystem trait doesnt force us that the trait injected necessarily has to fit the definition of a hook (whatever that might be).

Even if we move out some of the functionality we would then need that logic to return some information back to the electoral system which it then uses to create a new election which would still mean it would still not function like a hook. This is just the nature of this electoral system use case.

In other electoral systems as well the code in on_finalize of the ElectoralSystem includes logic of first checking for consensus (calling the check_consensus) and then executing some logic to then decide whether to start a new election and with what properties. It is also the same here with just some external logic accessed through the Hook.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't want to spend days arguing back and forth about this. In general I would prefer if we follow existing patterns and conventions when possible, that's all. It makes maintenance easier, testing easier, reusability easier. Please keep it in mind in future.

There are always exceptions and grey areas, but I don't think this needed to be an exception.

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