-
Notifications
You must be signed in to change notification settings - Fork 76
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
fix, refactor(sequencer): refactor ics20 logic #1495
Conversation
9ed086c
to
7476516
Compare
/// assert!(!denom.has_leading_port("")); | ||
/// ``` | ||
#[must_use] | ||
pub fn has_leading_port<T: AsRef<str>>(&self, port: T) -> bool { |
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.
Added has_leading_port
and has_leading_channel
to have a stricter prefix check instead of starts_with_str
.
return false; | ||
} | ||
parts.next().is_none() | ||
pub fn has_leading_channel<T: AsRef<str>>(&self, channel: T) -> bool { |
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.
Added has_leading_port
and has_leading_channel
to have a stricter prefix check instead of starts_with_str
.
@@ -1291,86 +1291,23 @@ impl FilteredSequencerBlockError { | |||
)] | |||
pub struct Deposit { |
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 stupid container without any invariants.
Made all fields public and removed the getters.
} | ||
|
||
impl Deposit { | ||
#[must_use] | ||
pub fn new( |
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.
Terrible evergrowing constructor. Since there are no invariants to be upheld I removed it in favor of directly constructing Deposit
from public fields.
@@ -1439,6 +1376,12 @@ impl Deposit { | |||
} | |||
} | |||
|
|||
impl From<Deposit> for crate::generated::sequencerblock::v1alpha1::Deposit { |
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.
Not new, just moved down from above; this is an artifact of the refactor, but the trait impl fits better down here.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
|
||
#[async_trait] | ||
pub(crate) trait StateWriteExt: StateWrite { | ||
#[instrument(skip_all, fields(%channel))] | ||
async fn decrease_ibc_channel_balance<TAsset>( |
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.
New utility to atomically read-update-write the balance on the escrow account.
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
crates/astria-sequencer/src/utils.rs
Outdated
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.
contains only changes due to deposit losing its getters
let ack: TokenTransferAcknowledgement = | ||
serde_json::from_slice(msg.acknowledgement.as_slice()) | ||
.context("failed to deserialize token transfer acknowledgement")?; | ||
if !ack.is_successful() { |
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 just flips the logic: instead of returning early on success, success is now the fall-through case while failure triggers a refund.
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 file should probably not be reviewed using its diff, but instead read from source.
As a high level overview:
execute_ics20_transfer
(that branched on an argument is_refund
) is split up into receive_tokens
and refund_tokens
.
Both functions were cleaned up and should be much easier to read.
|
||
// check if this is a transfer to a bridge account and | ||
// execute relevant state changes if it is | ||
execute_ics20_transfer_bridge_lock( |
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 believe this function was incorrect: its argument trace_with_dest = dest_port/dest_channel/source_port/source_channel/asset
was always constructed irrespective of whether sequencer was a source or a sink zone, but the construction is only correct if sequencer is a sink!
If sequencer is a source, then dest_port/dest_channel
must not be prepended, and instead source_port/soure_channel
removed, leaving just asset
.
bridge_address, | ||
&denom, | ||
memo.rollup_return_address, |
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 the actual fix for the incorrect deposit: instead of bridge_address
being used twice, the memo.rollup_return_address
is now put into destination_chain_address
field.
7476516
to
34e8132
Compare
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.
contains only changes due to Deposit::new
being replaced by direction declaration Deposit {}
.
34e8132
to
b8d2f27
Compare
0b09c08
to
5673d04
Compare
Rebased on top of recent main. In addition I instrumented all code that's called during ics20 execution, injecting address information, assets, amounts, etc into the generated spans. Function calls using eyre Reports as errors also generates an event in error cases. |
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.
looks good to me :D
Co-authored-by: noot <36753753+noot@users.noreply.github.com>
15efaec
to
be88e99
Compare
## Summary Fixes incorrect addresses in ics20 refunds, and fixes/adds source vs sink zone detection of received/refunded asets. ## Background This PR started with the goal of using `Ics20WithdrawalFromRollup.rollup_return_address` when emitting ics20 deposit events instead of the rollup's bridge address (which for the rollup was quite meaningless). However, because the original logic was overly convoluted, this patch evolved into a refactor which subsequently revealed 2 more bugs. ## Changes - Refactor ics20 logic: split up `execute_ics20_transfer` into two functions `receive_tokens` and `refund_tokens` - Fix deposit events being emitted with the packet sender/bridge address as the receiving address on the rollup: instead use `Ics20WithdrawalFromRollup.rollup_return_address` which is the address originally supplied and understood by the rollup. - Fix bridge lock events of source tokens being emitted with an extra (port, channel) pair added (this resulting token is likely completely meaningless and not understood by the rollup): instead strip the leading (port, channel) pair to get the original token on sequencer. - Fix refunds to a rollup of failed ics20 transfers not checking if sequencer is their source or sink zone: instead perform the check and decrease the ibc escrow account is necessary. ## Testing Renamed and expanded tests to also check for sink vs source zone assets being received, the correct asset being emitted in bridge lock events, and the correct rollup return address being emitted in refunds. Specifically these tests were added or renamed: - `receive_source_zone_asset_on_sequencer_account` - `receive_sink_zone_asset_on_sequencer_account` - `receive_source_zone_asset_on_bridge_account_and_emit_to_rollup` - `receive_sink_zone_asset_on_bridge_account_and_emit_to_rollup` - `transfer_to_bridge_is_rejected_due_to_invalid_memo` - `transfer_to_bridge_account_is_rejected_due_to_not_permitted_token` - `refund_sequencer_account_with_source_zone_asset` - `refund_sequencer_account_with_sink_zone_asset` - `refund_rollup_with_sink_zone_asset` - `refund_rollup_with_source_zone_asset` - `refund_rollup_with_source_zone_asset_compat_prefix` ## Related Issues Closes #1439 Closes #1496 Closes #1514 --------- Co-authored-by: noot <36753753+noot@users.noreply.github.com>
* main: feat(conductor): implement restart logic (#1463) fix: ignore `RUSTSEC-2024-0370` (#1483) fix, refactor(sequencer): refactor ics20 logic (#1495) fix(ci): use commit SHA instead of PR number preview-env images (#1501) chore(bridge-withdrawer): pass GRPC and CometBFT clients to consumers directly (#1510) fix(sequencer): Fix incorrect error message from BridgeUnlock actions (#1505) fix(bridge-contracts): fix memo transaction hash encoding (#1428) fix: build docker when workflow explicitly includes component (#1498) chore(sequencer): migrate from `anyhow::Result` to `eyre::Result` (#1387) fix(ci): typo for required field in sequencer preview-env (#1500) feat(ci): provide demo/preview environments (#1406)
Summary
Fixes incorrect addresses in ics20 refunds, and fixes/adds source vs sink zone detection of received/refunded asets.
Background
This PR started with the goal of using
Ics20WithdrawalFromRollup.rollup_return_address
when emitting ics20 deposit events instead of the rollup's bridge address (which for the rollup was quite meaningless).However, because the original logic was overly convoluted, this patch evolved into a refactor which subsequently revealed 2 more bugs.
Changes
execute_ics20_transfer
into two functionsreceive_tokens
andrefund_tokens
Ics20WithdrawalFromRollup.rollup_return_address
which is the address originally supplied and understood by the rollup.Testing
Renamed and expanded tests to also check for sink vs source zone assets being received, the correct asset being emitted in bridge lock events, and the correct rollup return address being emitted in refunds. Specifically these tests were added or renamed:
receive_source_zone_asset_on_sequencer_account
receive_sink_zone_asset_on_sequencer_account
receive_source_zone_asset_on_bridge_account_and_emit_to_rollup
receive_sink_zone_asset_on_bridge_account_and_emit_to_rollup
transfer_to_bridge_is_rejected_due_to_invalid_memo
transfer_to_bridge_account_is_rejected_due_to_not_permitted_token
refund_sequencer_account_with_source_zone_asset
refund_sequencer_account_with_sink_zone_asset
refund_rollup_with_sink_zone_asset
refund_rollup_with_source_zone_asset
refund_rollup_with_source_zone_asset_compat_prefix
Related Issues
Closes #1439
Closes #1496
Closes #1514