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

AddressLoader: allow for non-owned MessageAddressTableLookup #2592

Merged
merged 2 commits into from
Aug 19, 2024

Conversation

apfitzge
Copy link

Problem

  • [Tracking] TransactionView #2255 - we no longer have owned data for these MessageAddressTableLookup nor do we have a slice.
  • The interface for AddressLoader is overly restrictive

Summary of Changes

  • Add new function to AddressLoader which allows a for a non-owning iterator
  • Keep the old function to mostly allow for backwards compatibility

Fixes #

@apfitzge
Copy link
Author

I hate adding something new to sdk. But feel we are somewhat bound by previous mistakes in the area.

  • SanitizedTransaction construction depends on this trait (rather than LoadedAddresses).
  • ^ above forces AddressLoader to be part of sdk
  • We originally chose to just re-use the MessageAddressTableLookup for AddressLoader (easier at the time)
  • ^ above forces us to have an owned MessageAddressTableLookup even though the behavior it is supposed to abstract does not require that ownership

@apfitzge
Copy link
Author

apfitzge commented Aug 14, 2024

@jstarry think you're familiar with loading. Please let me know what you think.
For now, I'm keeping the interface which forces allocation internally - though it seems possible we may in the future want to allow for a pre-allocated vec to be passed in and populated.

@LucasSte relevant to the new TransactionView and iteration over the ATLs - iterator would use Item = MessageAddressTableLookupRef<'a>

Another option would be to move this out of sdk entirely, and make SanitizedTransaction::try_new just take LoadedAddresses as an argument instead.

@apfitzge apfitzge requested review from LucasSte and jstarry August 14, 2024 16:13
@apfitzge apfitzge marked this pull request as ready for review August 14, 2024 16:18
@apfitzge apfitzge self-assigned this Aug 14, 2024
@jstarry
Copy link

jstarry commented Aug 15, 2024

Can you explain more why you wouldn't have owned data or even a slice of lookups?

@apfitzge
Copy link
Author

Can you explain more why you wouldn't have owned data or even a slice of lookups?

The new transaction type(s) that are in progress, do not deserialize data in the same way our current transaction types. There's no forced allocation - the transaction accesses fields directly from the packet data and some cached offsets.

Some difficulty comes with the instructions and ATLs in the message, since these structs do not have fixed serialized sizes (because their internal vecs are serialized inline).
Current plan is to handle ATLs similarly to how we handled instructions: #2580 - only providing an interface to iterate over them (that's the only way we ever use them).

@jstarry
Copy link

jstarry commented Aug 15, 2024

Got it, makes sense to me. Can we add a new AddressLoaderByRef (naming?) trait instead of adding a new method to the existing trait? Adding a new method is technically a breaking change to the sdk. And yes it's rather unfortunate that this all lives in the sdk.

@apfitzge
Copy link
Author

apfitzge commented Aug 15, 2024

Got it, makes sense to me. Can we add a new AddressLoaderByRef (naming?) trait instead of adding a new method to the existing trait? Adding a new method is technically a breaking change to the sdk. And yes it's rather unfortunate that this all lives in the sdk.

That seems reasonable. It seems we could move this new trait out of sdk. Though I wonder where the best place for it is...new crate, or maybe runtime?

For Bank we change the impl of AddressLoader to call this new trait, but keep the old sdk trait for SanitizedTransaction stuff.

edit: Thinking for a moment, I think runtime is probably good. This address resolver is ideally non-public (imo). It should be meant strictly for our runtime to prepare transactions for execution, not used by users.

@jstarry
Copy link

jstarry commented Aug 15, 2024

Yeah runtime sounds reasonable to me. Note that it's still useful for users to construct a SanitizedTransaction by supplying their own loaded addresses (they can get them from tx metadata via RPC). But this doesn't need to be via a trait necessarily.

@apfitzge
Copy link
Author

Yeah runtime sounds reasonable to me. Note that it's still useful for users to construct a SanitizedTransaction by supplying their own loaded addresses (they can get them from tx metadata via RPC). But this doesn't need to be via a trait necessarily.

Yeah, my thinking is we won't change SanitizedTransaction. Our internal code won't use it anymore (eventually), but it the user-facing type and I don't see that going away entirely.

@apfitzge apfitzge force-pushed the address_loader_refactor branch from 54ba97b to 969017e Compare August 15, 2024 14:52

impl Bank {
/// Load addresses from an iterator of `MessageAddressTableLookupRef`.
pub fn load_addresses_from_ref<'a>(
Copy link
Author

Choose a reason for hiding this comment

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

Don't even need a trait - this is just a function on Bank. We will/can use this for resolving our transactions inside core/runtime.

@@ -103,6 +103,27 @@ impl AddressTableLookupMeta {
}
}

/// A non-owning version of `MessageAddressTableLookup`.
pub struct MessageAddressTableLookupRef<'a> {
Copy link
Author

Choose a reason for hiding this comment

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

struct defined here because ideally this is the same type that Bank's function takes. If same struct, needs to be somewhere that's accessible to both transaction-view and runtime, so this made more sense to me. I don't think it makes much sense to put this in its' own crate for something so simple; nor does it belong in svm-transaction since those are already resolved and SVM needs no knowledge of these.

Copy link
Author

Choose a reason for hiding this comment

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

Iterator to access these using TransactionMeta is not here yet, want to agree on where this lives and I'll do a follow-up PR to add the iterator once this is settled.

Copy link
Author

Choose a reason for hiding this comment

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

Welp - turns out I am actually dumb. I already have the type I need, from svm-transaction.

It is there beacuse we (sometimes) need to re-sanitize transactions in the runtime - though that's not explicitly part of SVM.

jstarry
jstarry previously approved these changes Aug 15, 2024
Comment on lines 30 to 34
self.load_addresses_from_ref(
address_table_lookups
.iter()
.map(MessageAddressTableLookupRef::from),
)
Copy link

@LucasSte LucasSte Aug 16, 2024

Choose a reason for hiding this comment

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

It is advantageous to add another indirection before calling the function? It seems to me that we are doing more work to first create the references then to call the function.

Copy link
Author

Choose a reason for hiding this comment

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

Change here will not make this any faster - and you're right, it may even be slightly slower (copying a reference and 2 slice ptrs => ~40 bytes).

Copy link
Author

Choose a reason for hiding this comment

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

^ To clarify - we do this mapping so we can use a shared implementation. Not for a specific benefit to the current function.

Additionally, the plan is for this function to not be called in our processing pipeline.

@apfitzge apfitzge merged commit 5b703d0 into anza-xyz:master Aug 19, 2024
40 checks passed
@apfitzge apfitzge deleted the address_loader_refactor branch August 19, 2024 13:09
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.

3 participants