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

LPv2: Batch message logic #1923

Closed
wants to merge 9 commits into from
Closed

LPv2: Batch message logic #1923

wants to merge 9 commits into from

Conversation

lemunozm
Copy link
Contributor

@lemunozm lemunozm commented Jul 22, 2024

Description

Responsibilities

  • pallet-liquidity-pools-gateway knows to batch/unbatch but doesn't know what a Batch message is. To handle this, the LPMessage trait now allows pack/unpack methods.
  • pallet-liquidity-pools will never send or receive a batch. The gateway is the responsible for the batching process.

Details

Batching is handled by two extrinsic:

  • Gateway::start_pack_messages(sender, destination): When calling this, any submitted messages from LP, that match the sender & destination will be packed. NOTE: We need to index also by destination domain because the destination information is not inside the message. So, we can never bundle two messages with two different destinations.
  • Gateway::end_pack_messages(sender, destination): When calling this, the batch is finally submitted. If this is not called, no message is sent. If the batch reaches the limit size, it will dispatch an error.

Later, the user can call pallet_utility::batch(calls) and any message sent between start_pack and end_pack will be bundled in the batch.

This PR depends on: #1920

Changes

  • Added Gateway::start_pack_messages() and Gateway::end_pack_messages() to allow creating batches.
  • Renamed process_msg() to receive_message(). Added a new parameter to be able to measure the weight correctly.
  • Renamed process_message() to send_message(). Measure the weight there based on the serialized message len.
  • Removed try_range for header message deserialization and use a BufferReader.
  • Removed defensive_weights.rs file and use more adjusted weights that take into account batch messages.
  • Added a weight() method to OutboundQueue trait that allows to compute correct weights from liquidity_pools taking into account batch sizes.

@lemunozm lemunozm added the I8-enhancement An additional feature. label Jul 22, 2024
@lemunozm lemunozm self-assigned this Jul 22, 2024
@lemunozm
Copy link
Contributor Author

lemunozm commented Jul 22, 2024

@mustermeiszer I had a lot of issues implementing the batch(calls) method regarding filtering the accounts (that some calls can be root), different destinations, nested calls to batch, weights…

I think this hybrid solution is simpler if you’re happy with the fulfilling requirements (I think everything we’ve talked about is fulfilled here). It gives enough control and never leaves the batch decision to the on_idle. Weights can be easily measured and handled out of on_idle.

The user will use this with pallet_utility::batch(calls) along with the Gateway start/end methods

Comment on lines 524 to 526
for msg in incoming_msg.unpack() {
T::InboundQueue::submit(domain_address.clone(), msg)?;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Weight of this function must take into account the maximum batch size possible. Defined by the deserialization implemenation.

Copy link
Contributor Author

@lemunozm lemunozm Jul 29, 2024

Choose a reason for hiding this comment

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

This is really difficult to measure because, right now, it's "not measured". It's using hardcoded weights. The real weight of this does not depend on how many bytes we read from the message, it mostly depends of what messages are in the batch that will dispatch certain actions. i.e., if this message is an increase it will call to foreign investments and would imply swaps having a weight increase.

I'm not sure what kind of solution we want to follow here.

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've got one which multiplies the current weight used by the number of messages in the batch

pallets/liquidity-pools-gateway/src/lib.rs Outdated Show resolved Hide resolved
pallets/liquidity-pools-gateway/src/lib.rs Outdated Show resolved Hide resolved
pallets/liquidity-pools-gateway/src/lib.rs Show resolved Hide resolved
Comment on lines 774 to 775
let message_weight =
read_weight.saturating_add(Weight::from_parts(0, serialized.len() as u64));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Message PoV size evaluated here

Copy link
Contributor Author

@lemunozm lemunozm left a comment

Choose a reason for hiding this comment

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

Some comments from the tricky parts:

Comment on lines +427 to 437
#[pallet::weight(T::WeightInfo::receive_message().saturating_mul(
Pallet::<T>::deserialize_message(expected_gateway_origin.clone(), msg.clone())
.map(|(_, msg)| msg.unpack().len() as u64)
.unwrap_or(T::Message::MAX_PACKED_MESSAGES as u64)
)
)]
#[pallet::call_index(5)]
pub fn process_msg(
pub fn receive_message(
origin: OriginFor<T>,
expected_gateway_origin: GatewayOrigin,
msg: BoundedVec<u8, T::MaxIncomingMessageSize>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even though origin is the same as the GatewayOrigin, we need to pass this extra parameter to be able to read it from the pallet::weight() macro (inside that macro, we do not have access to origin). We need to read this to know how to deserialize the message and then, knows how many message in a batch we have, adjusting upfront the weight consequently

Comment on lines +790 to +794
fn weight() -> Weight {
T::DbWeight::get()
.reads_writes(3, 4)
.saturating_add(Weight::from_parts(0, T::Message::max_encoded_len() as u64))
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we compute the weight needed to enqueue a message the could be a batch. This size is different to the used when sending the message, which use the serialized sized.

Comment on lines +950 to +954
fn outbound_weight(reads: u64, writes: u64) -> Weight {
Weight::from_parts(1_000_000, 256) //defensive base weights
.saturating_add(T::DbWeight::get().reads_writes(reads, writes))
.saturating_add(T::OutboundQueue::weight())
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This takes into account the correct OutboundQueue::submit() weights even when the message is a batch. We no longer need defensive_weights.rs

@lemunozm lemunozm marked this pull request as ready for review July 29, 2024 10:54
@lemunozm
Copy link
Contributor Author

lemunozm commented Jul 29, 2024

Maybe we should wait to merge @cosmin PRs first if they have more priority to avoid wasting time with conflict (that will be a lot 😄). Anyways this is ready to be reviewed in the meantime

Copy link

codecov bot commented Jul 29, 2024

Codecov Report

Attention: Patch coverage is 52.00000% with 60 lines in your changes missing coverage. Please review.

Please upload report for BASE (feat/lp-v2@ecd8821). Learn more about missing BASE report.

Files Patch % Lines
pallets/liquidity-pools-gateway/src/lib.rs 58.06% 39 Missing ⚠️
pallets/liquidity-pools/src/message.rs 0.00% 8 Missing ⚠️
pallets/liquidity-pools/src/lib.rs 0.00% 5 Missing ⚠️
...pools-gateway/axelar-gateway-precompile/src/lib.rs 0.00% 3 Missing ⚠️
libs/mocks/src/outbound_queue.rs 0.00% 2 Missing ⚠️
libs/traits/src/liquidity_pools.rs 50.00% 2 Missing ⚠️
libs/utils/src/lib.rs 90.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             feat/lp-v2    #1923   +/-   ##
=============================================
  Coverage              ?   47.89%           
=============================================
  Files                 ?      180           
  Lines                 ?    12895           
  Branches              ?        0           
=============================================
  Hits                  ?     6176           
  Misses                ?     6719           
  Partials              ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@lemunozm
Copy link
Contributor Author

lemunozm commented Aug 7, 2024

Closed in favor of #1949

@lemunozm lemunozm closed this Aug 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I8-enhancement An additional feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants