Skip to content

Commit 892e408

Browse files
SuperFluffyjoroshiba
andauthoredJul 25, 2024··
refactor(core, proto)!: define bridge memos in proto (#1285)
## Summary Defines the bridge unlock, ics20 withdrawal, and ics20 deposit memos as protobuf. ## Background The various memos were read inside sequencer to inform the behaviour of the protocol, but were not defined in the canonical `astria.protocol.v1alpha1` protobufs. This patch defines the memo types in a new `astria.protocol.v1alpha1.memos` so that there is a single source of truth for all protocol-relevant objects. The memos are still only ever serialiazed as plaintext `JSON` and not as protobuf. ## Changes * Define the following types: * `astria.protocol.v1alpha1.memos.BridgeUnlock` * `astria.protocol.v1alpha1.memos.Ics20WithdrawalFromRollup` * `astria.protocol.v1alpha1.memos.Ics20TransferDeposit` * Remove the `astria_core::bridge` module * Update `astria_bridge_contracts`, `astria_bridge_withdrawer`, and `astria_sequencer` to operate in terms of these types * Update all memo fields containing bytes to be of type `string` so that the rollup-native formatting can be used (to make it easier to identify e.g. transactions and avoid the use of base64 for non-Astria byte slices) * Various field names have been updated to clarify that their source is the rollup (e.g. `rollup_transaction_hash`, `rollup_return_address`). ## Testing The changes in this code rely on smoke tests still working. Because the IBC tests require the latest (rust) astria-cli, the IBC tests were reworked. ## Breaking Changelist * This is a protocl breaking change: the shape of the memo JSON objects has changed (object keys were renamed, the encoding of byte fields no longer requires base64). ## Related Issues Closes #1286 --------- Co-authored-by: Jordan Oroshiba <[email protected]>
1 parent 961294c commit 892e408

34 files changed

+784
-557
lines changed
 

‎.github/workflows/docker-build.yml

+8-21
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ jobs:
191191
uses: helm/kind-action@v1
192192
with:
193193
install_only: true
194+
- name: Install astria cli (rust)
195+
run: just install-cli
196+
- name: Fetch and install celestia-appd
197+
run: just get-celestia-appd v1.9.0 Linux x86_64
194198
- name: Log in to GHCR
195199
uses: docker/login-action@v2
196200
with:
@@ -204,27 +208,10 @@ jobs:
204208
just deploy cluster
205209
kubectl create secret generic regcred --from-file=.dockerconfigjson=$HOME/.docker/config.json --type=kubernetes.io/dockerconfigjson
206210
echo -e "\n\nDeploying with astria images tagged $TAG"
207-
just deploy ibc-test-infra $TAG
208-
just build-and-load-bridge-tester-image $TAG
209-
- name: Run IBC Bridge Tester
210-
timeout-minutes: 2
211-
run: |
212-
TAG=sha-$(git rev-parse --short HEAD)
213-
printlogs() {
214-
echo "IBC Transfer Test failed, printing logs..."
215-
kubectl describe job bridge-tester-chart -n astria-dev-cluster
216-
kubectl logs job/bridge-tester-chart --all-containers -n astria-dev-cluster
217-
exit 1
218-
}
219-
just deploy bridge-tester $TAG
220-
# timeout before the gh job times out so we can print logs
221-
kubectl wait --for=condition=complete --timeout=90s job/bridge-tester-chart -n astria-dev-cluster || printlogs
222-
JOB_STATUS=$(kubectl get job bridge-tester-chart -n astria-dev-cluster -o jsonpath='{.status.succeeded}')
223-
if [ "$JOB_STATUS" != "1" ]; then
224-
printlogs
225-
else
226-
echo "IBC Transfer Test passed"
227-
fi
211+
just ibc-test deploy $TAG
212+
- name: Run IBC ICS20 Transfer test
213+
timeout-minutes: 3
214+
run: just ibc-test run ./celestia ./celestia-appd
228215

229216
docker:
230217
if: ${{ always() && !cancelled() }}

‎Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎charts/bridge-test/.helmignore

-23
This file was deleted.

‎charts/bridge-test/Chart.yaml

-28
This file was deleted.

‎charts/bridge-test/files/scripts/test-ibc-transfer.sh

-58
This file was deleted.

‎charts/bridge-test/templates/_helpers.tpl

-23
This file was deleted.

‎charts/bridge-test/templates/configmap.yaml

-26
This file was deleted.

‎charts/bridge-test/templates/job.yaml

-41
This file was deleted.

‎charts/bridge-test/values.yaml

-38
This file was deleted.

‎charts/deploy.just

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod ibc-test
2+
13
##############################################
24
## Deploying and Running using Helm and K8s ##
35
##############################################
@@ -225,6 +227,16 @@ init-rollup-bridge rollupName=defaultRollupName evmDestinationAddress=evm_destin
225227
--fee-asset=$FEE_ASSET --asset=$ASSET || exit 1
226228

227229

230+
init-ibc-bridge privateKey asset feeAsset rollupName=defaultRollupName:
231+
astria-cli sequencer init-bridge-account \
232+
--rollup-name {{ rollupName }} \
233+
--private-key {{ privateKey }} \
234+
--sequencer.chain-id {{ sequencer_chain_id }} \
235+
--sequencer-url {{ sequencer_rpc_url }} \
236+
--fee-asset {{ feeAsset }} \
237+
--asset {{ asset }}
238+
239+
228240
eth_rpc_url := "http://executor.astria.localdev.me/"
229241
eth_ws_url := "ws://ws-executor.astria.localdev.me/"
230242
bridge_tx_bytes := "0xf8f280843c54e7f182898594a58639fb5458e65e4fa917ff951c390292c24a15880de0b6b3a7640000b884bab916d00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002d617374726961313777306164656736346b7930646178776432756779756e65656c6c6d6a676e786c333935303400000000000000000000000000000000000000820a96a086b85348c9816f6d34533669db3d3626cf55eecea6a380d4d072efb1839df443a04b8b60c8b91dd30add1ca4a96097238d73bab29b0a958322d9a51755d5a5f287"

‎charts/ibc-test.just

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
defaultTag := ""
2+
3+
delete:
4+
-just delete celestia-local
5+
-just delete sequencer
6+
-just delete hermes-local
7+
-just delete rollup
8+
9+
@deploy tag=defaultTag:
10+
echo "Deploying ingress controller..." && just deploy-ingress-controller > /dev/null
11+
just wait-for-ingress-controller > /dev/null
12+
echo "Deploying local celestia instance..." && just deploy celestia-local > /dev/null
13+
helm dependency update ./sequencer > /dev/null
14+
helm dependency update ./evm-stack > /dev/null
15+
echo "Setting up single astria sequencer..." && helm install \
16+
-n astria-validator-single single-sequencer-chart ./sequencer \
17+
-f ../dev/values/validators/all.yml \
18+
-f ../dev/values/validators/single.yml \
19+
{{ if tag != '' { replace('--set images.sequencer.devTag=# --set sequencer-relayer.images.sequencerRelayer.devTag=#', '#', tag) } else { '' } }} \
20+
--create-namespace > /dev/null
21+
just wait-for-sequencer > /dev/null
22+
echo "Starting EVM rollup..." && helm install -n astria-dev-cluster astria-chain-chart ./evm-stack \
23+
-f ../dev/values/rollup/dev.yaml \
24+
-f ../dev/values/rollup/ibc-bridge-test.yaml \
25+
{{ if tag != '' { replace('--set evm-rollup.images.conductor.devTag=# --set composer.images.composer.devTag=# --set evm-bridge-withdrawer.images.evmBridgeWithdrawer.devTag=#', '#', tag) } else { '' } }} \
26+
--set blockscout-stack.enabled=false \
27+
--set postgresql.enabled=false \
28+
--set evm-faucet.enabled=false > /dev/null
29+
just wait-for-rollup > /dev/null
30+
echo "Deploying Hermes"
31+
just deploy hermes-local > /dev/null
32+
kubectl wait -n astria-dev-cluster deployment hermes-local-chart --for=condition=Available=True --timeout=300s
33+
34+
[no-cd]
35+
run celestiaHome pathToCelestiaAppd=default_celestia_appd :
36+
#!/usr/bin/env bash
37+
38+
initial_balance=$(just evm-get-balance {{evm_destination_address}})
39+
40+
# Create a bridge account on the sequencer
41+
just init-ibc-bridge {{ sequencer_tia_bridge_pkey }} transfer/channel-0/utia nria
42+
43+
# Load the private key of the Celestia dev account to issue transfers
44+
just ibc-test _load-celestia-key "{{ celestiaHome}}" "{{ pathToCelestiaAppd }}"
45+
46+
# Execute the transfer from Celestia to the Rollup
47+
just ibc-test _do-ibc-transfer "{{ celestiaHome}}" "{{ pathToCelestiaAppd }}"
48+
49+
# Multiplication factor is 10^-6 (utia to tia) * 10^18 (rollup factor) = 10^12
50+
let expected_balance="$initial_balance + {{ transfer_amount }} * 10**12"
51+
52+
for i in {1..50}
53+
do
54+
current_balance=$(just evm-get-balance {{evm_destination_address}})
55+
echo "check $i, balance: $current_balance, expected: $expected_balance"
56+
if (( expected_balance == $current_balance )); then
57+
expected_balance_found="1"
58+
break
59+
else
60+
sleep 1
61+
fi
62+
done
63+
if [[ -z $expected_balance_found ]]; then
64+
echo "expected balance was not found; IBC transfer from Celestia to the Rollup failed"
65+
exit 1
66+
fi
67+
68+
69+
bridge_address := "astria1d7zjjljc0dsmxa545xkpwxym86g8uvvwhtezcr"
70+
celestia_dev_account_address := "celestia1m0ksdjl2p5nzhqy3p47fksv52at3ln885xvl96"
71+
celestia_dev_account_key_name := "dev"
72+
celestia_dev_account_mnemonic := "enrich avocado local net will avoid dizzy truth column excuse ready lesson"
73+
celestia_chain_id := "celestia-local-0"
74+
celestia_node_url := "http://rpc.app.celestia.localdev.me:80"
75+
sequencer_tia_bridge_pkey := "6015fbe1c365d3c5ef92dc891db8c5bb26ad454bec2db4762b96e9f8b2430285"
76+
keyring_backend := "test"
77+
78+
# This is the same address as used in deploy.just
79+
evm_destination_address := "0xaC21B97d35Bf75A7dAb16f35b111a50e78A72F30"
80+
81+
# all in units of utia
82+
transfer_amount := "53000"
83+
transfer_fees := "26000"
84+
85+
default_celestia_appd := "celestia-appd"
86+
[no-cd]
87+
_load-celestia-key celestiaHome pathToCelestiaAppd=default_celestia_appd:
88+
#!/usr/bin/env bash
89+
pwd
90+
"{{pathToCelestiaAppd}}" keys add {{ celestia_dev_account_key_name }} \
91+
--home "{{celestiaHome}}" \
92+
--keyring-backend="{{ keyring_backend }}" \
93+
--recover <<< "{{ celestia_dev_account_mnemonic }}"
94+
95+
[no-cd]
96+
_do-ibc-transfer celestiaHome pathToCelestiaAppd=default_celestia_appd:
97+
echo "Performing IBC transfer..."
98+
"{{pathToCelestiaAppd}}" tx ibc-transfer transfer \
99+
transfer \
100+
channel-0 \
101+
{{ bridge_address }} \
102+
"{{ transfer_amount }}utia" \
103+
--memo="{\"rollupDepositAddress\":\"{{ evm_destination_address }}\"}" \
104+
--chain-id="{{ celestia_chain_id }}" \
105+
--node="{{ celestia_node_url }}" \
106+
--from="{{ celestia_dev_account_address }}" \
107+
--fees="{{ transfer_fees }}utia" \
108+
--yes \
109+
--log_level=debug \
110+
--home "{{celestiaHome}}" \
111+
--keyring-backend="{{ keyring_backend }}"

‎crates/astria-bridge-contracts/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ astria-core = { path = "../astria-core", features = ["serde"] }
1111
ethers = { workspace = true }
1212
futures = { workspace = true }
1313
ibc-types = { workspace = true }
14+
prost = { workspace = true }
15+
serde = { workspace = true }
1416
serde_json = { workspace = true }
1517
tendermint = { workspace = true }
1618
thiserror = { workspace = true }

‎crates/astria-bridge-contracts/src/lib.rs

+38-29
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ use astria_core::{
1212
Address,
1313
AddressError,
1414
},
15-
protocol::transaction::v1alpha1::{
16-
action::Ics20Withdrawal,
17-
Action,
15+
protocol::{
16+
memos,
17+
transaction::v1alpha1::{
18+
action::Ics20Withdrawal,
19+
Action,
20+
},
1821
},
1922
};
2023
use astria_withdrawer::{
@@ -370,15 +373,15 @@ where
370373
&self,
371374
log: Log,
372375
) -> Result<Action, GetWithdrawalActionsError> {
373-
let block_number = log
376+
let rollup_block_number = log
374377
.block_number
375378
.ok_or_else(|| GetWithdrawalActionsError::log_without_block_number(&log))?
376379
.as_u64();
377380

378-
let transaction_hash = log
381+
let rollup_transaction_hash = log
379382
.transaction_hash
380383
.ok_or_else(|| GetWithdrawalActionsError::log_without_transaction_hash(&log))?
381-
.into();
384+
.to_string();
382385

383386
let event = decode_log::<Ics20WithdrawalFilter>(log)
384387
.map_err(GetWithdrawalActionsError::decode_log)?;
@@ -393,15 +396,13 @@ where
393396
.expect("must be set if this method is entered"),
394397
);
395398

396-
let memo = serde_json::to_string(&astria_core::bridge::Ics20WithdrawalFromRollupMemo {
399+
let memo = memo_to_json(&memos::v1alpha1::Ics20WithdrawalFromRollup {
397400
memo: event.memo.clone(),
398-
block_number,
401+
rollup_block_number,
399402
rollup_return_address: event.sender.to_string(),
400-
transaction_hash,
403+
rollup_transaction_hash,
401404
})
402-
.map_err(|source| {
403-
GetWithdrawalActionsError::encode_memo("Ics20WithdrawalFromRollupMemo", source)
404-
})?;
405+
.map_err(GetWithdrawalActionsError::encode_memo)?;
405406

406407
let amount = calculate_amount(&event, self.asset_withdrawal_divisor)
407408
.map_err(GetWithdrawalActionsError::calculate_withdrawal_amount)?;
@@ -427,24 +428,24 @@ where
427428
&self,
428429
log: Log,
429430
) -> Result<Action, GetWithdrawalActionsError> {
430-
let block_number = log
431+
let rollup_block_number = log
431432
.block_number
432433
.ok_or_else(|| GetWithdrawalActionsError::log_without_block_number(&log))?
433434
.as_u64();
434435

435-
let transaction_hash = log
436+
let rollup_transaction_hash = log
436437
.transaction_hash
437438
.ok_or_else(|| GetWithdrawalActionsError::log_without_transaction_hash(&log))?
438-
.into();
439+
.to_string();
439440

440441
let event = decode_log::<SequencerWithdrawalFilter>(log)
441442
.map_err(GetWithdrawalActionsError::decode_log)?;
442443

443-
let memo = serde_json::to_string(&astria_core::bridge::UnlockMemo {
444-
block_number,
445-
transaction_hash,
444+
let memo = memo_to_json(&memos::v1alpha1::BridgeUnlock {
445+
rollup_block_number,
446+
rollup_transaction_hash,
446447
})
447-
.map_err(|err| GetWithdrawalActionsError::encode_memo("bridge::UnlockMemo", err))?;
448+
.map_err(GetWithdrawalActionsError::encode_memo)?;
448449

449450
let amount = calculate_amount(&event, self.asset_withdrawal_divisor)
450451
.map_err(GetWithdrawalActionsError::calculate_withdrawal_amount)?;
@@ -485,11 +486,8 @@ impl GetWithdrawalActionsError {
485486
))
486487
}
487488

488-
fn encode_memo(which: &'static str, source: serde_json::Error) -> Self {
489-
Self(GetWithdrawalActionsErrorKind::EncodeMemo {
490-
which,
491-
source,
492-
})
489+
fn encode_memo(source: EncodeMemoError) -> Self {
490+
Self(GetWithdrawalActionsErrorKind::EncodeMemo(source))
493491
}
494492

495493
fn get_logs(source: GetLogsError) -> Self {
@@ -513,11 +511,8 @@ enum GetWithdrawalActionsErrorKind {
513511
DecodeLog(DecodeLogError),
514512
#[error(transparent)]
515513
DestinationChainAsAddress(DestinationChainAsAddressError),
516-
#[error("failed encoding memo `{which}`")]
517-
EncodeMemo {
518-
which: &'static str,
519-
source: serde_json::Error,
520-
},
514+
#[error(transparent)]
515+
EncodeMemo(EncodeMemoError),
521516
#[error(transparent)]
522517
GetLogs(GetLogsError),
523518
#[error("log did not contain a block number")]
@@ -628,6 +623,20 @@ struct DestinationChainAsAddressError {
628623
source: AddressError,
629624
}
630625

626+
#[derive(Debug, thiserror::Error)]
627+
#[error("failed encoding memo `{proto_message}` as JSON")]
628+
struct EncodeMemoError {
629+
proto_message: String,
630+
source: serde_json::Error,
631+
}
632+
633+
fn memo_to_json<T: prost::Name + serde::Serialize>(memo: &T) -> Result<String, EncodeMemoError> {
634+
serde_json::to_string(memo).map_err(|source| EncodeMemoError {
635+
proto_message: T::full_name(),
636+
source,
637+
})
638+
}
639+
631640
fn parse_destination_chain_as_address(
632641
event: &SequencerWithdrawalFilter,
633642
) -> Result<Address, DestinationChainAsAddressError> {

‎crates/astria-bridge-withdrawer/src/bridge_withdrawer/startup.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ use std::{
44
};
55

66
use astria_core::{
7-
bridge::{
8-
self,
9-
Ics20WithdrawalFromRollupMemo,
10-
},
117
generated::sequencerblock::v1alpha1::{
128
sequencer_service_client::{
139
self,
@@ -19,6 +15,7 @@ use astria_core::{
1915
protocol::{
2016
asset::v1alpha1::AllowedFeeAssetsResponse,
2117
bridge::v1alpha1::BridgeAccountLastTxHashResponse,
18+
memos,
2219
transaction::v1alpha1::Action,
2320
},
2421
};
@@ -442,14 +439,15 @@ fn rollup_height_from_signed_transaction(
442439

443440
let last_batch_rollup_height = match withdrawal_action {
444441
Action::BridgeUnlock(action) => {
445-
let memo: bridge::UnlockMemo = serde_json::from_str(&action.memo)
442+
let memo: memos::v1alpha1::BridgeUnlock = serde_json::from_str(&action.memo)
446443
.wrap_err("failed to parse memo from last transaction by the bridge account")?;
447-
Some(memo.block_number)
444+
Some(memo.rollup_block_number)
448445
}
449446
Action::Ics20Withdrawal(action) => {
450-
let memo: Ics20WithdrawalFromRollupMemo = serde_json::from_str(&action.memo)
451-
.wrap_err("failed to parse memo from last transaction by the bridge account")?;
452-
Some(memo.block_number)
447+
let memo: memos::v1alpha1::Ics20WithdrawalFromRollup =
448+
serde_json::from_str(&action.memo)
449+
.wrap_err("failed to parse memo from last transaction by the bridge account")?;
450+
Some(memo.rollup_block_number)
453451
}
454452
_ => None,
455453
}

‎crates/astria-core/src/bridge.rs

-91
This file was deleted.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/astria-core/src/generated/mod.rs

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/astria-core/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ compile_error!(
66
#[rustfmt::skip]
77
pub mod generated;
88

9-
pub mod bridge;
109
pub mod crypto;
1110
pub mod execution;
1211
pub mod primitive;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod v1alpha1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
source: crates/astria-core/src/protocol/memos/v1alpha1.rs
3+
expression: memo
4+
---
5+
{
6+
"rollupBlockNumber": "42",
7+
"rollupTransactionHash": "a-rollup-defined-hash"
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
source: crates/astria-core/src/protocol/memos/v1alpha1.rs
3+
expression: memo
4+
---
5+
{
6+
"rollupDepositAddress": "an-address-on-the-rollup"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
source: crates/astria-core/src/protocol/memos/v1alpha1.rs
3+
expression: memo
4+
---
5+
{
6+
"rollupBlockNumber": "1",
7+
"rollupTransactionHash": "a-rollup-defined-hash",
8+
"rollupReturnAddress": "a-rollup-defined-address",
9+
"memo": "hello"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
pub use crate::generated::protocol::memos::v1alpha1::{
2+
BridgeUnlock,
3+
Ics20TransferDeposit,
4+
Ics20WithdrawalFromRollup,
5+
};
6+
7+
#[cfg(all(feature = "serde", test))]
8+
mod test {
9+
use super::*;
10+
11+
#[test]
12+
fn bridge_unlock_memo_snapshot() {
13+
let memo = BridgeUnlock {
14+
rollup_block_number: 42,
15+
rollup_transaction_hash: "a-rollup-defined-hash".to_string(),
16+
};
17+
18+
insta::assert_json_snapshot!(memo);
19+
}
20+
21+
#[test]
22+
fn ics20_withdrawal_from_rollup_memo_snapshot() {
23+
let memo = Ics20WithdrawalFromRollup {
24+
rollup_block_number: 1,
25+
rollup_return_address: "a-rollup-defined-address".to_string(),
26+
rollup_transaction_hash: "a-rollup-defined-hash".to_string(),
27+
memo: "hello".to_string(),
28+
};
29+
30+
insta::assert_json_snapshot!(memo);
31+
}
32+
33+
#[test]
34+
fn ics20_transfer_deposit_memo_snapshot() {
35+
let memo = Ics20TransferDeposit {
36+
rollup_deposit_address: "an-address-on-the-rollup".to_string(),
37+
};
38+
39+
insta::assert_json_snapshot!(memo);
40+
}
41+
}

‎crates/astria-core/src/protocol/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod abci;
77
pub mod account;
88
pub mod asset;
99
pub mod bridge;
10+
pub mod memos;
1011
pub mod transaction;
1112

1213
#[cfg(any(feature = "test-utils", test))]

‎crates/astria-core/src/serde.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
use base64_serde::base64_serde_type;
2-
use serde::{
3-
Deserializer,
4-
Serializer,
5-
};
2+
use serde::Serializer;
63

74
base64_serde_type!(pub(crate) Base64Standard, base64::engine::general_purpose::STANDARD);
85
pub(crate) fn base64_serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
@@ -12,12 +9,3 @@ where
129
{
1310
Base64Standard::serialize(value, serializer)
1411
}
15-
16-
pub(crate) fn base64_deserialize_array<'de, T, D>(deserializer: D) -> Result<T, D::Error>
17-
where
18-
T: TryFrom<Vec<u8>>,
19-
D: Deserializer<'de>,
20-
{
21-
let bytes = Base64Standard::deserialize(deserializer)?;
22-
T::try_from(bytes).map_err(|_| serde::de::Error::custom("invalid array length"))
23-
}

‎crates/astria-core/src/snapshots/astria_core__bridge__test__bridge_unlock_memo_snapshot.snap

-8
This file was deleted.

‎crates/astria-core/src/snapshots/astria_core__bridge__test__ics20_transfer_deposit_memo_snapshot.snap

-7
This file was deleted.

‎crates/astria-core/src/snapshots/astria_core__bridge__test__ics20_withdrawal_from_rollup_memo_snapshot.snap

-10
This file was deleted.

‎crates/astria-sequencer/src/ibc/ics20_transfer.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,14 @@ use anyhow::{
1818
Result,
1919
};
2020
use astria_core::{
21-
bridge::{
22-
Ics20TransferDepositMemo,
23-
Ics20WithdrawalFromRollupMemo,
24-
},
2521
primitive::v1::{
2622
asset::{
2723
denom,
2824
Denom,
2925
},
3026
Address,
3127
},
28+
protocol::memos,
3229
sequencerblock::v1alpha1::block::Deposit,
3330
};
3431
use cnidarium::{
@@ -412,7 +409,9 @@ async fn execute_ics20_transfer<S: StateWriteExt>(
412409
//
413410
// in this case, we lock the tokens back in the bridge account and
414411
// emit a `Deposit` event to send the tokens back to the rollup.
415-
if is_refund && serde_json::from_str::<Ics20WithdrawalFromRollupMemo>(&packet_data.memo).is_ok()
412+
if is_refund
413+
&& serde_json::from_str::<memos::v1alpha1::Ics20WithdrawalFromRollup>(&packet_data.memo)
414+
.is_ok()
416415
{
417416
let bridge_account = packet_data.sender.parse().context(
418417
"sender not an Astria Address: for refunds of ics20 withdrawals that came from a \
@@ -581,20 +580,27 @@ async fn execute_ics20_transfer_bridge_lock<S: StateWriteExt>(
581580
}
582581

583582
// assert memo is valid
584-
let deposit_memo: Ics20TransferDepositMemo =
583+
let deposit_memo: memos::v1alpha1::Ics20TransferDeposit =
585584
serde_json::from_str(&memo).context("failed to parse memo as Ics20TransferDepositMemo")?;
586585

587586
ensure!(
588-
!deposit_memo.rollup_address.is_empty(),
589-
"packet memo field must be set for bridge account recipient",
587+
!deposit_memo.rollup_deposit_address.is_empty(),
588+
"rollup deposit address must be set to bridge funds from sequencer to rollup",
590589
);
591590

592591
ensure!(
593-
deposit_memo.rollup_address.len() <= MAX_ROLLUP_ADDRESS_BYTE_LENGTH,
592+
deposit_memo.rollup_deposit_address.len() <= MAX_ROLLUP_ADDRESS_BYTE_LENGTH,
594593
"rollup address is too long: exceeds MAX_ROLLUP_ADDRESS_BYTE_LENGTH",
595594
);
596595

597-
execute_deposit(state, recipient, denom, amount, deposit_memo.rollup_address).await
596+
execute_deposit(
597+
state,
598+
recipient,
599+
denom,
600+
amount,
601+
deposit_memo.rollup_deposit_address,
602+
)
603+
.await
598604
}
599605

600606
async fn execute_deposit<S: StateWriteExt>(
@@ -766,8 +772,8 @@ mod test {
766772
.put_bridge_account_ibc_asset(&bridge_address, &denom)
767773
.unwrap();
768774

769-
let memo = Ics20TransferDepositMemo {
770-
rollup_address: "rollupaddress".to_string(),
775+
let memo = memos::v1alpha1::Ics20TransferDeposit {
776+
rollup_deposit_address: "rollupaddress".to_string(),
771777
};
772778

773779
let packet = FungibleTokenPacketData {
@@ -1047,11 +1053,11 @@ mod test {
10471053
sender: bridge_address.to_string(),
10481054
amount: "100".to_string(),
10491055
receiver: "other-chain-address".to_string(),
1050-
memo: serde_json::to_string(&Ics20WithdrawalFromRollupMemo {
1056+
memo: serde_json::to_string(&memos::v1alpha1::Ics20WithdrawalFromRollup {
10511057
memo: String::new(),
1052-
block_number: 1,
1058+
rollup_block_number: 1,
10531059
rollup_return_address: "rollup-defined".to_string(),
1054-
transaction_hash: [1u8; 32],
1060+
rollup_transaction_hash: hex::encode([1u8; 32]),
10551061
})
10561062
.unwrap(),
10571063
};

‎dev/bridgetester.just

-71
This file was deleted.

‎dev/containerfiles/bridgetesterutility.Dockerfile

-44
This file was deleted.

‎justfile

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'charts/deploy.just'
2-
import 'dev/bridgetester.just'
32

43
default:
54
@just --list
@@ -14,6 +13,22 @@ docker-build crate tag=default_docker_tag:
1413
install-cli:
1514
cargo install --path ./crates/astria-cli --locked
1615

16+
# version is a celestia-app release. Example: v1.9.0
17+
# operatingSystem is Linux or Darwin
18+
# machineHardwareName is arm64 or x86_64
19+
celestia_default_appd_dst := "."
20+
get-celestia-appd version operatingSystem machineHardwareName dst=celestia_default_appd_dst:
21+
#!/usr/bin/env bash
22+
src="celestia-app_{{operatingSystem}}_{{machineHardwareName}}.tar.gz"
23+
curl -LOsS -q --output-dir "{{dst}}" \
24+
https://github.com/celestiaorg/celestia-app/releases/download/{{version}}/"$src"
25+
curl -LOsS -q --output-dir "{{dst}}" \
26+
https://github.com/celestiaorg/celestia-app/releases/download/{{version}}/checksums.txt
27+
cd "{{dst}}"
28+
sha256sum --ignore-missing -c checksums.txt
29+
cd -
30+
tar --directory "{{dst}}" -xvzf "{{dst}}"/"$src" celestia-appd
31+
1732
# Compiles the generated rust code from protos which are used in crates.
1833
compile-protos:
1934
cargo run --manifest-path tools/protobuf-compiler/Cargo.toml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Memo types that are intended to only be serialized as plaintext JSON and encoded
2+
// as binary/protobuf. The intent is to follow the IBC convention of keeping memos as
3+
// JSON. The specific JSON formatting should follows the pbjson mapping.
4+
//
5+
// XXX: Different from protobuf any changes in the field names is protocol breaking,
6+
// because these messages are serialized as plaintext JSON.
7+
8+
syntax = "proto3";
9+
10+
package astria.protocol.memos.v1alpha1;
11+
12+
message BridgeUnlock {
13+
// The block number on the rollup that triggered the transaction underlying
14+
// this bridge unlock memo.
15+
uint64 rollup_block_number = 1;
16+
// The hash of the original rollup transaction that triggered a bridge unlock
17+
// and that is underlying this bridge unlock memo.
18+
//
19+
// This field is of type `string` so that it can be formatted in the preferred
20+
// format of the rollup when targeting plain text encoding.
21+
string rollup_transaction_hash = 2;
22+
}
23+
24+
// Memo for an ICS20 withdrawal from the rollup which is sent to
25+
// an external IBC-enabled chain.
26+
message Ics20WithdrawalFromRollup {
27+
// The block number on the rollup that triggered the transaction underlying
28+
// this ics20 withdrawal memo.
29+
uint64 rollup_block_number = 1;
30+
// The hash of the original rollup transaction that triggered this ics20
31+
// withdrawal and that is underlying this bridge unlock memo.
32+
//
33+
// This field is of type `string` so that it can be formatted in the preferred
34+
// format of the rollup when targeting plain text encoding.
35+
string rollup_transaction_hash = 2;
36+
// The return address on the rollup to which funds should returned in case of
37+
// failure. This field exists so that the rollup can identify which account
38+
// the returned funds originated from.
39+
//
40+
// This field is of type `string` so that it can be formatted in the preferred
41+
// format of the rollup when targeting plain text encoding.
42+
string rollup_return_address = 3;
43+
// A field that can be populated by the rollup. It is assumed that this field
44+
// will be consumed by the downstream chain.
45+
string memo = 4;
46+
}
47+
48+
// Memo for an ICS20 transfer to Astria which is sent to a
49+
// bridge account, which will then be deposited into the rollup.
50+
message Ics20TransferDeposit {
51+
// The destination address for the deposit on the rollup.
52+
//
53+
// This field is of type `string` so that it can be formatted in the preferred
54+
// format of the rollup when targeting plain text encoding.
55+
string rollup_deposit_address = 1;
56+
}

0 commit comments

Comments
 (0)
Please sign in to comment.