diff --git a/Cargo.lock b/Cargo.lock index d116d2712a..063e3a9d2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -795,6 +795,7 @@ dependencies = [ "astria-merkle", "astria-telemetry", "async-trait", + "base64 0.21.7", "borsh", "bytes", "cnidarium", @@ -3273,9 +3274,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -3283,9 +3284,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" @@ -3300,9 +3301,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -3331,9 +3332,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2 1.0.86", "quote", @@ -3342,15 +3343,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -3364,9 +3365,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", diff --git a/charts/sequencer/Chart.yaml b/charts/sequencer/Chart.yaml index 6af0ddafc1..a76eec5f5b 100644 --- a/charts/sequencer/Chart.yaml +++ b/charts/sequencer/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.23.1 +version: 0.23.2 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. diff --git a/charts/sequencer/templates/configmaps.yaml b/charts/sequencer/templates/configmaps.yaml index 2f49d4416c..b780ce003c 100644 --- a/charts/sequencer/templates/configmaps.yaml +++ b/charts/sequencer/templates/configmaps.yaml @@ -75,5 +75,6 @@ data: OTEL_SERVICE_NAME: "{{ tpl .Values.sequencer.otel.serviceName . }}" {{- if not .Values.global.dev }} {{- else }} + ASTRIA_SEQUENCER_MEMPOOL_PARKED_MAX_TX_COUNT: "{{ .Values.sequencer.mempool.parked.maxTxCount }}" {{- end }} --- diff --git a/charts/sequencer/values.yaml b/charts/sequencer/values.yaml index 3b7247dab1..85faf008db 100644 --- a/charts/sequencer/values.yaml +++ b/charts/sequencer/values.yaml @@ -71,6 +71,9 @@ genesis: # pubKey: lV57+rGs2vac7mvkGHP1oBFGHPJM3a+WoAzeFDCJDNU= sequencer: + mempool: + parked: + maxTxCount: 200 metrics: enabled: false otel: diff --git a/crates/astria-bridge-contracts/src/lib.rs b/crates/astria-bridge-contracts/src/lib.rs index f6cb8b7b8f..454f3df0a2 100644 --- a/crates/astria-bridge-contracts/src/lib.rs +++ b/crates/astria-bridge-contracts/src/lib.rs @@ -464,7 +464,7 @@ where let to = parse_destination_chain_as_address(&event) .map_err(GetWithdrawalActionsError::destination_chain_as_address)?; - let action = astria_core::protocol::transaction::v1alpha1::action::BridgeUnlockAction { + let action = astria_core::protocol::transaction::v1alpha1::action::BridgeUnlock { to, amount, rollup_block_number, diff --git a/crates/astria-bridge-withdrawer/tests/blackbox/helpers/test_bridge_withdrawer.rs b/crates/astria-bridge-withdrawer/tests/blackbox/helpers/test_bridge_withdrawer.rs index 7048b4cf2f..18006aaf34 100644 --- a/crates/astria-bridge-withdrawer/tests/blackbox/helpers/test_bridge_withdrawer.rs +++ b/crates/astria-bridge-withdrawer/tests/blackbox/helpers/test_bridge_withdrawer.rs @@ -22,7 +22,7 @@ use astria_core::{ memos::v1alpha1::Ics20WithdrawalFromRollup, transaction::v1alpha1::{ action::{ - BridgeUnlockAction, + BridgeUnlock, Ics20Withdrawal, }, Action, @@ -435,7 +435,7 @@ pub fn make_native_bridge_unlock_action(receipt: &TransactionReceipt) -> Action let rollup_transaction_hash = receipt.transaction_hash.encode_hex(); let event_index = receipt.logs[0].log_index.unwrap().encode_hex(); - let inner = BridgeUnlockAction { + let inner = BridgeUnlock { to: default_sequencer_address(), amount: 1_000_000u128, rollup_block_number: receipt.block_number.unwrap().as_u64(), @@ -485,7 +485,7 @@ pub fn make_erc20_bridge_unlock_action(receipt: &TransactionReceipt) -> Action { // use the second event because the erc20 transfer also emits an event let event_index = receipt.logs[1].log_index.unwrap().encode_hex(); - let inner = BridgeUnlockAction { + let inner = BridgeUnlock { to: default_sequencer_address(), amount: 1_000_000u128, rollup_block_number: receipt.block_number.unwrap().as_u64(), diff --git a/crates/astria-cli/src/sequencer/bridge_lock.rs b/crates/astria-cli/src/sequencer/bridge_lock.rs index baeabbc717..4c07db8040 100644 --- a/crates/astria-cli/src/sequencer/bridge_lock.rs +++ b/crates/astria-cli/src/sequencer/bridge_lock.rs @@ -4,7 +4,7 @@ use astria_core::{ Address, }, protocol::transaction::v1alpha1::{ - action::BridgeLockAction, + action::BridgeLock, Action, }, }; @@ -62,7 +62,7 @@ impl Command { self.sequencer_chain_id.clone(), &self.prefix, self.private_key.as_str(), - Action::BridgeLock(BridgeLockAction { + Action::BridgeLock(BridgeLock { to: self.to_address, asset: self.asset.clone(), amount: self.amount, diff --git a/crates/astria-cli/src/sequencer/init_bridge_account.rs b/crates/astria-cli/src/sequencer/init_bridge_account.rs index 1e411457eb..9149909ecb 100644 --- a/crates/astria-cli/src/sequencer/init_bridge_account.rs +++ b/crates/astria-cli/src/sequencer/init_bridge_account.rs @@ -1,7 +1,7 @@ use astria_core::{ primitive::v1::asset, protocol::transaction::v1alpha1::{ - action::InitBridgeAccountAction, + action::InitBridgeAccount, Action, }, }; @@ -57,7 +57,7 @@ impl Command { self.sequencer_chain_id.clone(), &self.prefix, self.private_key.as_str(), - Action::InitBridgeAccount(InitBridgeAccountAction { + Action::InitBridgeAccount(InitBridgeAccount { rollup_id, asset: self.asset.clone(), fee_asset: self.fee_asset.clone(), diff --git a/crates/astria-cli/src/sequencer/sudo/fee_asset.rs b/crates/astria-cli/src/sequencer/sudo/fee_asset.rs index 181c833cda..f1ac0a750a 100644 --- a/crates/astria-cli/src/sequencer/sudo/fee_asset.rs +++ b/crates/astria-cli/src/sequencer/sudo/fee_asset.rs @@ -1,7 +1,7 @@ use astria_core::{ primitive::v1::asset, protocol::transaction::v1alpha1::{ - action::FeeAssetChangeAction, + action::FeeAssetChange, Action, }, }; @@ -50,7 +50,7 @@ impl Add { args.sequencer_chain_id.clone(), &args.prefix, args.private_key.as_str(), - Action::FeeAssetChange(FeeAssetChangeAction::Addition(args.asset.clone())), + Action::FeeAssetChange(FeeAssetChange::Addition(args.asset.clone())), ) .await .wrap_err("failed to submit FeeAssetChangeAction::Addition transaction")?; @@ -75,7 +75,7 @@ impl Remove { args.sequencer_chain_id.clone(), &args.prefix, args.private_key.as_str(), - Action::FeeAssetChange(FeeAssetChangeAction::Removal(args.asset.clone())), + Action::FeeAssetChange(FeeAssetChange::Removal(args.asset.clone())), ) .await .wrap_err("failed to submit FeeAssetChangeAction::Removal transaction")?; diff --git a/crates/astria-cli/src/sequencer/sudo/ibc_relayer.rs b/crates/astria-cli/src/sequencer/sudo/ibc_relayer.rs index f8c190b157..8ec116cc79 100644 --- a/crates/astria-cli/src/sequencer/sudo/ibc_relayer.rs +++ b/crates/astria-cli/src/sequencer/sudo/ibc_relayer.rs @@ -1,7 +1,7 @@ use astria_core::{ primitive::v1::Address, protocol::transaction::v1alpha1::{ - action::IbcRelayerChangeAction, + action::IbcRelayerChange, Action, }, }; @@ -47,7 +47,7 @@ impl Add { args.sequencer_chain_id.clone(), &args.prefix, args.private_key.as_str(), - Action::IbcRelayerChange(IbcRelayerChangeAction::Addition(args.address)), + Action::IbcRelayerChange(IbcRelayerChange::Addition(args.address)), ) .await .wrap_err("failed to submit IbcRelayerChangeAction::Addition transaction")?; @@ -72,7 +72,7 @@ impl Remove { args.sequencer_chain_id.clone(), &args.prefix, args.private_key.as_str(), - Action::IbcRelayerChange(IbcRelayerChangeAction::Removal(args.address)), + Action::IbcRelayerChange(IbcRelayerChange::Removal(args.address)), ) .await .wrap_err("failed to submit IbcRelayerChangeAction::Removal transaction")?; diff --git a/crates/astria-cli/src/sequencer/sudo/sudo_address_change.rs b/crates/astria-cli/src/sequencer/sudo/sudo_address_change.rs index f93277440e..ecfcf2b823 100644 --- a/crates/astria-cli/src/sequencer/sudo/sudo_address_change.rs +++ b/crates/astria-cli/src/sequencer/sudo/sudo_address_change.rs @@ -1,7 +1,7 @@ use astria_core::{ primitive::v1::Address, protocol::transaction::v1alpha1::{ - action::SudoAddressChangeAction, + action::SudoAddressChange, Action, }, }; @@ -49,7 +49,7 @@ impl Command { self.sequencer_chain_id.clone(), &self.prefix, self.private_key.as_str(), - Action::SudoAddressChange(SudoAddressChangeAction { + Action::SudoAddressChange(SudoAddressChange { new_address: self.address, }), ) diff --git a/crates/astria-cli/src/sequencer/transfer.rs b/crates/astria-cli/src/sequencer/transfer.rs index 648156cd3e..7903d04fcf 100644 --- a/crates/astria-cli/src/sequencer/transfer.rs +++ b/crates/astria-cli/src/sequencer/transfer.rs @@ -4,7 +4,7 @@ use astria_core::{ Address, }, protocol::transaction::v1alpha1::{ - action::TransferAction, + action::Transfer, Action, }, }; @@ -61,7 +61,7 @@ impl Command { self.sequencer_chain_id.clone(), &self.prefix, self.private_key.as_str(), - Action::Transfer(TransferAction { + Action::Transfer(Transfer { to: self.to_address, amount: self.amount, asset: self.asset.clone(), diff --git a/crates/astria-cli/src/utils.rs b/crates/astria-cli/src/utils.rs index 543b52e333..1ea5d27efb 100644 --- a/crates/astria-cli/src/utils.rs +++ b/crates/astria-cli/src/utils.rs @@ -58,10 +58,10 @@ pub(crate) async fn submit_transaction( .await .wrap_err("failed to submit transaction")?; - let tx_response = sequencer_client.wait_for_tx_inclusion(res.hash).await; - ensure!(res.code.is_ok(), "failed to check tx: {}", res.log); + let tx_response = sequencer_client.wait_for_tx_inclusion(res.hash).await; + ensure!( tx_response.tx_result.code.is_ok(), "failed to execute tx: {}", diff --git a/crates/astria-composer/src/collectors/geth.rs b/crates/astria-composer/src/collectors/geth.rs index c2e4e4601a..3e0c190ee9 100644 --- a/crates/astria-composer/src/collectors/geth.rs +++ b/crates/astria-composer/src/collectors/geth.rs @@ -20,7 +20,7 @@ use astria_core::{ asset, RollupId, }, - protocol::transaction::v1alpha1::action::SequenceAction, + protocol::transaction::v1alpha1::action::Sequence, }; use astria_eyre::eyre::{ self, @@ -194,7 +194,7 @@ impl Geth { if let Some(tx) = tx_res { let tx_hash = tx.hash; let data = tx.rlp().to_vec(); - let seq_action = SequenceAction { + let seq_action = Sequence { rollup_id, data: data.into(), fee_asset: fee_asset.clone(), @@ -234,7 +234,7 @@ impl Geth { #[instrument(skip_all)] async fn forward_geth_tx( executor_handle: &Handle, - seq_action: SequenceAction, + seq_action: Sequence, tx_hash: ethers::types::H256, txs_dropped_counter: &Counter, ) -> eyre::Result<()> { diff --git a/crates/astria-composer/src/collectors/grpc.rs b/crates/astria-composer/src/collectors/grpc.rs index 091cca23b2..ca378960f6 100644 --- a/crates/astria-composer/src/collectors/grpc.rs +++ b/crates/astria-composer/src/collectors/grpc.rs @@ -12,7 +12,7 @@ use astria_core::{ asset, RollupId, }, - protocol::transaction::v1alpha1::action::SequenceAction, + protocol::transaction::v1alpha1::action::Sequence, }; use tokio::sync::mpsc::error::SendTimeoutError; use tonic::{ @@ -62,7 +62,7 @@ impl GrpcCollectorService for Grpc { return Err(Status::invalid_argument("invalid rollup id")); }; - let sequence_action = SequenceAction { + let sequence_action = Sequence { rollup_id, data: submit_rollup_tx_request.data, fee_asset: self.fee_asset.clone(), diff --git a/crates/astria-composer/src/executor/builder.rs b/crates/astria-composer/src/executor/builder.rs index 7234600f05..b84ef794d6 100644 --- a/crates/astria-composer/src/executor/builder.rs +++ b/crates/astria-composer/src/executor/builder.rs @@ -7,7 +7,7 @@ use std::{ use astria_core::{ crypto::SigningKey, primitive::v1::Address, - protocol::transaction::v1alpha1::action::SequenceAction, + protocol::transaction::v1alpha1::action::Sequence, }; use astria_eyre::eyre::{ self, @@ -63,7 +63,7 @@ impl Builder { .wrap_err("failed constructing a sequencer address from private key")?; let (serialized_rollup_transaction_tx, serialized_rollup_transaction_rx) = - tokio::sync::mpsc::channel::(256); + tokio::sync::mpsc::channel::(256); Ok(( super::Executor { diff --git a/crates/astria-composer/src/executor/bundle_factory/mod.rs b/crates/astria-composer/src/executor/bundle_factory/mod.rs index f4fb47eaaa..8c1c87fd1f 100644 --- a/crates/astria-composer/src/executor/bundle_factory/mod.rs +++ b/crates/astria-composer/src/executor/bundle_factory/mod.rs @@ -11,7 +11,7 @@ use std::{ use astria_core::{ primitive::v1::RollupId, protocol::transaction::v1alpha1::{ - action::SequenceAction, + action::Sequence, Action, UnsignedTransaction, }, @@ -29,9 +29,9 @@ mod tests; #[derive(Debug, thiserror::Error)] enum SizedBundleError { #[error("bundle does not have enough space left for the given sequence action")] - NotEnoughSpace(SequenceAction), + NotEnoughSpace(Sequence), #[error("sequence action is larger than the max bundle size")] - SequenceActionTooLarge(SequenceAction), + SequenceActionTooLarge(Sequence), } pub(super) struct SizedBundleReport<'a>(pub(super) &'a SizedBundle); @@ -78,7 +78,7 @@ impl SizedBundle { /// Constructs an [`UnsignedTransaction`] from the actions contained in the bundle and `params`. /// # Panics /// Method is expected to never panic because only `SequenceActions` are added to the bundle, - /// which should produce a valid variant of the `ActionGroup` type. + /// which should produce a valid variant of the [`action::Group`] type. pub(super) fn to_unsigned_transaction( &self, nonce: u32, @@ -91,8 +91,8 @@ impl SizedBundle { .try_build() .expect( "method is expected to never panic because only `SequenceActions` are added to \ - the bundle, which should produce a valid variant of the `ActionGroup` type; this \ - is checked by `tests::transaction_construction_should_not_panic", + the bundle, which should produce a valid variant of the `action::Group` type; \ + this is checked by `tests::transaction_construction_should_not_panic", ) } @@ -100,7 +100,7 @@ impl SizedBundle { /// # Errors /// - `seq_action` is beyond the max size allowed for the entire bundle /// - `seq_action` does not fit in the remaining space in the bundle - fn try_push(&mut self, seq_action: SequenceAction) -> Result<(), SizedBundleError> { + fn try_push(&mut self, seq_action: Sequence) -> Result<(), SizedBundleError> { let seq_action_size = encoded_len(&seq_action); if seq_action_size > self.max_size { @@ -162,7 +162,7 @@ pub(super) struct FinishedQueueFull { curr_bundle_size: usize, finished_queue_capacity: usize, sequence_action_size: usize, - seq_action: SequenceAction, + seq_action: Sequence, } impl From for BundleFactoryError { @@ -196,10 +196,7 @@ impl BundleFactory { /// Buffer `seq_action` into the current bundle. If the bundle won't fit `seq_action`, flush /// `curr_bundle` into the `finished` queue and start a new bundle, unless the `finished` queue /// is at capacity. - pub(super) fn try_push( - &mut self, - seq_action: SequenceAction, - ) -> Result<(), BundleFactoryError> { + pub(super) fn try_push(&mut self, seq_action: Sequence) -> Result<(), BundleFactoryError> { let seq_action = with_ibc_prefixed(seq_action); let seq_action_size = encoded_len(&seq_action); @@ -289,14 +286,14 @@ impl<'a> NextFinishedBundle<'a> { } } -fn with_ibc_prefixed(action: SequenceAction) -> SequenceAction { - SequenceAction { +fn with_ibc_prefixed(action: Sequence) -> Sequence { + Sequence { fee_asset: action.fee_asset.to_ibc_prefixed().into(), ..action } } -fn encoded_len(action: &SequenceAction) -> usize { +fn encoded_len(action: &Sequence) -> usize { use prost::Message as _; action.to_raw().encoded_len() } diff --git a/crates/astria-composer/src/executor/bundle_factory/tests.rs b/crates/astria-composer/src/executor/bundle_factory/tests.rs index 762934782e..31c6e2de8b 100644 --- a/crates/astria-composer/src/executor/bundle_factory/tests.rs +++ b/crates/astria-composer/src/executor/bundle_factory/tests.rs @@ -3,7 +3,7 @@ use astria_core::{ RollupId, ROLLUP_ID_LEN, }, - protocol::transaction::v1alpha1::action::SequenceAction, + protocol::transaction::v1alpha1::action::Sequence, }; mod sized_bundle { @@ -203,7 +203,7 @@ mod bundle_factory { // try to push a third bundle that wouldn't fit in `curr_bundle`, forcing the factory to // flush it into `finished` this shouldn't work since the `finished` queue's // capacity is 1. - let seq_action1 = SequenceAction { + let seq_action1 = Sequence { rollup_id: RollupId::new([1; ROLLUP_ID_LEN]), ..sequence_action_of_max_size(200) }; @@ -256,7 +256,7 @@ mod bundle_factory { // push another sequence action that is <100 bytes total to force the current bundle to // flush - let seq_action1 = SequenceAction { + let seq_action1 = Sequence { rollup_id: RollupId::new([1; ROLLUP_ID_LEN]), ..sequence_action_of_max_size(200) }; @@ -290,7 +290,7 @@ mod bundle_factory { let seq_action0 = sequence_action_of_max_size(200); bundle_factory.try_push(seq_action0.clone()).unwrap(); - let seq_action1 = SequenceAction { + let seq_action1 = Sequence { rollup_id: RollupId::new([1; ROLLUP_ID_LEN]), ..sequence_action_of_max_size(200) }; diff --git a/crates/astria-composer/src/executor/mod.rs b/crates/astria-composer/src/executor/mod.rs index 26260cbfaa..f1512d43b7 100644 --- a/crates/astria-composer/src/executor/mod.rs +++ b/crates/astria-composer/src/executor/mod.rs @@ -15,7 +15,7 @@ use astria_core::{ protocol::{ abci::AbciErrorCode, transaction::v1alpha1::{ - action::SequenceAction, + action::Sequence, SignedTransaction, }, }, @@ -120,7 +120,7 @@ pub(super) struct Executor { // The status of this executor status: watch::Sender, // Channel for receiving `SequenceAction`s to be bundled. - serialized_rollup_transactions: mpsc::Receiver, + serialized_rollup_transactions: mpsc::Receiver, // The client for submitting wrapped and signed pending eth transactions to the astria // sequencer. sequencer_client: sequencer_client::HttpClient, @@ -143,11 +143,11 @@ pub(super) struct Executor { #[derive(Clone)] pub(super) struct Handle { - serialized_rollup_transactions_tx: mpsc::Sender, + serialized_rollup_transactions_tx: mpsc::Sender, } impl Handle { - fn new(serialized_rollup_transactions_tx: mpsc::Sender) -> Self { + fn new(serialized_rollup_transactions_tx: mpsc::Sender) -> Self { Self { serialized_rollup_transactions_tx, } @@ -156,9 +156,9 @@ impl Handle { #[instrument(skip_all, err)] pub(super) async fn send_timeout( &self, - sequence_action: SequenceAction, + sequence_action: Sequence, timeout: Duration, - ) -> Result<(), SendTimeoutError> { + ) -> Result<(), SendTimeoutError> { self.serialized_rollup_transactions_tx .send_timeout(sequence_action, timeout) .await @@ -446,7 +446,7 @@ impl Executor { /// Pushes sequence action into current bundle, warning and dropping on failure. #[instrument(skip_all)] - fn bundle_seq_action(&self, seq_action: SequenceAction, bundle_factory: &mut BundleFactory) { + fn bundle_seq_action(&self, seq_action: Sequence, bundle_factory: &mut BundleFactory) { let rollup_id = seq_action.rollup_id; if let Err(e) = bundle_factory.try_push(seq_action) { diff --git a/crates/astria-composer/src/executor/tests.rs b/crates/astria-composer/src/executor/tests.rs index bf0f8d9ee9..5abb7c6ff7 100644 --- a/crates/astria-composer/src/executor/tests.rs +++ b/crates/astria-composer/src/executor/tests.rs @@ -18,7 +18,7 @@ use astria_core::{ RollupId, ROLLUP_ID_LEN, }, - protocol::transaction::v1alpha1::action::SequenceAction, + protocol::transaction::v1alpha1::action::Sequence, }; use astria_eyre::eyre; use prost::{ @@ -111,8 +111,8 @@ static TELEMETRY: LazyLock<()> = LazyLock::new(|| { } }); -fn sequence_action() -> SequenceAction { - SequenceAction { +fn sequence_action() -> Sequence { + Sequence { rollup_id: RollupId::new([0; ROLLUP_ID_LEN]), data: Bytes::new(), fee_asset: "nria".parse().unwrap(), @@ -354,7 +354,7 @@ async fn full_bundle() { // order to make space for the second let seq0 = sequence_action_of_max_size(cfg.max_bytes_per_bundle); - let seq1 = SequenceAction { + let seq1 = Sequence { rollup_id: RollupId::new([1; ROLLUP_ID_LEN]), ..sequence_action_of_max_size(cfg.max_bytes_per_bundle) }; @@ -443,7 +443,7 @@ async fn bundle_triggered_by_block_timer() { // send two sequence actions to the executor, both small enough to fit in a single bundle // without filling it - let seq0 = SequenceAction { + let seq0 = Sequence { data: vec![0u8; cfg.max_bytes_per_bundle / 4].into(), ..sequence_action() }; @@ -530,12 +530,12 @@ async fn two_seq_actions_single_bundle() { // send two sequence actions to the executor, both small enough to fit in a single bundle // without filling it - let seq0 = SequenceAction { + let seq0 = Sequence { data: vec![0u8; cfg.max_bytes_per_bundle / 4].into(), ..sequence_action() }; - let seq1 = SequenceAction { + let seq1 = Sequence { rollup_id: RollupId::new([1; ROLLUP_ID_LEN]), data: vec![1u8; cfg.max_bytes_per_bundle / 4].into(), ..sequence_action() diff --git a/crates/astria-composer/src/test_utils.rs b/crates/astria-composer/src/test_utils.rs index 0759b81666..54b9a551dc 100644 --- a/crates/astria-composer/src/test_utils.rs +++ b/crates/astria-composer/src/test_utils.rs @@ -4,17 +4,17 @@ use astria_core::{ RollupId, ROLLUP_ID_LEN, }, - protocol::transaction::v1alpha1::action::SequenceAction, + protocol::transaction::v1alpha1::action::Sequence, Protobuf as _, }; -fn encoded_len(action: &SequenceAction) -> usize { +fn encoded_len(action: &Sequence) -> usize { use prost::Message as _; action.to_raw().encoded_len() } -pub(crate) fn sequence_action_with_n_bytes(n: usize) -> SequenceAction { - SequenceAction { +pub(crate) fn sequence_action_with_n_bytes(n: usize) -> Sequence { + Sequence { rollup_id: RollupId::new([0; ROLLUP_ID_LEN]), data: vec![0; n].into(), fee_asset: "nria" @@ -25,11 +25,11 @@ pub(crate) fn sequence_action_with_n_bytes(n: usize) -> SequenceAction { } } -pub(crate) fn empty_sequence_action() -> SequenceAction { +pub(crate) fn empty_sequence_action() -> Sequence { sequence_action_with_n_bytes(0) } -pub(crate) fn sequence_action_of_max_size(max: usize) -> SequenceAction { +pub(crate) fn sequence_action_of_max_size(max: usize) -> Sequence { // an action where the data part is exactly max bytes long let big_action = sequence_action_with_n_bytes(max); // the number of bytes past max diff --git a/crates/astria-core/src/generated/astria.protocol.transaction.v1alpha1.rs b/crates/astria-core/src/generated/astria.protocol.transaction.v1alpha1.rs new file mode 100644 index 0000000000..7ffa6cdf51 --- /dev/null +++ b/crates/astria-core/src/generated/astria.protocol.transaction.v1alpha1.rs @@ -0,0 +1,539 @@ +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Action { + #[prost( + oneof = "action::Value", + tags = "1, 2, 11, 12, 13, 14, 21, 22, 50, 51, 52, 53, 55, 56" + )] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Action`. +pub mod action { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + /// Core protocol actions are defined on 1-10 + #[prost(message, tag = "1")] + Transfer(super::Transfer), + #[prost(message, tag = "2")] + Sequence(super::Sequence), + /// Bridge actions are defined on 11-20 + #[prost(message, tag = "11")] + InitBridgeAccount(super::InitBridgeAccount), + #[prost(message, tag = "12")] + BridgeLock(super::BridgeLock), + #[prost(message, tag = "13")] + BridgeUnlock(super::BridgeUnlock), + #[prost(message, tag = "14")] + BridgeSudoChange(super::BridgeSudoChange), + /// IBC user actions are defined on 21-30 + #[prost(message, tag = "21")] + Ibc(::penumbra_proto::core::component::ibc::v1::IbcRelay), + #[prost(message, tag = "22")] + Ics20Withdrawal(super::Ics20Withdrawal), + /// POA sudo actions are defined on 50-60 + #[prost(message, tag = "50")] + SudoAddressChange(super::SudoAddressChange), + #[prost(message, tag = "51")] + ValidatorUpdate( + crate::generated::astria_vendored::tendermint::abci::ValidatorUpdate, + ), + #[prost(message, tag = "52")] + IbcRelayerChange(super::IbcRelayerChange), + #[prost(message, tag = "53")] + FeeAssetChange(super::FeeAssetChange), + #[prost(message, tag = "55")] + FeeChange(super::FeeChange), + #[prost(message, tag = "56")] + IbcSudoChange(super::IbcSudoChange), + } +} +impl ::prost::Name for Action { + const NAME: &'static str = "Action"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `TransferAction` represents a value transfer transaction. +/// +/// Note: all values must be set (ie. not `None`), otherwise it will +/// be considered invalid by the sequencer. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Transfer { + #[prost(message, optional, tag = "1")] + pub to: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub amount: ::core::option::Option, + /// the asset to be transferred + #[prost(string, tag = "3")] + pub asset: ::prost::alloc::string::String, + /// the asset used to pay the transaction fee + #[prost(string, tag = "4")] + pub fee_asset: ::prost::alloc::string::String, +} +impl ::prost::Name for Transfer { + const NAME: &'static str = "Transfer"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `Sequence` represents a transaction destined for another +/// chain, ordered by the sequencer. +/// +/// It contains the rollup ID of the destination chain, and the +/// opaque transaction data. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Sequence { + #[prost(message, optional, tag = "1")] + pub rollup_id: ::core::option::Option, + #[prost(bytes = "bytes", tag = "2")] + pub data: ::prost::bytes::Bytes, + /// the asset used to pay the transaction fee + #[prost(string, tag = "3")] + pub fee_asset: ::prost::alloc::string::String, +} +impl ::prost::Name for Sequence { + const NAME: &'static str = "Sequence"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// / `SudoAddressChange` represents a transaction that changes +/// / the sudo address of the chain, which is the address authorized to +/// / make validator update actions. +/// / +/// / It contains the new sudo address. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SudoAddressChange { + #[prost(message, optional, tag = "1")] + pub new_address: ::core::option::Option, +} +impl ::prost::Name for SudoAddressChange { + const NAME: &'static str = "SudoAddressChange"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Ics20Withdrawal { + /// first two fields are a transparent value consisting of an amount and a denom. + #[prost(message, optional, tag = "1")] + pub amount: ::core::option::Option, + #[prost(string, tag = "2")] + pub denom: ::prost::alloc::string::String, + /// the address on the destination chain to send the transfer to. + /// this is not validated by Astria; it is up to the destination chain + /// to interpret it. + #[prost(string, tag = "3")] + pub destination_chain_address: ::prost::alloc::string::String, + /// an Astria address to use to return funds from this withdrawal + /// in the case it fails. + #[prost(message, optional, tag = "4")] + pub return_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, + /// the height (on Astria) at which this transfer expires. + #[prost(message, optional, tag = "5")] + pub timeout_height: ::core::option::Option, + /// the unix timestamp (in nanoseconds) at which this transfer expires. + #[prost(uint64, tag = "6")] + pub timeout_time: u64, + /// the source channel used for the withdrawal. + #[prost(string, tag = "7")] + pub source_channel: ::prost::alloc::string::String, + /// the asset used to pay the transaction fee + #[prost(string, tag = "8")] + pub fee_asset: ::prost::alloc::string::String, + /// a memo to include with the transfer + #[prost(string, tag = "9")] + pub memo: ::prost::alloc::string::String, + /// the address of the bridge account to transfer from, if this is a withdrawal + /// from a bridge account and the sender of the tx is the bridge's withdrawer, + /// which differs from the bridge account's address. + /// + /// if unset, and the transaction sender is not a bridge account, the withdrawal + /// is treated as a user (non-bridge) withdrawal. + /// + /// if unset, and the transaction sender is a bridge account, the withdrawal is + /// treated as a bridge withdrawal (ie. the bridge account's withdrawer address is checked). + #[prost(message, optional, tag = "10")] + pub bridge_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, + /// whether to use a bech32-compatible format of the `.return_address` when generating + /// fungible token packets (as opposed to Astria-native bech32m addresses). This is + /// necessary for chains like noble which enforce a strict bech32 format. + #[prost(bool, tag = "11")] + pub use_compat_address: bool, +} +impl ::prost::Name for Ics20Withdrawal { + const NAME: &'static str = "Ics20Withdrawal"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IbcHeight { + #[prost(uint64, tag = "1")] + pub revision_number: u64, + #[prost(uint64, tag = "2")] + pub revision_height: u64, +} +impl ::prost::Name for IbcHeight { + const NAME: &'static str = "IbcHeight"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `IbcRelayerChange` represents a transaction that adds +/// or removes an IBC relayer address. +/// The bytes contained in each variant are the address to add or remove. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IbcRelayerChange { + #[prost(oneof = "ibc_relayer_change::Value", tags = "1, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `IbcRelayerChange`. +pub mod ibc_relayer_change { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag = "1")] + Addition(super::super::super::super::primitive::v1::Address), + #[prost(message, tag = "2")] + Removal(super::super::super::super::primitive::v1::Address), + } +} +impl ::prost::Name for IbcRelayerChange { + const NAME: &'static str = "IbcRelayerChange"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `FeeAssetChange` represents a transaction that adds +/// or removes an asset for fee payments. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FeeAssetChange { + #[prost(oneof = "fee_asset_change::Value", tags = "1, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `FeeAssetChange`. +pub mod fee_asset_change { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(string, tag = "1")] + Addition(::prost::alloc::string::String), + #[prost(string, tag = "2")] + Removal(::prost::alloc::string::String), + } +} +impl ::prost::Name for FeeAssetChange { + const NAME: &'static str = "FeeAssetChange"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `InitBridgeAccount` represents a transaction that initializes +/// a bridge account for the given rollup on the chain. +/// +/// The sender of the transaction is used as the owner of the bridge account +/// and is the only actor authorized to transfer out of this account via +/// a `Transfer`. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InitBridgeAccount { + /// the rollup ID to register with the bridge account (the tx sender) + #[prost(message, optional, tag = "1")] + pub rollup_id: ::core::option::Option, + /// the asset ID accepted as an incoming transfer by the bridge account + #[prost(string, tag = "2")] + pub asset: ::prost::alloc::string::String, + /// the asset used to pay the transaction fee + #[prost(string, tag = "3")] + pub fee_asset: ::prost::alloc::string::String, + /// the address corresponding to the key which has sudo capabilities; + /// ie. can change the sudo and withdrawer addresses for this bridge account. + /// if this is empty, the sender of the transaction is used. + #[prost(message, optional, tag = "4")] + pub sudo_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, + /// the address corresponding to the key which can withdraw funds from this bridge account. + /// if this is empty, the sender of the transaction is used. + #[prost(message, optional, tag = "5")] + pub withdrawer_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, +} +impl ::prost::Name for InitBridgeAccount { + const NAME: &'static str = "InitBridgeAccount"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `BridgeLock` represents a transaction that transfers +/// funds from a sequencer account to a bridge account. +/// +/// It's the same as a `Transfer` but with the added +/// `destination_chain_address` field. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BridgeLock { + /// the address of the bridge account to transfer to + #[prost(message, optional, tag = "1")] + pub to: ::core::option::Option, + /// the amount to transfer + #[prost(message, optional, tag = "2")] + pub amount: ::core::option::Option, + /// the asset to be transferred + #[prost(string, tag = "3")] + pub asset: ::prost::alloc::string::String, + /// the asset used to pay the transaction fee + #[prost(string, tag = "4")] + pub fee_asset: ::prost::alloc::string::String, + /// the address on the destination chain which + /// will receive the bridged funds + #[prost(string, tag = "5")] + pub destination_chain_address: ::prost::alloc::string::String, +} +impl ::prost::Name for BridgeLock { + const NAME: &'static str = "BridgeLock"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `BridgeUnlock` represents a transaction that transfers +/// funds from a bridge account to a sequencer account. +/// +/// It's the same as a `Transfer` but without the `asset` field +/// and with the `memo` field. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BridgeUnlock { + /// the to withdraw funds to + #[prost(message, optional, tag = "1")] + pub to: ::core::option::Option, + /// the amount to transfer + #[prost(message, optional, tag = "2")] + pub amount: ::core::option::Option, + /// the asset used to pay the transaction fee + #[prost(string, tag = "3")] + pub fee_asset: ::prost::alloc::string::String, + /// The memo field can be used to provide unique identifying additional + /// information about the bridge unlock transaction. + #[prost(string, tag = "4")] + pub memo: ::prost::alloc::string::String, + /// the address of the bridge account to transfer from + #[prost(message, optional, tag = "5")] + pub bridge_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, + /// The block number on the rollup that triggered the transaction underlying + /// this bridge unlock memo. + #[prost(uint64, tag = "6")] + pub rollup_block_number: u64, + /// An identifier of the original rollup event, such as a transaction hash which + /// triggered a bridge unlock and is underlying event that led to this bridge + /// unlock. This can be utilized for tracing from the bridge back to + /// distinct rollup events. + /// + /// This field is of type `string` so that it can be formatted in the preferred + /// format of the rollup when targeting plain text encoding. + #[prost(string, tag = "7")] + pub rollup_withdrawal_event_id: ::prost::alloc::string::String, +} +impl ::prost::Name for BridgeUnlock { + const NAME: &'static str = "BridgeUnlock"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BridgeSudoChange { + /// the address of the bridge account to change the sudo or withdrawer addresses for + #[prost(message, optional, tag = "1")] + pub bridge_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, + /// the new sudo address; unchanged if unset + #[prost(message, optional, tag = "2")] + pub new_sudo_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, + /// the new withdrawer address; unchanged if unset + #[prost(message, optional, tag = "3")] + pub new_withdrawer_address: ::core::option::Option< + super::super::super::primitive::v1::Address, + >, + /// the asset used to pay the transaction fee + #[prost(string, tag = "4")] + pub fee_asset: ::prost::alloc::string::String, +} +impl ::prost::Name for BridgeSudoChange { + const NAME: &'static str = "BridgeSudoChange"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FeeChange { + /// note that the proto number ranges are doubled from that of `Action`. + /// this to accomodate both `base_fee` and `byte_cost_multiplier` for each action. + #[prost(oneof = "fee_change::Value", tags = "1, 2, 3, 20, 21, 22, 40")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `FeeChange`. +pub mod fee_change { + /// note that the proto number ranges are doubled from that of `Action`. + /// this to accomodate both `base_fee` and `byte_cost_multiplier` for each action. + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + /// core protocol fees are defined on 1-20 + #[prost(message, tag = "1")] + TransferBaseFee(super::super::super::super::primitive::v1::Uint128), + #[prost(message, tag = "2")] + SequenceBaseFee(super::super::super::super::primitive::v1::Uint128), + #[prost(message, tag = "3")] + SequenceByteCostMultiplier(super::super::super::super::primitive::v1::Uint128), + /// bridge fees are defined on 20-39 + #[prost(message, tag = "20")] + InitBridgeAccountBaseFee(super::super::super::super::primitive::v1::Uint128), + #[prost(message, tag = "21")] + BridgeLockByteCostMultiplier(super::super::super::super::primitive::v1::Uint128), + #[prost(message, tag = "22")] + BridgeSudoChangeBaseFee(super::super::super::super::primitive::v1::Uint128), + /// ibc fees are defined on 40-59 + #[prost(message, tag = "40")] + Ics20WithdrawalBaseFee(super::super::super::super::primitive::v1::Uint128), + } +} +impl ::prost::Name for FeeChange { + const NAME: &'static str = "FeeChange"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IbcSudoChange { + #[prost(message, optional, tag = "1")] + pub new_address: ::core::option::Option, +} +impl ::prost::Name for IbcSudoChange { + const NAME: &'static str = "IbcSudoChange"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// Response to a transaction fee ABCI query. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransactionFeeResponse { + #[prost(uint64, tag = "2")] + pub height: u64, + #[prost(message, repeated, tag = "3")] + pub fees: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for TransactionFeeResponse { + const NAME: &'static str = "TransactionFeeResponse"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransactionFee { + #[prost(string, tag = "1")] + pub asset: ::prost::alloc::string::String, + #[prost(message, optional, tag = "2")] + pub fee: ::core::option::Option, +} +impl ::prost::Name for TransactionFee { + const NAME: &'static str = "TransactionFee"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `SignedTransaction` is a transaction that has +/// been signed by the given public key. +/// It wraps an `UnsignedTransaction` with a +/// signature and public key. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignedTransaction { + #[prost(bytes = "bytes", tag = "1")] + pub signature: ::prost::bytes::Bytes, + #[prost(bytes = "bytes", tag = "2")] + pub public_key: ::prost::bytes::Bytes, + #[prost(message, optional, tag = "3")] + pub transaction: ::core::option::Option<::pbjson_types::Any>, +} +impl ::prost::Name for SignedTransaction { + const NAME: &'static str = "SignedTransaction"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `UnsignedTransaction` is a transaction that does +/// not have an attached signature. +/// Note: `value` must be set, it cannot be `None`. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnsignedTransaction { + #[prost(message, repeated, tag = "1")] + pub actions: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub params: ::core::option::Option, +} +impl ::prost::Name for UnsignedTransaction { + const NAME: &'static str = "UnsignedTransaction"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} +/// `TransactionParams` contains parameters that define the +/// validity of the transaction. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransactionParams { + #[prost(uint32, tag = "1")] + pub nonce: u32, + #[prost(string, tag = "2")] + pub chain_id: ::prost::alloc::string::String, +} +impl ::prost::Name for TransactionParams { + const NAME: &'static str = "TransactionParams"; + const PACKAGE: &'static str = "astria.protocol.transaction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transaction.v1alpha1.{}", Self::NAME) + } +} diff --git a/crates/astria-core/src/generated/astria.protocol.transaction.v1alpha1.serde.rs b/crates/astria-core/src/generated/astria.protocol.transaction.v1alpha1.serde.rs new file mode 100644 index 0000000000..7665816927 --- /dev/null +++ b/crates/astria-core/src/generated/astria.protocol.transaction.v1alpha1.serde.rs @@ -0,0 +1,2758 @@ +impl serde::Serialize for Action { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.value.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.Action", len)?; + if let Some(v) = self.value.as_ref() { + match v { + action::Value::Transfer(v) => { + struct_ser.serialize_field("transfer", v)?; + } + action::Value::Sequence(v) => { + struct_ser.serialize_field("sequence", v)?; + } + action::Value::InitBridgeAccount(v) => { + struct_ser.serialize_field("initBridgeAccount", v)?; + } + action::Value::BridgeLock(v) => { + struct_ser.serialize_field("bridgeLock", v)?; + } + action::Value::BridgeUnlock(v) => { + struct_ser.serialize_field("bridgeUnlock", v)?; + } + action::Value::BridgeSudoChange(v) => { + struct_ser.serialize_field("bridgeSudoChange", v)?; + } + action::Value::Ibc(v) => { + struct_ser.serialize_field("ibc", v)?; + } + action::Value::Ics20Withdrawal(v) => { + struct_ser.serialize_field("ics20Withdrawal", v)?; + } + action::Value::SudoAddressChange(v) => { + struct_ser.serialize_field("sudoAddressChange", v)?; + } + action::Value::ValidatorUpdate(v) => { + struct_ser.serialize_field("validatorUpdate", v)?; + } + action::Value::IbcRelayerChange(v) => { + struct_ser.serialize_field("ibcRelayerChange", v)?; + } + action::Value::FeeAssetChange(v) => { + struct_ser.serialize_field("feeAssetChange", v)?; + } + action::Value::FeeChange(v) => { + struct_ser.serialize_field("feeChange", v)?; + } + action::Value::IbcSudoChange(v) => { + struct_ser.serialize_field("ibcSudoChange", v)?; + } + } + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for Action { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "transfer", + "sequence", + "init_bridge_account", + "initBridgeAccount", + "bridge_lock", + "bridgeLock", + "bridge_unlock", + "bridgeUnlock", + "bridge_sudo_change", + "bridgeSudoChange", + "ibc", + "ics20_withdrawal", + "ics20Withdrawal", + "sudo_address_change", + "sudoAddressChange", + "validator_update", + "validatorUpdate", + "ibc_relayer_change", + "ibcRelayerChange", + "fee_asset_change", + "feeAssetChange", + "fee_change", + "feeChange", + "ibc_sudo_change", + "ibcSudoChange", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Transfer, + Sequence, + InitBridgeAccount, + BridgeLock, + BridgeUnlock, + BridgeSudoChange, + Ibc, + Ics20Withdrawal, + SudoAddressChange, + ValidatorUpdate, + IbcRelayerChange, + FeeAssetChange, + FeeChange, + IbcSudoChange, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "transfer" => Ok(GeneratedField::Transfer), + "sequence" => Ok(GeneratedField::Sequence), + "initBridgeAccount" | "init_bridge_account" => Ok(GeneratedField::InitBridgeAccount), + "bridgeLock" | "bridge_lock" => Ok(GeneratedField::BridgeLock), + "bridgeUnlock" | "bridge_unlock" => Ok(GeneratedField::BridgeUnlock), + "bridgeSudoChange" | "bridge_sudo_change" => Ok(GeneratedField::BridgeSudoChange), + "ibc" => Ok(GeneratedField::Ibc), + "ics20Withdrawal" | "ics20_withdrawal" => Ok(GeneratedField::Ics20Withdrawal), + "sudoAddressChange" | "sudo_address_change" => Ok(GeneratedField::SudoAddressChange), + "validatorUpdate" | "validator_update" => Ok(GeneratedField::ValidatorUpdate), + "ibcRelayerChange" | "ibc_relayer_change" => Ok(GeneratedField::IbcRelayerChange), + "feeAssetChange" | "fee_asset_change" => Ok(GeneratedField::FeeAssetChange), + "feeChange" | "fee_change" => Ok(GeneratedField::FeeChange), + "ibcSudoChange" | "ibc_sudo_change" => Ok(GeneratedField::IbcSudoChange), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = Action; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.Action") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut value__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Transfer => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("transfer")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Transfer) +; + } + GeneratedField::Sequence => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("sequence")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Sequence) +; + } + GeneratedField::InitBridgeAccount => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("initBridgeAccount")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::InitBridgeAccount) +; + } + GeneratedField::BridgeLock => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeLock")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeLock) +; + } + GeneratedField::BridgeUnlock => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeUnlock")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeUnlock) +; + } + GeneratedField::BridgeSudoChange => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeSudoChange")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeSudoChange) +; + } + GeneratedField::Ibc => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("ibc")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Ibc) +; + } + GeneratedField::Ics20Withdrawal => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("ics20Withdrawal")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Ics20Withdrawal) +; + } + GeneratedField::SudoAddressChange => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("sudoAddressChange")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::SudoAddressChange) +; + } + GeneratedField::ValidatorUpdate => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("validatorUpdate")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::ValidatorUpdate) +; + } + GeneratedField::IbcRelayerChange => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("ibcRelayerChange")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::IbcRelayerChange) +; + } + GeneratedField::FeeAssetChange => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAssetChange")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::FeeAssetChange) +; + } + GeneratedField::FeeChange => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("feeChange")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::FeeChange) +; + } + GeneratedField::IbcSudoChange => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("ibcSudoChange")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::IbcSudoChange) +; + } + } + } + Ok(Action { + value: value__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.Action", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for BridgeLock { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.to.is_some() { + len += 1; + } + if self.amount.is_some() { + len += 1; + } + if !self.asset.is_empty() { + len += 1; + } + if !self.fee_asset.is_empty() { + len += 1; + } + if !self.destination_chain_address.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.BridgeLock", len)?; + if let Some(v) = self.to.as_ref() { + struct_ser.serialize_field("to", v)?; + } + if let Some(v) = self.amount.as_ref() { + struct_ser.serialize_field("amount", v)?; + } + if !self.asset.is_empty() { + struct_ser.serialize_field("asset", &self.asset)?; + } + if !self.fee_asset.is_empty() { + struct_ser.serialize_field("feeAsset", &self.fee_asset)?; + } + if !self.destination_chain_address.is_empty() { + struct_ser.serialize_field("destinationChainAddress", &self.destination_chain_address)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for BridgeLock { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "to", + "amount", + "asset", + "fee_asset", + "feeAsset", + "destination_chain_address", + "destinationChainAddress", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + To, + Amount, + Asset, + FeeAsset, + DestinationChainAddress, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "to" => Ok(GeneratedField::To), + "amount" => Ok(GeneratedField::Amount), + "asset" => Ok(GeneratedField::Asset), + "feeAsset" | "fee_asset" => Ok(GeneratedField::FeeAsset), + "destinationChainAddress" | "destination_chain_address" => Ok(GeneratedField::DestinationChainAddress), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = BridgeLock; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.BridgeLock") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut to__ = None; + let mut amount__ = None; + let mut asset__ = None; + let mut fee_asset__ = None; + let mut destination_chain_address__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::To => { + if to__.is_some() { + return Err(serde::de::Error::duplicate_field("to")); + } + to__ = map_.next_value()?; + } + GeneratedField::Amount => { + if amount__.is_some() { + return Err(serde::de::Error::duplicate_field("amount")); + } + amount__ = map_.next_value()?; + } + GeneratedField::Asset => { + if asset__.is_some() { + return Err(serde::de::Error::duplicate_field("asset")); + } + asset__ = Some(map_.next_value()?); + } + GeneratedField::FeeAsset => { + if fee_asset__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAsset")); + } + fee_asset__ = Some(map_.next_value()?); + } + GeneratedField::DestinationChainAddress => { + if destination_chain_address__.is_some() { + return Err(serde::de::Error::duplicate_field("destinationChainAddress")); + } + destination_chain_address__ = Some(map_.next_value()?); + } + } + } + Ok(BridgeLock { + to: to__, + amount: amount__, + asset: asset__.unwrap_or_default(), + fee_asset: fee_asset__.unwrap_or_default(), + destination_chain_address: destination_chain_address__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.BridgeLock", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for BridgeSudoChange { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.bridge_address.is_some() { + len += 1; + } + if self.new_sudo_address.is_some() { + len += 1; + } + if self.new_withdrawer_address.is_some() { + len += 1; + } + if !self.fee_asset.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.BridgeSudoChange", len)?; + if let Some(v) = self.bridge_address.as_ref() { + struct_ser.serialize_field("bridgeAddress", v)?; + } + if let Some(v) = self.new_sudo_address.as_ref() { + struct_ser.serialize_field("newSudoAddress", v)?; + } + if let Some(v) = self.new_withdrawer_address.as_ref() { + struct_ser.serialize_field("newWithdrawerAddress", v)?; + } + if !self.fee_asset.is_empty() { + struct_ser.serialize_field("feeAsset", &self.fee_asset)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for BridgeSudoChange { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "bridge_address", + "bridgeAddress", + "new_sudo_address", + "newSudoAddress", + "new_withdrawer_address", + "newWithdrawerAddress", + "fee_asset", + "feeAsset", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + BridgeAddress, + NewSudoAddress, + NewWithdrawerAddress, + FeeAsset, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "bridgeAddress" | "bridge_address" => Ok(GeneratedField::BridgeAddress), + "newSudoAddress" | "new_sudo_address" => Ok(GeneratedField::NewSudoAddress), + "newWithdrawerAddress" | "new_withdrawer_address" => Ok(GeneratedField::NewWithdrawerAddress), + "feeAsset" | "fee_asset" => Ok(GeneratedField::FeeAsset), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = BridgeSudoChange; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.BridgeSudoChange") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut bridge_address__ = None; + let mut new_sudo_address__ = None; + let mut new_withdrawer_address__ = None; + let mut fee_asset__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::BridgeAddress => { + if bridge_address__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeAddress")); + } + bridge_address__ = map_.next_value()?; + } + GeneratedField::NewSudoAddress => { + if new_sudo_address__.is_some() { + return Err(serde::de::Error::duplicate_field("newSudoAddress")); + } + new_sudo_address__ = map_.next_value()?; + } + GeneratedField::NewWithdrawerAddress => { + if new_withdrawer_address__.is_some() { + return Err(serde::de::Error::duplicate_field("newWithdrawerAddress")); + } + new_withdrawer_address__ = map_.next_value()?; + } + GeneratedField::FeeAsset => { + if fee_asset__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAsset")); + } + fee_asset__ = Some(map_.next_value()?); + } + } + } + Ok(BridgeSudoChange { + bridge_address: bridge_address__, + new_sudo_address: new_sudo_address__, + new_withdrawer_address: new_withdrawer_address__, + fee_asset: fee_asset__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.BridgeSudoChange", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for BridgeUnlock { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.to.is_some() { + len += 1; + } + if self.amount.is_some() { + len += 1; + } + if !self.fee_asset.is_empty() { + len += 1; + } + if !self.memo.is_empty() { + len += 1; + } + if self.bridge_address.is_some() { + len += 1; + } + if self.rollup_block_number != 0 { + len += 1; + } + if !self.rollup_withdrawal_event_id.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.BridgeUnlock", len)?; + if let Some(v) = self.to.as_ref() { + struct_ser.serialize_field("to", v)?; + } + if let Some(v) = self.amount.as_ref() { + struct_ser.serialize_field("amount", v)?; + } + if !self.fee_asset.is_empty() { + struct_ser.serialize_field("feeAsset", &self.fee_asset)?; + } + if !self.memo.is_empty() { + struct_ser.serialize_field("memo", &self.memo)?; + } + if let Some(v) = self.bridge_address.as_ref() { + struct_ser.serialize_field("bridgeAddress", v)?; + } + if self.rollup_block_number != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("rollupBlockNumber", ToString::to_string(&self.rollup_block_number).as_str())?; + } + if !self.rollup_withdrawal_event_id.is_empty() { + struct_ser.serialize_field("rollupWithdrawalEventId", &self.rollup_withdrawal_event_id)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for BridgeUnlock { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "to", + "amount", + "fee_asset", + "feeAsset", + "memo", + "bridge_address", + "bridgeAddress", + "rollup_block_number", + "rollupBlockNumber", + "rollup_withdrawal_event_id", + "rollupWithdrawalEventId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + To, + Amount, + FeeAsset, + Memo, + BridgeAddress, + RollupBlockNumber, + RollupWithdrawalEventId, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "to" => Ok(GeneratedField::To), + "amount" => Ok(GeneratedField::Amount), + "feeAsset" | "fee_asset" => Ok(GeneratedField::FeeAsset), + "memo" => Ok(GeneratedField::Memo), + "bridgeAddress" | "bridge_address" => Ok(GeneratedField::BridgeAddress), + "rollupBlockNumber" | "rollup_block_number" => Ok(GeneratedField::RollupBlockNumber), + "rollupWithdrawalEventId" | "rollup_withdrawal_event_id" => Ok(GeneratedField::RollupWithdrawalEventId), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = BridgeUnlock; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.BridgeUnlock") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut to__ = None; + let mut amount__ = None; + let mut fee_asset__ = None; + let mut memo__ = None; + let mut bridge_address__ = None; + let mut rollup_block_number__ = None; + let mut rollup_withdrawal_event_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::To => { + if to__.is_some() { + return Err(serde::de::Error::duplicate_field("to")); + } + to__ = map_.next_value()?; + } + GeneratedField::Amount => { + if amount__.is_some() { + return Err(serde::de::Error::duplicate_field("amount")); + } + amount__ = map_.next_value()?; + } + GeneratedField::FeeAsset => { + if fee_asset__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAsset")); + } + fee_asset__ = Some(map_.next_value()?); + } + GeneratedField::Memo => { + if memo__.is_some() { + return Err(serde::de::Error::duplicate_field("memo")); + } + memo__ = Some(map_.next_value()?); + } + GeneratedField::BridgeAddress => { + if bridge_address__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeAddress")); + } + bridge_address__ = map_.next_value()?; + } + GeneratedField::RollupBlockNumber => { + if rollup_block_number__.is_some() { + return Err(serde::de::Error::duplicate_field("rollupBlockNumber")); + } + rollup_block_number__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::RollupWithdrawalEventId => { + if rollup_withdrawal_event_id__.is_some() { + return Err(serde::de::Error::duplicate_field("rollupWithdrawalEventId")); + } + rollup_withdrawal_event_id__ = Some(map_.next_value()?); + } + } + } + Ok(BridgeUnlock { + to: to__, + amount: amount__, + fee_asset: fee_asset__.unwrap_or_default(), + memo: memo__.unwrap_or_default(), + bridge_address: bridge_address__, + rollup_block_number: rollup_block_number__.unwrap_or_default(), + rollup_withdrawal_event_id: rollup_withdrawal_event_id__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.BridgeUnlock", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for FeeAssetChange { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.value.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.FeeAssetChange", len)?; + if let Some(v) = self.value.as_ref() { + match v { + fee_asset_change::Value::Addition(v) => { + struct_ser.serialize_field("addition", v)?; + } + fee_asset_change::Value::Removal(v) => { + struct_ser.serialize_field("removal", v)?; + } + } + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for FeeAssetChange { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "addition", + "removal", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Addition, + Removal, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "addition" => Ok(GeneratedField::Addition), + "removal" => Ok(GeneratedField::Removal), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = FeeAssetChange; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.FeeAssetChange") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut value__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Addition => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("addition")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_asset_change::Value::Addition); + } + GeneratedField::Removal => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("removal")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_asset_change::Value::Removal); + } + } + } + Ok(FeeAssetChange { + value: value__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.FeeAssetChange", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for FeeChange { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.value.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.FeeChange", len)?; + if let Some(v) = self.value.as_ref() { + match v { + fee_change::Value::TransferBaseFee(v) => { + struct_ser.serialize_field("transferBaseFee", v)?; + } + fee_change::Value::SequenceBaseFee(v) => { + struct_ser.serialize_field("sequenceBaseFee", v)?; + } + fee_change::Value::SequenceByteCostMultiplier(v) => { + struct_ser.serialize_field("sequenceByteCostMultiplier", v)?; + } + fee_change::Value::InitBridgeAccountBaseFee(v) => { + struct_ser.serialize_field("initBridgeAccountBaseFee", v)?; + } + fee_change::Value::BridgeLockByteCostMultiplier(v) => { + struct_ser.serialize_field("bridgeLockByteCostMultiplier", v)?; + } + fee_change::Value::BridgeSudoChangeBaseFee(v) => { + struct_ser.serialize_field("bridgeSudoChangeBaseFee", v)?; + } + fee_change::Value::Ics20WithdrawalBaseFee(v) => { + struct_ser.serialize_field("ics20WithdrawalBaseFee", v)?; + } + } + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for FeeChange { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "transfer_base_fee", + "transferBaseFee", + "sequence_base_fee", + "sequenceBaseFee", + "sequence_byte_cost_multiplier", + "sequenceByteCostMultiplier", + "init_bridge_account_base_fee", + "initBridgeAccountBaseFee", + "bridge_lock_byte_cost_multiplier", + "bridgeLockByteCostMultiplier", + "bridge_sudo_change_base_fee", + "bridgeSudoChangeBaseFee", + "ics20_withdrawal_base_fee", + "ics20WithdrawalBaseFee", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + TransferBaseFee, + SequenceBaseFee, + SequenceByteCostMultiplier, + InitBridgeAccountBaseFee, + BridgeLockByteCostMultiplier, + BridgeSudoChangeBaseFee, + Ics20WithdrawalBaseFee, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "transferBaseFee" | "transfer_base_fee" => Ok(GeneratedField::TransferBaseFee), + "sequenceBaseFee" | "sequence_base_fee" => Ok(GeneratedField::SequenceBaseFee), + "sequenceByteCostMultiplier" | "sequence_byte_cost_multiplier" => Ok(GeneratedField::SequenceByteCostMultiplier), + "initBridgeAccountBaseFee" | "init_bridge_account_base_fee" => Ok(GeneratedField::InitBridgeAccountBaseFee), + "bridgeLockByteCostMultiplier" | "bridge_lock_byte_cost_multiplier" => Ok(GeneratedField::BridgeLockByteCostMultiplier), + "bridgeSudoChangeBaseFee" | "bridge_sudo_change_base_fee" => Ok(GeneratedField::BridgeSudoChangeBaseFee), + "ics20WithdrawalBaseFee" | "ics20_withdrawal_base_fee" => Ok(GeneratedField::Ics20WithdrawalBaseFee), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = FeeChange; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.FeeChange") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut value__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::TransferBaseFee => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("transferBaseFee")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::TransferBaseFee) +; + } + GeneratedField::SequenceBaseFee => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("sequenceBaseFee")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::SequenceBaseFee) +; + } + GeneratedField::SequenceByteCostMultiplier => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("sequenceByteCostMultiplier")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::SequenceByteCostMultiplier) +; + } + GeneratedField::InitBridgeAccountBaseFee => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("initBridgeAccountBaseFee")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::InitBridgeAccountBaseFee) +; + } + GeneratedField::BridgeLockByteCostMultiplier => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeLockByteCostMultiplier")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::BridgeLockByteCostMultiplier) +; + } + GeneratedField::BridgeSudoChangeBaseFee => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeSudoChangeBaseFee")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::BridgeSudoChangeBaseFee) +; + } + GeneratedField::Ics20WithdrawalBaseFee => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("ics20WithdrawalBaseFee")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::Ics20WithdrawalBaseFee) +; + } + } + } + Ok(FeeChange { + value: value__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.FeeChange", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for IbcHeight { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.revision_number != 0 { + len += 1; + } + if self.revision_height != 0 { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.IbcHeight", len)?; + if self.revision_number != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("revisionNumber", ToString::to_string(&self.revision_number).as_str())?; + } + if self.revision_height != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("revisionHeight", ToString::to_string(&self.revision_height).as_str())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for IbcHeight { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "revision_number", + "revisionNumber", + "revision_height", + "revisionHeight", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + RevisionNumber, + RevisionHeight, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "revisionNumber" | "revision_number" => Ok(GeneratedField::RevisionNumber), + "revisionHeight" | "revision_height" => Ok(GeneratedField::RevisionHeight), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = IbcHeight; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.IbcHeight") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut revision_number__ = None; + let mut revision_height__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::RevisionNumber => { + if revision_number__.is_some() { + return Err(serde::de::Error::duplicate_field("revisionNumber")); + } + revision_number__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::RevisionHeight => { + if revision_height__.is_some() { + return Err(serde::de::Error::duplicate_field("revisionHeight")); + } + revision_height__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + } + } + Ok(IbcHeight { + revision_number: revision_number__.unwrap_or_default(), + revision_height: revision_height__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.IbcHeight", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for IbcRelayerChange { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.value.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.IbcRelayerChange", len)?; + if let Some(v) = self.value.as_ref() { + match v { + ibc_relayer_change::Value::Addition(v) => { + struct_ser.serialize_field("addition", v)?; + } + ibc_relayer_change::Value::Removal(v) => { + struct_ser.serialize_field("removal", v)?; + } + } + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for IbcRelayerChange { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "addition", + "removal", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Addition, + Removal, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "addition" => Ok(GeneratedField::Addition), + "removal" => Ok(GeneratedField::Removal), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = IbcRelayerChange; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.IbcRelayerChange") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut value__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Addition => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("addition")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(ibc_relayer_change::Value::Addition) +; + } + GeneratedField::Removal => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("removal")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(ibc_relayer_change::Value::Removal) +; + } + } + } + Ok(IbcRelayerChange { + value: value__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.IbcRelayerChange", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for IbcSudoChange { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.new_address.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.IbcSudoChange", len)?; + if let Some(v) = self.new_address.as_ref() { + struct_ser.serialize_field("newAddress", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for IbcSudoChange { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "new_address", + "newAddress", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + NewAddress, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "newAddress" | "new_address" => Ok(GeneratedField::NewAddress), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = IbcSudoChange; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.IbcSudoChange") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut new_address__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::NewAddress => { + if new_address__.is_some() { + return Err(serde::de::Error::duplicate_field("newAddress")); + } + new_address__ = map_.next_value()?; + } + } + } + Ok(IbcSudoChange { + new_address: new_address__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.IbcSudoChange", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for Ics20Withdrawal { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.amount.is_some() { + len += 1; + } + if !self.denom.is_empty() { + len += 1; + } + if !self.destination_chain_address.is_empty() { + len += 1; + } + if self.return_address.is_some() { + len += 1; + } + if self.timeout_height.is_some() { + len += 1; + } + if self.timeout_time != 0 { + len += 1; + } + if !self.source_channel.is_empty() { + len += 1; + } + if !self.fee_asset.is_empty() { + len += 1; + } + if !self.memo.is_empty() { + len += 1; + } + if self.bridge_address.is_some() { + len += 1; + } + if self.use_compat_address { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.Ics20Withdrawal", len)?; + if let Some(v) = self.amount.as_ref() { + struct_ser.serialize_field("amount", v)?; + } + if !self.denom.is_empty() { + struct_ser.serialize_field("denom", &self.denom)?; + } + if !self.destination_chain_address.is_empty() { + struct_ser.serialize_field("destinationChainAddress", &self.destination_chain_address)?; + } + if let Some(v) = self.return_address.as_ref() { + struct_ser.serialize_field("returnAddress", v)?; + } + if let Some(v) = self.timeout_height.as_ref() { + struct_ser.serialize_field("timeoutHeight", v)?; + } + if self.timeout_time != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("timeoutTime", ToString::to_string(&self.timeout_time).as_str())?; + } + if !self.source_channel.is_empty() { + struct_ser.serialize_field("sourceChannel", &self.source_channel)?; + } + if !self.fee_asset.is_empty() { + struct_ser.serialize_field("feeAsset", &self.fee_asset)?; + } + if !self.memo.is_empty() { + struct_ser.serialize_field("memo", &self.memo)?; + } + if let Some(v) = self.bridge_address.as_ref() { + struct_ser.serialize_field("bridgeAddress", v)?; + } + if self.use_compat_address { + struct_ser.serialize_field("useCompatAddress", &self.use_compat_address)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for Ics20Withdrawal { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "amount", + "denom", + "destination_chain_address", + "destinationChainAddress", + "return_address", + "returnAddress", + "timeout_height", + "timeoutHeight", + "timeout_time", + "timeoutTime", + "source_channel", + "sourceChannel", + "fee_asset", + "feeAsset", + "memo", + "bridge_address", + "bridgeAddress", + "use_compat_address", + "useCompatAddress", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Amount, + Denom, + DestinationChainAddress, + ReturnAddress, + TimeoutHeight, + TimeoutTime, + SourceChannel, + FeeAsset, + Memo, + BridgeAddress, + UseCompatAddress, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "amount" => Ok(GeneratedField::Amount), + "denom" => Ok(GeneratedField::Denom), + "destinationChainAddress" | "destination_chain_address" => Ok(GeneratedField::DestinationChainAddress), + "returnAddress" | "return_address" => Ok(GeneratedField::ReturnAddress), + "timeoutHeight" | "timeout_height" => Ok(GeneratedField::TimeoutHeight), + "timeoutTime" | "timeout_time" => Ok(GeneratedField::TimeoutTime), + "sourceChannel" | "source_channel" => Ok(GeneratedField::SourceChannel), + "feeAsset" | "fee_asset" => Ok(GeneratedField::FeeAsset), + "memo" => Ok(GeneratedField::Memo), + "bridgeAddress" | "bridge_address" => Ok(GeneratedField::BridgeAddress), + "useCompatAddress" | "use_compat_address" => Ok(GeneratedField::UseCompatAddress), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = Ics20Withdrawal; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.Ics20Withdrawal") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut amount__ = None; + let mut denom__ = None; + let mut destination_chain_address__ = None; + let mut return_address__ = None; + let mut timeout_height__ = None; + let mut timeout_time__ = None; + let mut source_channel__ = None; + let mut fee_asset__ = None; + let mut memo__ = None; + let mut bridge_address__ = None; + let mut use_compat_address__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Amount => { + if amount__.is_some() { + return Err(serde::de::Error::duplicate_field("amount")); + } + amount__ = map_.next_value()?; + } + GeneratedField::Denom => { + if denom__.is_some() { + return Err(serde::de::Error::duplicate_field("denom")); + } + denom__ = Some(map_.next_value()?); + } + GeneratedField::DestinationChainAddress => { + if destination_chain_address__.is_some() { + return Err(serde::de::Error::duplicate_field("destinationChainAddress")); + } + destination_chain_address__ = Some(map_.next_value()?); + } + GeneratedField::ReturnAddress => { + if return_address__.is_some() { + return Err(serde::de::Error::duplicate_field("returnAddress")); + } + return_address__ = map_.next_value()?; + } + GeneratedField::TimeoutHeight => { + if timeout_height__.is_some() { + return Err(serde::de::Error::duplicate_field("timeoutHeight")); + } + timeout_height__ = map_.next_value()?; + } + GeneratedField::TimeoutTime => { + if timeout_time__.is_some() { + return Err(serde::de::Error::duplicate_field("timeoutTime")); + } + timeout_time__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::SourceChannel => { + if source_channel__.is_some() { + return Err(serde::de::Error::duplicate_field("sourceChannel")); + } + source_channel__ = Some(map_.next_value()?); + } + GeneratedField::FeeAsset => { + if fee_asset__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAsset")); + } + fee_asset__ = Some(map_.next_value()?); + } + GeneratedField::Memo => { + if memo__.is_some() { + return Err(serde::de::Error::duplicate_field("memo")); + } + memo__ = Some(map_.next_value()?); + } + GeneratedField::BridgeAddress => { + if bridge_address__.is_some() { + return Err(serde::de::Error::duplicate_field("bridgeAddress")); + } + bridge_address__ = map_.next_value()?; + } + GeneratedField::UseCompatAddress => { + if use_compat_address__.is_some() { + return Err(serde::de::Error::duplicate_field("useCompatAddress")); + } + use_compat_address__ = Some(map_.next_value()?); + } + } + } + Ok(Ics20Withdrawal { + amount: amount__, + denom: denom__.unwrap_or_default(), + destination_chain_address: destination_chain_address__.unwrap_or_default(), + return_address: return_address__, + timeout_height: timeout_height__, + timeout_time: timeout_time__.unwrap_or_default(), + source_channel: source_channel__.unwrap_or_default(), + fee_asset: fee_asset__.unwrap_or_default(), + memo: memo__.unwrap_or_default(), + bridge_address: bridge_address__, + use_compat_address: use_compat_address__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.Ics20Withdrawal", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for InitBridgeAccount { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.rollup_id.is_some() { + len += 1; + } + if !self.asset.is_empty() { + len += 1; + } + if !self.fee_asset.is_empty() { + len += 1; + } + if self.sudo_address.is_some() { + len += 1; + } + if self.withdrawer_address.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.InitBridgeAccount", len)?; + if let Some(v) = self.rollup_id.as_ref() { + struct_ser.serialize_field("rollupId", v)?; + } + if !self.asset.is_empty() { + struct_ser.serialize_field("asset", &self.asset)?; + } + if !self.fee_asset.is_empty() { + struct_ser.serialize_field("feeAsset", &self.fee_asset)?; + } + if let Some(v) = self.sudo_address.as_ref() { + struct_ser.serialize_field("sudoAddress", v)?; + } + if let Some(v) = self.withdrawer_address.as_ref() { + struct_ser.serialize_field("withdrawerAddress", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for InitBridgeAccount { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "rollup_id", + "rollupId", + "asset", + "fee_asset", + "feeAsset", + "sudo_address", + "sudoAddress", + "withdrawer_address", + "withdrawerAddress", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + RollupId, + Asset, + FeeAsset, + SudoAddress, + WithdrawerAddress, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "rollupId" | "rollup_id" => Ok(GeneratedField::RollupId), + "asset" => Ok(GeneratedField::Asset), + "feeAsset" | "fee_asset" => Ok(GeneratedField::FeeAsset), + "sudoAddress" | "sudo_address" => Ok(GeneratedField::SudoAddress), + "withdrawerAddress" | "withdrawer_address" => Ok(GeneratedField::WithdrawerAddress), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = InitBridgeAccount; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.InitBridgeAccount") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut rollup_id__ = None; + let mut asset__ = None; + let mut fee_asset__ = None; + let mut sudo_address__ = None; + let mut withdrawer_address__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::RollupId => { + if rollup_id__.is_some() { + return Err(serde::de::Error::duplicate_field("rollupId")); + } + rollup_id__ = map_.next_value()?; + } + GeneratedField::Asset => { + if asset__.is_some() { + return Err(serde::de::Error::duplicate_field("asset")); + } + asset__ = Some(map_.next_value()?); + } + GeneratedField::FeeAsset => { + if fee_asset__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAsset")); + } + fee_asset__ = Some(map_.next_value()?); + } + GeneratedField::SudoAddress => { + if sudo_address__.is_some() { + return Err(serde::de::Error::duplicate_field("sudoAddress")); + } + sudo_address__ = map_.next_value()?; + } + GeneratedField::WithdrawerAddress => { + if withdrawer_address__.is_some() { + return Err(serde::de::Error::duplicate_field("withdrawerAddress")); + } + withdrawer_address__ = map_.next_value()?; + } + } + } + Ok(InitBridgeAccount { + rollup_id: rollup_id__, + asset: asset__.unwrap_or_default(), + fee_asset: fee_asset__.unwrap_or_default(), + sudo_address: sudo_address__, + withdrawer_address: withdrawer_address__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.InitBridgeAccount", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for Sequence { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.rollup_id.is_some() { + len += 1; + } + if !self.data.is_empty() { + len += 1; + } + if !self.fee_asset.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.Sequence", len)?; + if let Some(v) = self.rollup_id.as_ref() { + struct_ser.serialize_field("rollupId", v)?; + } + if !self.data.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("data", pbjson::private::base64::encode(&self.data).as_str())?; + } + if !self.fee_asset.is_empty() { + struct_ser.serialize_field("feeAsset", &self.fee_asset)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for Sequence { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "rollup_id", + "rollupId", + "data", + "fee_asset", + "feeAsset", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + RollupId, + Data, + FeeAsset, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "rollupId" | "rollup_id" => Ok(GeneratedField::RollupId), + "data" => Ok(GeneratedField::Data), + "feeAsset" | "fee_asset" => Ok(GeneratedField::FeeAsset), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = Sequence; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.Sequence") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut rollup_id__ = None; + let mut data__ = None; + let mut fee_asset__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::RollupId => { + if rollup_id__.is_some() { + return Err(serde::de::Error::duplicate_field("rollupId")); + } + rollup_id__ = map_.next_value()?; + } + GeneratedField::Data => { + if data__.is_some() { + return Err(serde::de::Error::duplicate_field("data")); + } + data__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + GeneratedField::FeeAsset => { + if fee_asset__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAsset")); + } + fee_asset__ = Some(map_.next_value()?); + } + } + } + Ok(Sequence { + rollup_id: rollup_id__, + data: data__.unwrap_or_default(), + fee_asset: fee_asset__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.Sequence", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for SignedTransaction { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.signature.is_empty() { + len += 1; + } + if !self.public_key.is_empty() { + len += 1; + } + if self.transaction.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.SignedTransaction", len)?; + if !self.signature.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("signature", pbjson::private::base64::encode(&self.signature).as_str())?; + } + if !self.public_key.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("publicKey", pbjson::private::base64::encode(&self.public_key).as_str())?; + } + if let Some(v) = self.transaction.as_ref() { + struct_ser.serialize_field("transaction", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for SignedTransaction { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "signature", + "public_key", + "publicKey", + "transaction", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Signature, + PublicKey, + Transaction, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "signature" => Ok(GeneratedField::Signature), + "publicKey" | "public_key" => Ok(GeneratedField::PublicKey), + "transaction" => Ok(GeneratedField::Transaction), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SignedTransaction; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.SignedTransaction") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut signature__ = None; + let mut public_key__ = None; + let mut transaction__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Signature => { + if signature__.is_some() { + return Err(serde::de::Error::duplicate_field("signature")); + } + signature__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + GeneratedField::PublicKey => { + if public_key__.is_some() { + return Err(serde::de::Error::duplicate_field("publicKey")); + } + public_key__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + GeneratedField::Transaction => { + if transaction__.is_some() { + return Err(serde::de::Error::duplicate_field("transaction")); + } + transaction__ = map_.next_value()?; + } + } + } + Ok(SignedTransaction { + signature: signature__.unwrap_or_default(), + public_key: public_key__.unwrap_or_default(), + transaction: transaction__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.SignedTransaction", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for SudoAddressChange { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.new_address.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.SudoAddressChange", len)?; + if let Some(v) = self.new_address.as_ref() { + struct_ser.serialize_field("newAddress", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for SudoAddressChange { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "new_address", + "newAddress", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + NewAddress, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "newAddress" | "new_address" => Ok(GeneratedField::NewAddress), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SudoAddressChange; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.SudoAddressChange") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut new_address__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::NewAddress => { + if new_address__.is_some() { + return Err(serde::de::Error::duplicate_field("newAddress")); + } + new_address__ = map_.next_value()?; + } + } + } + Ok(SudoAddressChange { + new_address: new_address__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.SudoAddressChange", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for TransactionFee { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.asset.is_empty() { + len += 1; + } + if self.fee.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.TransactionFee", len)?; + if !self.asset.is_empty() { + struct_ser.serialize_field("asset", &self.asset)?; + } + if let Some(v) = self.fee.as_ref() { + struct_ser.serialize_field("fee", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for TransactionFee { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "asset", + "fee", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Asset, + Fee, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "asset" => Ok(GeneratedField::Asset), + "fee" => Ok(GeneratedField::Fee), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = TransactionFee; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.TransactionFee") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut asset__ = None; + let mut fee__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Asset => { + if asset__.is_some() { + return Err(serde::de::Error::duplicate_field("asset")); + } + asset__ = Some(map_.next_value()?); + } + GeneratedField::Fee => { + if fee__.is_some() { + return Err(serde::de::Error::duplicate_field("fee")); + } + fee__ = map_.next_value()?; + } + } + } + Ok(TransactionFee { + asset: asset__.unwrap_or_default(), + fee: fee__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.TransactionFee", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for TransactionFeeResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.height != 0 { + len += 1; + } + if !self.fees.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.TransactionFeeResponse", len)?; + if self.height != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("height", ToString::to_string(&self.height).as_str())?; + } + if !self.fees.is_empty() { + struct_ser.serialize_field("fees", &self.fees)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for TransactionFeeResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "height", + "fees", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Height, + Fees, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "height" => Ok(GeneratedField::Height), + "fees" => Ok(GeneratedField::Fees), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = TransactionFeeResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.TransactionFeeResponse") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut height__ = None; + let mut fees__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Height => { + if height__.is_some() { + return Err(serde::de::Error::duplicate_field("height")); + } + height__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Fees => { + if fees__.is_some() { + return Err(serde::de::Error::duplicate_field("fees")); + } + fees__ = Some(map_.next_value()?); + } + } + } + Ok(TransactionFeeResponse { + height: height__.unwrap_or_default(), + fees: fees__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.TransactionFeeResponse", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for TransactionParams { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.nonce != 0 { + len += 1; + } + if !self.chain_id.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.TransactionParams", len)?; + if self.nonce != 0 { + struct_ser.serialize_field("nonce", &self.nonce)?; + } + if !self.chain_id.is_empty() { + struct_ser.serialize_field("chainId", &self.chain_id)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for TransactionParams { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "nonce", + "chain_id", + "chainId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Nonce, + ChainId, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "nonce" => Ok(GeneratedField::Nonce), + "chainId" | "chain_id" => Ok(GeneratedField::ChainId), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = TransactionParams; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.TransactionParams") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut nonce__ = None; + let mut chain_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Nonce => { + if nonce__.is_some() { + return Err(serde::de::Error::duplicate_field("nonce")); + } + nonce__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::ChainId => { + if chain_id__.is_some() { + return Err(serde::de::Error::duplicate_field("chainId")); + } + chain_id__ = Some(map_.next_value()?); + } + } + } + Ok(TransactionParams { + nonce: nonce__.unwrap_or_default(), + chain_id: chain_id__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.TransactionParams", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for Transfer { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.to.is_some() { + len += 1; + } + if self.amount.is_some() { + len += 1; + } + if !self.asset.is_empty() { + len += 1; + } + if !self.fee_asset.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.Transfer", len)?; + if let Some(v) = self.to.as_ref() { + struct_ser.serialize_field("to", v)?; + } + if let Some(v) = self.amount.as_ref() { + struct_ser.serialize_field("amount", v)?; + } + if !self.asset.is_empty() { + struct_ser.serialize_field("asset", &self.asset)?; + } + if !self.fee_asset.is_empty() { + struct_ser.serialize_field("feeAsset", &self.fee_asset)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for Transfer { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "to", + "amount", + "asset", + "fee_asset", + "feeAsset", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + To, + Amount, + Asset, + FeeAsset, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "to" => Ok(GeneratedField::To), + "amount" => Ok(GeneratedField::Amount), + "asset" => Ok(GeneratedField::Asset), + "feeAsset" | "fee_asset" => Ok(GeneratedField::FeeAsset), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = Transfer; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.Transfer") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut to__ = None; + let mut amount__ = None; + let mut asset__ = None; + let mut fee_asset__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::To => { + if to__.is_some() { + return Err(serde::de::Error::duplicate_field("to")); + } + to__ = map_.next_value()?; + } + GeneratedField::Amount => { + if amount__.is_some() { + return Err(serde::de::Error::duplicate_field("amount")); + } + amount__ = map_.next_value()?; + } + GeneratedField::Asset => { + if asset__.is_some() { + return Err(serde::de::Error::duplicate_field("asset")); + } + asset__ = Some(map_.next_value()?); + } + GeneratedField::FeeAsset => { + if fee_asset__.is_some() { + return Err(serde::de::Error::duplicate_field("feeAsset")); + } + fee_asset__ = Some(map_.next_value()?); + } + } + } + Ok(Transfer { + to: to__, + amount: amount__, + asset: asset__.unwrap_or_default(), + fee_asset: fee_asset__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.Transfer", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for UnsignedTransaction { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.actions.is_empty() { + len += 1; + } + if self.params.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.protocol.transaction.v1alpha1.UnsignedTransaction", len)?; + if !self.actions.is_empty() { + struct_ser.serialize_field("actions", &self.actions)?; + } + if let Some(v) = self.params.as_ref() { + struct_ser.serialize_field("params", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for UnsignedTransaction { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "actions", + "params", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Actions, + Params, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "actions" => Ok(GeneratedField::Actions), + "params" => Ok(GeneratedField::Params), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = UnsignedTransaction; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.protocol.transaction.v1alpha1.UnsignedTransaction") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut actions__ = None; + let mut params__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Actions => { + if actions__.is_some() { + return Err(serde::de::Error::duplicate_field("actions")); + } + actions__ = Some(map_.next_value()?); + } + GeneratedField::Params => { + if params__.is_some() { + return Err(serde::de::Error::duplicate_field("params")); + } + params__ = map_.next_value()?; + } + } + } + Ok(UnsignedTransaction { + actions: actions__.unwrap_or_default(), + params: params__, + }) + } + } + deserializer.deserialize_struct("astria.protocol.transaction.v1alpha1.UnsignedTransaction", FIELDS, GeneratedVisitor) + } +} diff --git a/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.rs b/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.rs index 5d8a18974d..ce9f4c94f6 100644 --- a/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.rs +++ b/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.rs @@ -1,59 +1,3 @@ -/// `SignedTransaction` is a transaction that has -/// been signed by the given public key. -/// It wraps an `UnsignedTransaction` with a -/// signature and public key. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct SignedTransaction { - #[prost(bytes = "bytes", tag = "1")] - pub signature: ::prost::bytes::Bytes, - #[prost(bytes = "bytes", tag = "2")] - pub public_key: ::prost::bytes::Bytes, - #[prost(message, optional, tag = "3")] - pub transaction: ::core::option::Option<::pbjson_types::Any>, -} -impl ::prost::Name for SignedTransaction { - const NAME: &'static str = "SignedTransaction"; - const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; - fn full_name() -> ::prost::alloc::string::String { - ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) - } -} -/// `UnsignedTransaction` is a transaction that does -/// not have an attached signature. -/// Note: `value` must be set, it cannot be `None`. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct UnsignedTransaction { - #[prost(message, repeated, tag = "1")] - pub actions: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag = "2")] - pub params: ::core::option::Option, -} -impl ::prost::Name for UnsignedTransaction { - const NAME: &'static str = "UnsignedTransaction"; - const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; - fn full_name() -> ::prost::alloc::string::String { - ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) - } -} -/// `TransactionParams` contains parameters that define the -/// validity of the transaction. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct TransactionParams { - #[prost(uint32, tag = "1")] - pub nonce: u32, - #[prost(string, tag = "2")] - pub chain_id: ::prost::alloc::string::String, -} -impl ::prost::Name for TransactionParams { - const NAME: &'static str = "TransactionParams"; - const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; - fn full_name() -> ::prost::alloc::string::String { - ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) - } -} #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Action { @@ -70,38 +14,38 @@ pub mod action { pub enum Value { /// Core protocol actions are defined on 1-10 #[prost(message, tag = "1")] - TransferAction(super::TransferAction), + Transfer(super::Transfer), #[prost(message, tag = "2")] - SequenceAction(super::SequenceAction), + Sequence(super::Sequence), /// Bridge actions are defined on 11-20 #[prost(message, tag = "11")] - InitBridgeAccountAction(super::InitBridgeAccountAction), + InitBridgeAccount(super::InitBridgeAccount), #[prost(message, tag = "12")] - BridgeLockAction(super::BridgeLockAction), + BridgeLock(super::BridgeLock), #[prost(message, tag = "13")] - BridgeUnlockAction(super::BridgeUnlockAction), + BridgeUnlock(super::BridgeUnlock), #[prost(message, tag = "14")] - BridgeSudoChangeAction(super::BridgeSudoChangeAction), + BridgeSudoChange(super::BridgeSudoChange), /// IBC user actions are defined on 21-30 #[prost(message, tag = "21")] - IbcAction(::penumbra_proto::core::component::ibc::v1::IbcRelay), + Ibc(::penumbra_proto::core::component::ibc::v1::IbcRelay), #[prost(message, tag = "22")] Ics20Withdrawal(super::Ics20Withdrawal), /// POA sudo actions are defined on 50-60 #[prost(message, tag = "50")] - SudoAddressChangeAction(super::SudoAddressChangeAction), + SudoAddressChange(super::SudoAddressChange), #[prost(message, tag = "51")] - ValidatorUpdateAction( + ValidatorUpdate( crate::generated::astria_vendored::tendermint::abci::ValidatorUpdate, ), #[prost(message, tag = "52")] - IbcRelayerChangeAction(super::IbcRelayerChangeAction), + IbcRelayerChange(super::IbcRelayerChange), #[prost(message, tag = "53")] - FeeAssetChangeAction(super::FeeAssetChangeAction), + FeeAssetChange(super::FeeAssetChange), #[prost(message, tag = "55")] - FeeChangeAction(super::FeeChangeAction), + FeeChange(super::FeeChange), #[prost(message, tag = "56")] - IbcSudoChangeAction(super::IbcSudoChangeAction), + IbcSudoChange(super::IbcSudoChange), } } impl ::prost::Name for Action { @@ -117,7 +61,7 @@ impl ::prost::Name for Action { /// be considered invalid by the sequencer. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct TransferAction { +pub struct Transfer { #[prost(message, optional, tag = "1")] pub to: ::core::option::Option, #[prost(message, optional, tag = "2")] @@ -129,21 +73,21 @@ pub struct TransferAction { #[prost(string, tag = "4")] pub fee_asset: ::prost::alloc::string::String, } -impl ::prost::Name for TransferAction { - const NAME: &'static str = "TransferAction"; +impl ::prost::Name for Transfer { + const NAME: &'static str = "Transfer"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } -/// `SequenceAction` represents a transaction destined for another +/// `Sequence` represents a transaction destined for another /// chain, ordered by the sequencer. /// /// It contains the rollup ID of the destination chain, and the /// opaque transaction data. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct SequenceAction { +pub struct Sequence { #[prost(message, optional, tag = "1")] pub rollup_id: ::core::option::Option, #[prost(bytes = "bytes", tag = "2")] @@ -152,26 +96,26 @@ pub struct SequenceAction { #[prost(string, tag = "3")] pub fee_asset: ::prost::alloc::string::String, } -impl ::prost::Name for SequenceAction { - const NAME: &'static str = "SequenceAction"; +impl ::prost::Name for Sequence { + const NAME: &'static str = "Sequence"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } -/// / `SudoAddressChangeAction` represents a transaction that changes +/// / `SudoAddressChange` represents a transaction that changes /// / the sudo address of the chain, which is the address authorized to /// / make validator update actions. /// / /// / It contains the new sudo address. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct SudoAddressChangeAction { +pub struct SudoAddressChange { #[prost(message, optional, tag = "1")] pub new_address: ::core::option::Option, } -impl ::prost::Name for SudoAddressChangeAction { - const NAME: &'static str = "SudoAddressChangeAction"; +impl ::prost::Name for SudoAddressChange { + const NAME: &'static str = "SudoAddressChange"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) @@ -252,17 +196,17 @@ impl ::prost::Name for IbcHeight { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } -/// `IbcRelayerChangeAction` represents a transaction that adds +/// `IbcRelayerChange` represents a transaction that adds /// or removes an IBC relayer address. /// The bytes contained in each variant are the address to add or remove. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct IbcRelayerChangeAction { - #[prost(oneof = "ibc_relayer_change_action::Value", tags = "1, 2")] - pub value: ::core::option::Option, +pub struct IbcRelayerChange { + #[prost(oneof = "ibc_relayer_change::Value", tags = "1, 2")] + pub value: ::core::option::Option, } -/// Nested message and enum types in `IbcRelayerChangeAction`. -pub mod ibc_relayer_change_action { +/// Nested message and enum types in `IbcRelayerChange`. +pub mod ibc_relayer_change { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Value { @@ -272,23 +216,23 @@ pub mod ibc_relayer_change_action { Removal(super::super::super::super::primitive::v1::Address), } } -impl ::prost::Name for IbcRelayerChangeAction { - const NAME: &'static str = "IbcRelayerChangeAction"; +impl ::prost::Name for IbcRelayerChange { + const NAME: &'static str = "IbcRelayerChange"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } -/// `FeeAssetChangeAction` represents a transaction that adds +/// `FeeAssetChange` represents a transaction that adds /// or removes an asset for fee payments. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct FeeAssetChangeAction { - #[prost(oneof = "fee_asset_change_action::Value", tags = "1, 2")] - pub value: ::core::option::Option, +pub struct FeeAssetChange { + #[prost(oneof = "fee_asset_change::Value", tags = "1, 2")] + pub value: ::core::option::Option, } -/// Nested message and enum types in `FeeAssetChangeAction`. -pub mod fee_asset_change_action { +/// Nested message and enum types in `FeeAssetChange`. +pub mod fee_asset_change { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Value { @@ -298,22 +242,22 @@ pub mod fee_asset_change_action { Removal(::prost::alloc::string::String), } } -impl ::prost::Name for FeeAssetChangeAction { - const NAME: &'static str = "FeeAssetChangeAction"; +impl ::prost::Name for FeeAssetChange { + const NAME: &'static str = "FeeAssetChange"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } -/// `InitBridgeAccountAction` represents a transaction that initializes +/// `InitBridgeAccount` represents a transaction that initializes /// a bridge account for the given rollup on the chain. /// /// The sender of the transaction is used as the owner of the bridge account /// and is the only actor authorized to transfer out of this account via -/// a `TransferAction`. +/// a `Transfer`. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct InitBridgeAccountAction { +pub struct InitBridgeAccount { /// the rollup ID to register with the bridge account (the tx sender) #[prost(message, optional, tag = "1")] pub rollup_id: ::core::option::Option, @@ -337,21 +281,21 @@ pub struct InitBridgeAccountAction { super::super::super::primitive::v1::Address, >, } -impl ::prost::Name for InitBridgeAccountAction { - const NAME: &'static str = "InitBridgeAccountAction"; +impl ::prost::Name for InitBridgeAccount { + const NAME: &'static str = "InitBridgeAccount"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } -/// `BridgeLockAction` represents a transaction that transfers +/// `BridgeLock` represents a transaction that transfers /// funds from a sequencer account to a bridge account. /// -/// It's the same as a `TransferAction` but with the added +/// It's the same as a `Transfer` but with the added /// `destination_chain_address` field. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct BridgeLockAction { +pub struct BridgeLock { /// the address of the bridge account to transfer to #[prost(message, optional, tag = "1")] pub to: ::core::option::Option, @@ -369,21 +313,21 @@ pub struct BridgeLockAction { #[prost(string, tag = "5")] pub destination_chain_address: ::prost::alloc::string::String, } -impl ::prost::Name for BridgeLockAction { - const NAME: &'static str = "BridgeLockAction"; +impl ::prost::Name for BridgeLock { + const NAME: &'static str = "BridgeLock"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } -/// `BridgeUnlockAction` represents a transaction that transfers +/// `BridgeUnlock` represents a transaction that transfers /// funds from a bridge account to a sequencer account. /// -/// It's the same as a `TransferAction` but without the `asset` field +/// It's the same as a `Transfer` but without the `asset` field /// and with the `memo` field. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct BridgeUnlockAction { +pub struct BridgeUnlock { /// the to withdraw funds to #[prost(message, optional, tag = "1")] pub to: ::core::option::Option, @@ -416,8 +360,8 @@ pub struct BridgeUnlockAction { #[prost(string, tag = "7")] pub rollup_withdrawal_event_id: ::prost::alloc::string::String, } -impl ::prost::Name for BridgeUnlockAction { - const NAME: &'static str = "BridgeUnlockAction"; +impl ::prost::Name for BridgeUnlock { + const NAME: &'static str = "BridgeUnlock"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) @@ -425,7 +369,7 @@ impl ::prost::Name for BridgeUnlockAction { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct BridgeSudoChangeAction { +pub struct BridgeSudoChange { /// the address of the bridge account to change the sudo or withdrawer addresses for #[prost(message, optional, tag = "1")] pub bridge_address: ::core::option::Option< @@ -445,8 +389,8 @@ pub struct BridgeSudoChangeAction { #[prost(string, tag = "4")] pub fee_asset: ::prost::alloc::string::String, } -impl ::prost::Name for BridgeSudoChangeAction { - const NAME: &'static str = "BridgeSudoChangeAction"; +impl ::prost::Name for BridgeSudoChange { + const NAME: &'static str = "BridgeSudoChange"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) @@ -454,14 +398,14 @@ impl ::prost::Name for BridgeSudoChangeAction { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct FeeChangeAction { +pub struct FeeChange { /// note that the proto number ranges are doubled from that of `Action`. /// this to accomodate both `base_fee` and `byte_cost_multiplier` for each action. - #[prost(oneof = "fee_change_action::Value", tags = "1, 2, 3, 20, 21, 22, 40")] - pub value: ::core::option::Option, + #[prost(oneof = "fee_change::Value", tags = "1, 2, 3, 20, 21, 22, 40")] + pub value: ::core::option::Option, } -/// Nested message and enum types in `FeeChangeAction`. -pub mod fee_change_action { +/// Nested message and enum types in `FeeChange`. +pub mod fee_change { /// note that the proto number ranges are doubled from that of `Action`. /// this to accomodate both `base_fee` and `byte_cost_multiplier` for each action. #[allow(clippy::derive_partial_eq_without_eq)] @@ -486,8 +430,8 @@ pub mod fee_change_action { Ics20WithdrawalBaseFee(super::super::super::super::primitive::v1::Uint128), } } -impl ::prost::Name for FeeChangeAction { - const NAME: &'static str = "FeeChangeAction"; +impl ::prost::Name for FeeChange { + const NAME: &'static str = "FeeChange"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) @@ -495,12 +439,12 @@ impl ::prost::Name for FeeChangeAction { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct IbcSudoChangeAction { +pub struct IbcSudoChange { #[prost(message, optional, tag = "1")] pub new_address: ::core::option::Option, } -impl ::prost::Name for IbcSudoChangeAction { - const NAME: &'static str = "IbcSudoChangeAction"; +impl ::prost::Name for IbcSudoChange { + const NAME: &'static str = "IbcSudoChange"; const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) @@ -537,3 +481,59 @@ impl ::prost::Name for TransactionFee { ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) } } +/// `SignedTransaction` is a transaction that has +/// been signed by the given public key. +/// It wraps an `UnsignedTransaction` with a +/// signature and public key. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignedTransaction { + #[prost(bytes = "bytes", tag = "1")] + pub signature: ::prost::bytes::Bytes, + #[prost(bytes = "bytes", tag = "2")] + pub public_key: ::prost::bytes::Bytes, + #[prost(message, optional, tag = "3")] + pub transaction: ::core::option::Option<::pbjson_types::Any>, +} +impl ::prost::Name for SignedTransaction { + const NAME: &'static str = "SignedTransaction"; + const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) + } +} +/// `UnsignedTransaction` is a transaction that does +/// not have an attached signature. +/// Note: `value` must be set, it cannot be `None`. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnsignedTransaction { + #[prost(message, repeated, tag = "1")] + pub actions: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub params: ::core::option::Option, +} +impl ::prost::Name for UnsignedTransaction { + const NAME: &'static str = "UnsignedTransaction"; + const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) + } +} +/// `TransactionParams` contains parameters that define the +/// validity of the transaction. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransactionParams { + #[prost(uint32, tag = "1")] + pub nonce: u32, + #[prost(string, tag = "2")] + pub chain_id: ::prost::alloc::string::String, +} +impl ::prost::Name for TransactionParams { + const NAME: &'static str = "TransactionParams"; + const PACKAGE: &'static str = "astria.protocol.transactions.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.protocol.transactions.v1alpha1.{}", Self::NAME) + } +} diff --git a/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.serde.rs b/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.serde.rs index 92cfc727e0..ea905cf97e 100644 --- a/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.serde.rs +++ b/crates/astria-core/src/generated/astria.protocol.transactions.v1alpha1.serde.rs @@ -12,47 +12,47 @@ impl serde::Serialize for Action { let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.Action", len)?; if let Some(v) = self.value.as_ref() { match v { - action::Value::TransferAction(v) => { - struct_ser.serialize_field("transferAction", v)?; + action::Value::Transfer(v) => { + struct_ser.serialize_field("transfer", v)?; } - action::Value::SequenceAction(v) => { - struct_ser.serialize_field("sequenceAction", v)?; + action::Value::Sequence(v) => { + struct_ser.serialize_field("sequence", v)?; } - action::Value::InitBridgeAccountAction(v) => { - struct_ser.serialize_field("initBridgeAccountAction", v)?; + action::Value::InitBridgeAccount(v) => { + struct_ser.serialize_field("initBridgeAccount", v)?; } - action::Value::BridgeLockAction(v) => { - struct_ser.serialize_field("bridgeLockAction", v)?; + action::Value::BridgeLock(v) => { + struct_ser.serialize_field("bridgeLock", v)?; } - action::Value::BridgeUnlockAction(v) => { - struct_ser.serialize_field("bridgeUnlockAction", v)?; + action::Value::BridgeUnlock(v) => { + struct_ser.serialize_field("bridgeUnlock", v)?; } - action::Value::BridgeSudoChangeAction(v) => { - struct_ser.serialize_field("bridgeSudoChangeAction", v)?; + action::Value::BridgeSudoChange(v) => { + struct_ser.serialize_field("bridgeSudoChange", v)?; } - action::Value::IbcAction(v) => { - struct_ser.serialize_field("ibcAction", v)?; + action::Value::Ibc(v) => { + struct_ser.serialize_field("ibc", v)?; } action::Value::Ics20Withdrawal(v) => { struct_ser.serialize_field("ics20Withdrawal", v)?; } - action::Value::SudoAddressChangeAction(v) => { - struct_ser.serialize_field("sudoAddressChangeAction", v)?; + action::Value::SudoAddressChange(v) => { + struct_ser.serialize_field("sudoAddressChange", v)?; } - action::Value::ValidatorUpdateAction(v) => { - struct_ser.serialize_field("validatorUpdateAction", v)?; + action::Value::ValidatorUpdate(v) => { + struct_ser.serialize_field("validatorUpdate", v)?; } - action::Value::IbcRelayerChangeAction(v) => { - struct_ser.serialize_field("ibcRelayerChangeAction", v)?; + action::Value::IbcRelayerChange(v) => { + struct_ser.serialize_field("ibcRelayerChange", v)?; } - action::Value::FeeAssetChangeAction(v) => { - struct_ser.serialize_field("feeAssetChangeAction", v)?; + action::Value::FeeAssetChange(v) => { + struct_ser.serialize_field("feeAssetChange", v)?; } - action::Value::FeeChangeAction(v) => { - struct_ser.serialize_field("feeChangeAction", v)?; + action::Value::FeeChange(v) => { + struct_ser.serialize_field("feeChange", v)?; } - action::Value::IbcSudoChangeAction(v) => { - struct_ser.serialize_field("ibcSudoChangeAction", v)?; + action::Value::IbcSudoChange(v) => { + struct_ser.serialize_field("ibcSudoChange", v)?; } } } @@ -66,52 +66,49 @@ impl<'de> serde::Deserialize<'de> for Action { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "transfer_action", - "transferAction", - "sequence_action", - "sequenceAction", - "init_bridge_account_action", - "initBridgeAccountAction", - "bridge_lock_action", - "bridgeLockAction", - "bridge_unlock_action", - "bridgeUnlockAction", - "bridge_sudo_change_action", - "bridgeSudoChangeAction", - "ibc_action", - "ibcAction", + "transfer", + "sequence", + "init_bridge_account", + "initBridgeAccount", + "bridge_lock", + "bridgeLock", + "bridge_unlock", + "bridgeUnlock", + "bridge_sudo_change", + "bridgeSudoChange", + "ibc", "ics20_withdrawal", "ics20Withdrawal", - "sudo_address_change_action", - "sudoAddressChangeAction", - "validator_update_action", - "validatorUpdateAction", - "ibc_relayer_change_action", - "ibcRelayerChangeAction", - "fee_asset_change_action", - "feeAssetChangeAction", - "fee_change_action", - "feeChangeAction", - "ibc_sudo_change_action", - "ibcSudoChangeAction", + "sudo_address_change", + "sudoAddressChange", + "validator_update", + "validatorUpdate", + "ibc_relayer_change", + "ibcRelayerChange", + "fee_asset_change", + "feeAssetChange", + "fee_change", + "feeChange", + "ibc_sudo_change", + "ibcSudoChange", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - TransferAction, - SequenceAction, - InitBridgeAccountAction, - BridgeLockAction, - BridgeUnlockAction, - BridgeSudoChangeAction, - IbcAction, + Transfer, + Sequence, + InitBridgeAccount, + BridgeLock, + BridgeUnlock, + BridgeSudoChange, + Ibc, Ics20Withdrawal, - SudoAddressChangeAction, - ValidatorUpdateAction, - IbcRelayerChangeAction, - FeeAssetChangeAction, - FeeChangeAction, - IbcSudoChangeAction, + SudoAddressChange, + ValidatorUpdate, + IbcRelayerChange, + FeeAssetChange, + FeeChange, + IbcSudoChange, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -133,20 +130,20 @@ impl<'de> serde::Deserialize<'de> for Action { E: serde::de::Error, { match value { - "transferAction" | "transfer_action" => Ok(GeneratedField::TransferAction), - "sequenceAction" | "sequence_action" => Ok(GeneratedField::SequenceAction), - "initBridgeAccountAction" | "init_bridge_account_action" => Ok(GeneratedField::InitBridgeAccountAction), - "bridgeLockAction" | "bridge_lock_action" => Ok(GeneratedField::BridgeLockAction), - "bridgeUnlockAction" | "bridge_unlock_action" => Ok(GeneratedField::BridgeUnlockAction), - "bridgeSudoChangeAction" | "bridge_sudo_change_action" => Ok(GeneratedField::BridgeSudoChangeAction), - "ibcAction" | "ibc_action" => Ok(GeneratedField::IbcAction), + "transfer" => Ok(GeneratedField::Transfer), + "sequence" => Ok(GeneratedField::Sequence), + "initBridgeAccount" | "init_bridge_account" => Ok(GeneratedField::InitBridgeAccount), + "bridgeLock" | "bridge_lock" => Ok(GeneratedField::BridgeLock), + "bridgeUnlock" | "bridge_unlock" => Ok(GeneratedField::BridgeUnlock), + "bridgeSudoChange" | "bridge_sudo_change" => Ok(GeneratedField::BridgeSudoChange), + "ibc" => Ok(GeneratedField::Ibc), "ics20Withdrawal" | "ics20_withdrawal" => Ok(GeneratedField::Ics20Withdrawal), - "sudoAddressChangeAction" | "sudo_address_change_action" => Ok(GeneratedField::SudoAddressChangeAction), - "validatorUpdateAction" | "validator_update_action" => Ok(GeneratedField::ValidatorUpdateAction), - "ibcRelayerChangeAction" | "ibc_relayer_change_action" => Ok(GeneratedField::IbcRelayerChangeAction), - "feeAssetChangeAction" | "fee_asset_change_action" => Ok(GeneratedField::FeeAssetChangeAction), - "feeChangeAction" | "fee_change_action" => Ok(GeneratedField::FeeChangeAction), - "ibcSudoChangeAction" | "ibc_sudo_change_action" => Ok(GeneratedField::IbcSudoChangeAction), + "sudoAddressChange" | "sudo_address_change" => Ok(GeneratedField::SudoAddressChange), + "validatorUpdate" | "validator_update" => Ok(GeneratedField::ValidatorUpdate), + "ibcRelayerChange" | "ibc_relayer_change" => Ok(GeneratedField::IbcRelayerChange), + "feeAssetChange" | "fee_asset_change" => Ok(GeneratedField::FeeAssetChange), + "feeChange" | "fee_change" => Ok(GeneratedField::FeeChange), + "ibcSudoChange" | "ibc_sudo_change" => Ok(GeneratedField::IbcSudoChange), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -169,53 +166,53 @@ impl<'de> serde::Deserialize<'de> for Action { let mut value__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::TransferAction => { + GeneratedField::Transfer => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("transferAction")); + return Err(serde::de::Error::duplicate_field("transfer")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::TransferAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Transfer) ; } - GeneratedField::SequenceAction => { + GeneratedField::Sequence => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("sequenceAction")); + return Err(serde::de::Error::duplicate_field("sequence")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::SequenceAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Sequence) ; } - GeneratedField::InitBridgeAccountAction => { + GeneratedField::InitBridgeAccount => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("initBridgeAccountAction")); + return Err(serde::de::Error::duplicate_field("initBridgeAccount")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::InitBridgeAccountAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::InitBridgeAccount) ; } - GeneratedField::BridgeLockAction => { + GeneratedField::BridgeLock => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("bridgeLockAction")); + return Err(serde::de::Error::duplicate_field("bridgeLock")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeLockAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeLock) ; } - GeneratedField::BridgeUnlockAction => { + GeneratedField::BridgeUnlock => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("bridgeUnlockAction")); + return Err(serde::de::Error::duplicate_field("bridgeUnlock")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeUnlockAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeUnlock) ; } - GeneratedField::BridgeSudoChangeAction => { + GeneratedField::BridgeSudoChange => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("bridgeSudoChangeAction")); + return Err(serde::de::Error::duplicate_field("bridgeSudoChange")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeSudoChangeAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::BridgeSudoChange) ; } - GeneratedField::IbcAction => { + GeneratedField::Ibc => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("ibcAction")); + return Err(serde::de::Error::duplicate_field("ibc")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::IbcAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Ibc) ; } GeneratedField::Ics20Withdrawal => { @@ -225,46 +222,46 @@ impl<'de> serde::Deserialize<'de> for Action { value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::Ics20Withdrawal) ; } - GeneratedField::SudoAddressChangeAction => { + GeneratedField::SudoAddressChange => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("sudoAddressChangeAction")); + return Err(serde::de::Error::duplicate_field("sudoAddressChange")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::SudoAddressChangeAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::SudoAddressChange) ; } - GeneratedField::ValidatorUpdateAction => { + GeneratedField::ValidatorUpdate => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("validatorUpdateAction")); + return Err(serde::de::Error::duplicate_field("validatorUpdate")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::ValidatorUpdateAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::ValidatorUpdate) ; } - GeneratedField::IbcRelayerChangeAction => { + GeneratedField::IbcRelayerChange => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("ibcRelayerChangeAction")); + return Err(serde::de::Error::duplicate_field("ibcRelayerChange")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::IbcRelayerChangeAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::IbcRelayerChange) ; } - GeneratedField::FeeAssetChangeAction => { + GeneratedField::FeeAssetChange => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("feeAssetChangeAction")); + return Err(serde::de::Error::duplicate_field("feeAssetChange")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::FeeAssetChangeAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::FeeAssetChange) ; } - GeneratedField::FeeChangeAction => { + GeneratedField::FeeChange => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("feeChangeAction")); + return Err(serde::de::Error::duplicate_field("feeChange")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::FeeChangeAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::FeeChange) ; } - GeneratedField::IbcSudoChangeAction => { + GeneratedField::IbcSudoChange => { if value__.is_some() { - return Err(serde::de::Error::duplicate_field("ibcSudoChangeAction")); + return Err(serde::de::Error::duplicate_field("ibcSudoChange")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::IbcSudoChangeAction) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Value::IbcSudoChange) ; } } @@ -277,7 +274,7 @@ impl<'de> serde::Deserialize<'de> for Action { deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.Action", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for BridgeLockAction { +impl serde::Serialize for BridgeLock { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -300,7 +297,7 @@ impl serde::Serialize for BridgeLockAction { if !self.destination_chain_address.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.BridgeLockAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.BridgeLock", len)?; if let Some(v) = self.to.as_ref() { struct_ser.serialize_field("to", v)?; } @@ -319,7 +316,7 @@ impl serde::Serialize for BridgeLockAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for BridgeLockAction { +impl<'de> serde::Deserialize<'de> for BridgeLock { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -377,13 +374,13 @@ impl<'de> serde::Deserialize<'de> for BridgeLockAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = BridgeLockAction; + type Value = BridgeLock; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.BridgeLockAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.BridgeLock") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -426,7 +423,7 @@ impl<'de> serde::Deserialize<'de> for BridgeLockAction { } } } - Ok(BridgeLockAction { + Ok(BridgeLock { to: to__, amount: amount__, asset: asset__.unwrap_or_default(), @@ -435,10 +432,10 @@ impl<'de> serde::Deserialize<'de> for BridgeLockAction { }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.BridgeLockAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.BridgeLock", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for BridgeSudoChangeAction { +impl serde::Serialize for BridgeSudoChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -458,7 +455,7 @@ impl serde::Serialize for BridgeSudoChangeAction { if !self.fee_asset.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.BridgeSudoChangeAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.BridgeSudoChange", len)?; if let Some(v) = self.bridge_address.as_ref() { struct_ser.serialize_field("bridgeAddress", v)?; } @@ -474,7 +471,7 @@ impl serde::Serialize for BridgeSudoChangeAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for BridgeSudoChangeAction { +impl<'de> serde::Deserialize<'de> for BridgeSudoChange { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -531,13 +528,13 @@ impl<'de> serde::Deserialize<'de> for BridgeSudoChangeAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = BridgeSudoChangeAction; + type Value = BridgeSudoChange; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.BridgeSudoChangeAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.BridgeSudoChange") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -573,7 +570,7 @@ impl<'de> serde::Deserialize<'de> for BridgeSudoChangeAction { } } } - Ok(BridgeSudoChangeAction { + Ok(BridgeSudoChange { bridge_address: bridge_address__, new_sudo_address: new_sudo_address__, new_withdrawer_address: new_withdrawer_address__, @@ -581,10 +578,10 @@ impl<'de> serde::Deserialize<'de> for BridgeSudoChangeAction { }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.BridgeSudoChangeAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.BridgeSudoChange", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for BridgeUnlockAction { +impl serde::Serialize for BridgeUnlock { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -613,7 +610,7 @@ impl serde::Serialize for BridgeUnlockAction { if !self.rollup_withdrawal_event_id.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.BridgeUnlockAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.BridgeUnlock", len)?; if let Some(v) = self.to.as_ref() { struct_ser.serialize_field("to", v)?; } @@ -639,7 +636,7 @@ impl serde::Serialize for BridgeUnlockAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for BridgeUnlockAction { +impl<'de> serde::Deserialize<'de> for BridgeUnlock { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -705,13 +702,13 @@ impl<'de> serde::Deserialize<'de> for BridgeUnlockAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = BridgeUnlockAction; + type Value = BridgeUnlock; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.BridgeUnlockAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.BridgeUnlock") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -770,7 +767,7 @@ impl<'de> serde::Deserialize<'de> for BridgeUnlockAction { } } } - Ok(BridgeUnlockAction { + Ok(BridgeUnlock { to: to__, amount: amount__, fee_asset: fee_asset__.unwrap_or_default(), @@ -781,10 +778,10 @@ impl<'de> serde::Deserialize<'de> for BridgeUnlockAction { }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.BridgeUnlockAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.BridgeUnlock", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for FeeAssetChangeAction { +impl serde::Serialize for FeeAssetChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -795,13 +792,13 @@ impl serde::Serialize for FeeAssetChangeAction { if self.value.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.FeeAssetChangeAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.FeeAssetChange", len)?; if let Some(v) = self.value.as_ref() { match v { - fee_asset_change_action::Value::Addition(v) => { + fee_asset_change::Value::Addition(v) => { struct_ser.serialize_field("addition", v)?; } - fee_asset_change_action::Value::Removal(v) => { + fee_asset_change::Value::Removal(v) => { struct_ser.serialize_field("removal", v)?; } } @@ -809,7 +806,7 @@ impl serde::Serialize for FeeAssetChangeAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for FeeAssetChangeAction { +impl<'de> serde::Deserialize<'de> for FeeAssetChange { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -856,13 +853,13 @@ impl<'de> serde::Deserialize<'de> for FeeAssetChangeAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = FeeAssetChangeAction; + type Value = FeeAssetChange; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.FeeAssetChangeAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.FeeAssetChange") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -873,25 +870,25 @@ impl<'de> serde::Deserialize<'de> for FeeAssetChangeAction { if value__.is_some() { return Err(serde::de::Error::duplicate_field("addition")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_asset_change_action::Value::Addition); + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_asset_change::Value::Addition); } GeneratedField::Removal => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("removal")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_asset_change_action::Value::Removal); + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_asset_change::Value::Removal); } } } - Ok(FeeAssetChangeAction { + Ok(FeeAssetChange { value: value__, }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.FeeAssetChangeAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.FeeAssetChange", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for FeeChangeAction { +impl serde::Serialize for FeeChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -902,28 +899,28 @@ impl serde::Serialize for FeeChangeAction { if self.value.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.FeeChangeAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.FeeChange", len)?; if let Some(v) = self.value.as_ref() { match v { - fee_change_action::Value::TransferBaseFee(v) => { + fee_change::Value::TransferBaseFee(v) => { struct_ser.serialize_field("transferBaseFee", v)?; } - fee_change_action::Value::SequenceBaseFee(v) => { + fee_change::Value::SequenceBaseFee(v) => { struct_ser.serialize_field("sequenceBaseFee", v)?; } - fee_change_action::Value::SequenceByteCostMultiplier(v) => { + fee_change::Value::SequenceByteCostMultiplier(v) => { struct_ser.serialize_field("sequenceByteCostMultiplier", v)?; } - fee_change_action::Value::InitBridgeAccountBaseFee(v) => { + fee_change::Value::InitBridgeAccountBaseFee(v) => { struct_ser.serialize_field("initBridgeAccountBaseFee", v)?; } - fee_change_action::Value::BridgeLockByteCostMultiplier(v) => { + fee_change::Value::BridgeLockByteCostMultiplier(v) => { struct_ser.serialize_field("bridgeLockByteCostMultiplier", v)?; } - fee_change_action::Value::BridgeSudoChangeBaseFee(v) => { + fee_change::Value::BridgeSudoChangeBaseFee(v) => { struct_ser.serialize_field("bridgeSudoChangeBaseFee", v)?; } - fee_change_action::Value::Ics20WithdrawalBaseFee(v) => { + fee_change::Value::Ics20WithdrawalBaseFee(v) => { struct_ser.serialize_field("ics20WithdrawalBaseFee", v)?; } } @@ -931,7 +928,7 @@ impl serde::Serialize for FeeChangeAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for FeeChangeAction { +impl<'de> serde::Deserialize<'de> for FeeChange { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -1000,13 +997,13 @@ impl<'de> serde::Deserialize<'de> for FeeChangeAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = FeeChangeAction; + type Value = FeeChange; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.FeeChangeAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.FeeChange") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -1017,59 +1014,59 @@ impl<'de> serde::Deserialize<'de> for FeeChangeAction { if value__.is_some() { return Err(serde::de::Error::duplicate_field("transferBaseFee")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change_action::Value::TransferBaseFee) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::TransferBaseFee) ; } GeneratedField::SequenceBaseFee => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("sequenceBaseFee")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change_action::Value::SequenceBaseFee) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::SequenceBaseFee) ; } GeneratedField::SequenceByteCostMultiplier => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("sequenceByteCostMultiplier")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change_action::Value::SequenceByteCostMultiplier) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::SequenceByteCostMultiplier) ; } GeneratedField::InitBridgeAccountBaseFee => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("initBridgeAccountBaseFee")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change_action::Value::InitBridgeAccountBaseFee) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::InitBridgeAccountBaseFee) ; } GeneratedField::BridgeLockByteCostMultiplier => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("bridgeLockByteCostMultiplier")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change_action::Value::BridgeLockByteCostMultiplier) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::BridgeLockByteCostMultiplier) ; } GeneratedField::BridgeSudoChangeBaseFee => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("bridgeSudoChangeBaseFee")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change_action::Value::BridgeSudoChangeBaseFee) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::BridgeSudoChangeBaseFee) ; } GeneratedField::Ics20WithdrawalBaseFee => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("ics20WithdrawalBaseFee")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change_action::Value::Ics20WithdrawalBaseFee) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(fee_change::Value::Ics20WithdrawalBaseFee) ; } } } - Ok(FeeChangeAction { + Ok(FeeChange { value: value__, }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.FeeChangeAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.FeeChange", FIELDS, GeneratedVisitor) } } impl serde::Serialize for IbcHeight { @@ -1188,7 +1185,7 @@ impl<'de> serde::Deserialize<'de> for IbcHeight { deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.IbcHeight", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for IbcRelayerChangeAction { +impl serde::Serialize for IbcRelayerChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -1199,13 +1196,13 @@ impl serde::Serialize for IbcRelayerChangeAction { if self.value.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.IbcRelayerChangeAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.IbcRelayerChange", len)?; if let Some(v) = self.value.as_ref() { match v { - ibc_relayer_change_action::Value::Addition(v) => { + ibc_relayer_change::Value::Addition(v) => { struct_ser.serialize_field("addition", v)?; } - ibc_relayer_change_action::Value::Removal(v) => { + ibc_relayer_change::Value::Removal(v) => { struct_ser.serialize_field("removal", v)?; } } @@ -1213,7 +1210,7 @@ impl serde::Serialize for IbcRelayerChangeAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for IbcRelayerChangeAction { +impl<'de> serde::Deserialize<'de> for IbcRelayerChange { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -1260,13 +1257,13 @@ impl<'de> serde::Deserialize<'de> for IbcRelayerChangeAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = IbcRelayerChangeAction; + type Value = IbcRelayerChange; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.IbcRelayerChangeAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.IbcRelayerChange") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -1277,27 +1274,27 @@ impl<'de> serde::Deserialize<'de> for IbcRelayerChangeAction { if value__.is_some() { return Err(serde::de::Error::duplicate_field("addition")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(ibc_relayer_change_action::Value::Addition) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(ibc_relayer_change::Value::Addition) ; } GeneratedField::Removal => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("removal")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(ibc_relayer_change_action::Value::Removal) + value__ = map_.next_value::<::std::option::Option<_>>()?.map(ibc_relayer_change::Value::Removal) ; } } } - Ok(IbcRelayerChangeAction { + Ok(IbcRelayerChange { value: value__, }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.IbcRelayerChangeAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.IbcRelayerChange", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for IbcSudoChangeAction { +impl serde::Serialize for IbcSudoChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -1308,14 +1305,14 @@ impl serde::Serialize for IbcSudoChangeAction { if self.new_address.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.IbcSudoChangeAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.IbcSudoChange", len)?; if let Some(v) = self.new_address.as_ref() { struct_ser.serialize_field("newAddress", v)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for IbcSudoChangeAction { +impl<'de> serde::Deserialize<'de> for IbcSudoChange { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -1360,13 +1357,13 @@ impl<'de> serde::Deserialize<'de> for IbcSudoChangeAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = IbcSudoChangeAction; + type Value = IbcSudoChange; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.IbcSudoChangeAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.IbcSudoChange") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -1381,12 +1378,12 @@ impl<'de> serde::Deserialize<'de> for IbcSudoChangeAction { } } } - Ok(IbcSudoChangeAction { + Ok(IbcSudoChange { new_address: new_address__, }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.IbcSudoChangeAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.IbcSudoChange", FIELDS, GeneratedVisitor) } } impl serde::Serialize for Ics20Withdrawal { @@ -1661,7 +1658,7 @@ impl<'de> serde::Deserialize<'de> for Ics20Withdrawal { deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.Ics20Withdrawal", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for InitBridgeAccountAction { +impl serde::Serialize for InitBridgeAccount { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -1684,7 +1681,7 @@ impl serde::Serialize for InitBridgeAccountAction { if self.withdrawer_address.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.InitBridgeAccountAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.InitBridgeAccount", len)?; if let Some(v) = self.rollup_id.as_ref() { struct_ser.serialize_field("rollupId", v)?; } @@ -1703,7 +1700,7 @@ impl serde::Serialize for InitBridgeAccountAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for InitBridgeAccountAction { +impl<'de> serde::Deserialize<'de> for InitBridgeAccount { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -1763,13 +1760,13 @@ impl<'de> serde::Deserialize<'de> for InitBridgeAccountAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = InitBridgeAccountAction; + type Value = InitBridgeAccount; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.InitBridgeAccountAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.InitBridgeAccount") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -1812,7 +1809,7 @@ impl<'de> serde::Deserialize<'de> for InitBridgeAccountAction { } } } - Ok(InitBridgeAccountAction { + Ok(InitBridgeAccount { rollup_id: rollup_id__, asset: asset__.unwrap_or_default(), fee_asset: fee_asset__.unwrap_or_default(), @@ -1821,10 +1818,10 @@ impl<'de> serde::Deserialize<'de> for InitBridgeAccountAction { }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.InitBridgeAccountAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.InitBridgeAccount", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for SequenceAction { +impl serde::Serialize for Sequence { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -1841,7 +1838,7 @@ impl serde::Serialize for SequenceAction { if !self.fee_asset.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.SequenceAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.Sequence", len)?; if let Some(v) = self.rollup_id.as_ref() { struct_ser.serialize_field("rollupId", v)?; } @@ -1855,7 +1852,7 @@ impl serde::Serialize for SequenceAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for SequenceAction { +impl<'de> serde::Deserialize<'de> for Sequence { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -1907,13 +1904,13 @@ impl<'de> serde::Deserialize<'de> for SequenceAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = SequenceAction; + type Value = Sequence; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.SequenceAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.Sequence") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -1944,14 +1941,14 @@ impl<'de> serde::Deserialize<'de> for SequenceAction { } } } - Ok(SequenceAction { + Ok(Sequence { rollup_id: rollup_id__, data: data__.unwrap_or_default(), fee_asset: fee_asset__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.SequenceAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.Sequence", FIELDS, GeneratedVisitor) } } impl serde::Serialize for SignedTransaction { @@ -2086,7 +2083,7 @@ impl<'de> serde::Deserialize<'de> for SignedTransaction { deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.SignedTransaction", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for SudoAddressChangeAction { +impl serde::Serialize for SudoAddressChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -2097,14 +2094,14 @@ impl serde::Serialize for SudoAddressChangeAction { if self.new_address.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.SudoAddressChangeAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.SudoAddressChange", len)?; if let Some(v) = self.new_address.as_ref() { struct_ser.serialize_field("newAddress", v)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for SudoAddressChangeAction { +impl<'de> serde::Deserialize<'de> for SudoAddressChange { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -2149,13 +2146,13 @@ impl<'de> serde::Deserialize<'de> for SudoAddressChangeAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = SudoAddressChangeAction; + type Value = SudoAddressChange; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.SudoAddressChangeAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.SudoAddressChange") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -2170,12 +2167,12 @@ impl<'de> serde::Deserialize<'de> for SudoAddressChangeAction { } } } - Ok(SudoAddressChangeAction { + Ok(SudoAddressChange { new_address: new_address__, }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.SudoAddressChangeAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.SudoAddressChange", FIELDS, GeneratedVisitor) } } impl serde::Serialize for TransactionFee { @@ -2508,7 +2505,7 @@ impl<'de> serde::Deserialize<'de> for TransactionParams { deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.TransactionParams", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for TransferAction { +impl serde::Serialize for Transfer { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -2528,7 +2525,7 @@ impl serde::Serialize for TransferAction { if !self.fee_asset.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.TransferAction", len)?; + let mut struct_ser = serializer.serialize_struct("astria.protocol.transactions.v1alpha1.Transfer", len)?; if let Some(v) = self.to.as_ref() { struct_ser.serialize_field("to", v)?; } @@ -2544,7 +2541,7 @@ impl serde::Serialize for TransferAction { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for TransferAction { +impl<'de> serde::Deserialize<'de> for Transfer { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -2598,13 +2595,13 @@ impl<'de> serde::Deserialize<'de> for TransferAction { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = TransferAction; + type Value = Transfer; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.protocol.transactions.v1alpha1.TransferAction") + formatter.write_str("struct astria.protocol.transactions.v1alpha1.Transfer") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -2640,7 +2637,7 @@ impl<'de> serde::Deserialize<'de> for TransferAction { } } } - Ok(TransferAction { + Ok(Transfer { to: to__, amount: amount__, asset: asset__.unwrap_or_default(), @@ -2648,7 +2645,7 @@ impl<'de> serde::Deserialize<'de> for TransferAction { }) } } - deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.TransferAction", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.protocol.transactions.v1alpha1.Transfer", FIELDS, GeneratedVisitor) } } impl serde::Serialize for UnsignedTransaction { diff --git a/crates/astria-core/src/primitive/v1/asset/denom.rs b/crates/astria-core/src/primitive/v1/asset/denom.rs index ec685dba7d..6913f2321b 100644 --- a/crates/astria-core/src/primitive/v1/asset/denom.rs +++ b/crates/astria-core/src/primitive/v1/asset/denom.rs @@ -1,4 +1,5 @@ use std::{ + borrow::Cow, collections::VecDeque, str::FromStr, }; @@ -140,6 +141,27 @@ impl<'a> From<&'a IbcPrefixed> for IbcPrefixed { } } +impl<'a> From<&'a IbcPrefixed> for Cow<'a, IbcPrefixed> { + fn from(ibc_prefixed: &'a IbcPrefixed) -> Self { + Cow::Borrowed(ibc_prefixed) + } +} + +impl<'a> From<&'a TracePrefixed> for Cow<'a, IbcPrefixed> { + fn from(trace_prefixed: &'a TracePrefixed) -> Self { + Cow::Owned(trace_prefixed.to_ibc_prefixed()) + } +} + +impl<'a> From<&'a Denom> for Cow<'a, IbcPrefixed> { + fn from(value: &'a Denom) -> Self { + match value { + Denom::TracePrefixed(trace_prefixed) => Cow::from(trace_prefixed), + Denom::IbcPrefixed(ibc_prefixed) => Cow::from(ibc_prefixed), + } + } +} + impl FromStr for Denom { type Err = ParseDenomError; @@ -543,20 +565,22 @@ pub struct IbcPrefixed { } impl IbcPrefixed { + pub const ENCODED_HASH_LEN: usize = 32; + #[must_use] - pub fn new(id: [u8; 32]) -> Self { + pub const fn new(id: [u8; Self::ENCODED_HASH_LEN]) -> Self { Self { id, } } #[must_use] - pub fn as_bytes(&self) -> &[u8; 32] { + pub const fn as_bytes(&self) -> &[u8; Self::ENCODED_HASH_LEN] { &self.id } #[must_use] - pub fn display_len(&self) -> usize { + pub const fn display_len(&self) -> usize { 68 // "ibc/" + 64 hex characters } } @@ -586,7 +610,7 @@ impl FromStr for IbcPrefixed { if segments.next().is_some() { return Err(ParseIbcPrefixedError::too_many_segments()); } - let id = <[u8; 32]>::from_hex(hex).map_err(Self::Err::hex)?; + let id = <[u8; Self::ENCODED_HASH_LEN]>::from_hex(hex).map_err(Self::Err::hex)?; Ok(Self { id, }) diff --git a/crates/astria-core/src/primitive/v1/mod.rs b/crates/astria-core/src/primitive/v1/mod.rs index 531ebe8f72..36d3f0d583 100644 --- a/crates/astria-core/src/primitive/v1/mod.rs +++ b/crates/astria-core/src/primitive/v1/mod.rs @@ -8,7 +8,7 @@ use std::{ use base64::{ display::Base64Display, - prelude::BASE64_STANDARD, + prelude::BASE64_URL_SAFE, }; use bytes::Bytes; use sha2::{ @@ -231,7 +231,7 @@ impl From<&RollupId> for RollupId { impl std::fmt::Display for RollupId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Base64Display::new(self.as_ref(), &BASE64_STANDARD).fmt(f) + Base64Display::new(self.as_ref(), &BASE64_URL_SAFE).fmt(f) } } diff --git a/crates/astria-core/src/protocol/abci.rs b/crates/astria-core/src/protocol/abci.rs index 7cacc6b780..4047ae679f 100644 --- a/crates/astria-core/src/protocol/abci.rs +++ b/crates/astria-core/src/protocol/abci.rs @@ -25,6 +25,7 @@ impl AbciErrorCode { pub const ALREADY_PRESENT: Self = Self(unsafe { NonZeroU32::new_unchecked(14) }); pub const NONCE_TAKEN: Self = Self(unsafe { NonZeroU32::new_unchecked(15) }); pub const ACCOUNT_SIZE_LIMIT: Self = Self(unsafe { NonZeroU32::new_unchecked(16) }); + pub const PARKED_FULL: Self = Self(unsafe { NonZeroU32::new_unchecked(17) }); } impl AbciErrorCode { @@ -62,6 +63,7 @@ impl AbciErrorCode { Self::ACCOUNT_SIZE_LIMIT => { "the account has reached the maximum number of parked transactions".into() } + Self::PARKED_FULL => "the mempool is out of space for more parked transactions".into(), Self(other) => { format!("invalid error code {other}: should be unreachable (this is a bug)") } diff --git a/crates/astria-core/src/protocol/test_utils.rs b/crates/astria-core/src/protocol/test_utils.rs index c1edc8e92f..6b389039bf 100644 --- a/crates/astria-core/src/protocol/test_utils.rs +++ b/crates/astria-core/src/protocol/test_utils.rs @@ -7,7 +7,7 @@ use prost::Message as _; use super::{ group_sequence_actions_in_signed_transaction_transactions_by_rollup_id, - transaction::v1alpha1::action::SequenceAction, + transaction::v1alpha1::action::Sequence, }; use crate::{ crypto::SigningKey, @@ -93,7 +93,7 @@ impl ConfigureSequencerBlock { let actions: Vec = sequence_data .into_iter() .map(|(rollup_id, data)| { - SequenceAction { + Sequence { rollup_id, data: data.into(), fee_asset: "nria".parse().unwrap(), diff --git a/crates/astria-core/src/protocol/transaction/mod.rs b/crates/astria-core/src/protocol/transaction/mod.rs index 1f44391b58..32a5a9d4fd 100644 --- a/crates/astria-core/src/protocol/transaction/mod.rs +++ b/crates/astria-core/src/protocol/transaction/mod.rs @@ -1,3 +1 @@ pub mod v1alpha1; - -use crate::generated::protocol::transactions::v1alpha1 as raw; diff --git a/crates/astria-core/src/protocol/transaction/v1alpha1/action/group/mod.rs b/crates/astria-core/src/protocol/transaction/v1alpha1/action/group/mod.rs new file mode 100644 index 0000000000..7c79c29306 --- /dev/null +++ b/crates/astria-core/src/protocol/transaction/v1alpha1/action/group/mod.rs @@ -0,0 +1,204 @@ +#[cfg(test)] +mod tests; + +use std::fmt::{ + self, + Debug, +}; + +use penumbra_ibc::IbcRelay; + +use super::{ + Action, + ActionName, + BridgeLock, + BridgeSudoChange, + BridgeUnlock, + FeeAssetChange, + FeeChangeKind, + IbcRelayerChange, + IbcSudoChange, + Ics20Withdrawal, + InitBridgeAccount, + Sequence, + SudoAddressChange, + Transfer, + ValidatorUpdate, +}; + +trait BelongsToGroup { + const GROUP: Group; +} + +macro_rules! impl_belong_to_group { + ($(($act:ty, $group:expr)),*$(,)?) => { + $( + impl BelongsToGroup for $act { + const GROUP: Group = $group; + } + )* + } +} + +impl_belong_to_group!( + (Sequence, Group::BundleableGeneral), + (Transfer, Group::BundleableGeneral), + (ValidatorUpdate, Group::BundleableGeneral), + (SudoAddressChange, Group::UnbundleableSudo), + (IbcRelayerChange, Group::BundleableSudo), + (Ics20Withdrawal, Group::BundleableGeneral), + (InitBridgeAccount, Group::UnbundleableGeneral), + (BridgeLock, Group::BundleableGeneral), + (BridgeUnlock, Group::BundleableGeneral), + (BridgeSudoChange, Group::UnbundleableGeneral), + (FeeChangeKind, Group::BundleableSudo), + (FeeAssetChange, Group::BundleableSudo), + (IbcRelay, Group::BundleableGeneral), + (IbcSudoChange, Group::UnbundleableSudo), +); + +impl Action { + pub const fn group(&self) -> Group { + match self { + Action::Sequence(_) => Sequence::GROUP, + Action::Transfer(_) => Transfer::GROUP, + Action::ValidatorUpdate(_) => ValidatorUpdate::GROUP, + Action::SudoAddressChange(_) => SudoAddressChange::GROUP, + Action::IbcRelayerChange(_) => IbcRelayerChange::GROUP, + Action::Ics20Withdrawal(_) => Ics20Withdrawal::GROUP, + Action::InitBridgeAccount(_) => InitBridgeAccount::GROUP, + Action::BridgeLock(_) => BridgeLock::GROUP, + Action::BridgeUnlock(_) => BridgeUnlock::GROUP, + Action::BridgeSudoChange(_) => BridgeSudoChange::GROUP, + Action::FeeChange(_) => FeeChangeKind::GROUP, + Action::FeeAssetChange(_) => FeeAssetChange::GROUP, + Action::Ibc(_) => IbcRelay::GROUP, + Action::IbcSudoChange(_) => IbcSudoChange::GROUP, + } + } +} + +/// `action::Group` +/// +/// Used to constrain the types of actions that can be included in a single +/// transaction and the order which transactions are ran in a block. +/// +/// NOTE: The ordering is important and must be maintained. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Group { + UnbundleableSudo = 1, + BundleableSudo = 2, + UnbundleableGeneral = 3, + BundleableGeneral = 4, +} + +impl Group { + pub(crate) fn is_bundleable(self) -> bool { + matches!(self, Group::BundleableGeneral | Group::BundleableSudo) + } + + pub(crate) fn is_bundleable_sudo(self) -> bool { + matches!(self, Group::BundleableSudo) + } +} + +impl fmt::Display for Group { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Group::BundleableGeneral => write!(f, "bundleable general"), + Group::UnbundleableGeneral => write!(f, "unbundleable general"), + Group::BundleableSudo => write!(f, "bundleable sudo"), + Group::UnbundleableSudo => write!(f, "unbundleable sudo"), + } + } +} + +#[derive(Debug, thiserror::Error)] +#[error(transparent)] +pub struct Error(ErrorKind); + +impl Error { + fn mixed(original_group: Group, additional_group: Group, action: &'static str) -> Self { + Self(ErrorKind::Mixed { + original_group, + additional_group, + action, + }) + } + + fn not_bundleable(group: Group) -> Self { + Self(ErrorKind::NotBundleable { + group, + }) + } + + fn empty() -> Self { + Self(ErrorKind::Empty) + } +} + +#[derive(Debug, thiserror::Error)] +enum ErrorKind { + #[error( + "input contains mixed `Group` types. original group: {original_group}, additional group: \ + {additional_group}, triggering action: {action}" + )] + Mixed { + original_group: Group, + additional_group: Group, + action: &'static str, + }, + #[error("attempted to create bundle with non bundleable `Group` type: {group}")] + NotBundleable { group: Group }, + #[error("actions cannot be empty")] + Empty, +} + +#[derive(Clone, Debug)] +pub(crate) struct Actions { + group: Group, + inner: Vec, +} + +impl Actions { + pub(crate) fn actions(&self) -> &[Action] { + &self.inner + } + + #[must_use] + pub(crate) fn into_actions(self) -> Vec { + self.inner + } + + pub(crate) fn group(&self) -> Group { + self.group + } + + pub(crate) fn try_from_list_of_actions(actions: Vec) -> Result { + let mut actions_iter = actions.iter(); + let group = match actions_iter.next() { + Some(action) => action.group(), + None => { + // empty `actions` + return Err(Error::empty()); + } + }; + + // assert size constraints on non-bundleable action groups + if actions.len() > 1 && !group.is_bundleable() { + return Err(Error::not_bundleable(group)); + } + + // assert the rest of the actions have the same group as the first + for action in actions_iter { + if action.group() != group { + return Err(Error::mixed(group, action.group(), action.name())); + } + } + + Ok(Self { + group, + inner: actions, + }) + } +} diff --git a/crates/astria-core/src/protocol/transaction/v1alpha1/action_group/tests.rs b/crates/astria-core/src/protocol/transaction/v1alpha1/action/group/tests.rs similarity index 77% rename from crates/astria-core/src/protocol/transaction/v1alpha1/action_group/tests.rs rename to crates/astria-core/src/protocol/transaction/v1alpha1/action/group/tests.rs index 71169c6a67..c5cd6212e0 100644 --- a/crates/astria-core/src/protocol/transaction/v1alpha1/action_group/tests.rs +++ b/crates/astria-core/src/protocol/transaction/v1alpha1/action/group/tests.rs @@ -7,29 +7,27 @@ use crate::{ Address, RollupId, }, - protocol::transaction::v1alpha1::{ - action::{ - Action, - BridgeLockAction, - BridgeSudoChangeAction, - BridgeUnlockAction, - FeeAssetChangeAction, - FeeChange, - FeeChangeAction, - IbcRelayerChangeAction, - IbcSudoChangeAction, - Ics20Withdrawal, - InitBridgeAccountAction, - SequenceAction, - SudoAddressChangeAction, - TransferAction, - ValidatorUpdate, - }, - action_group::{ - ActionGroup, + protocol::transaction::v1alpha1::action::{ + group::{ Actions, ErrorKind, + Group, }, + Action, + BridgeLock, + BridgeSudoChange, + BridgeUnlock, + FeeAssetChange, + FeeChange, + FeeChangeKind, + IbcRelayerChange, + IbcSudoChange, + Ics20Withdrawal, + InitBridgeAccount, + Sequence, + SudoAddressChange, + Transfer, + ValidatorUpdate, }, }; const ASTRIA_ADDRESS_PREFIX: &str = "astria"; @@ -44,25 +42,25 @@ fn try_from_list_of_actions_bundleable_general() { let asset: Denom = "nria".parse().unwrap(); let actions = vec![ - Action::Sequence(SequenceAction { + Action::Sequence(Sequence { rollup_id: RollupId::from([8; 32]), data: vec![].into(), fee_asset: asset.clone(), }), - Action::Transfer(TransferAction { + Action::Transfer(Transfer { to: address, amount: 100, asset: asset.clone(), fee_asset: asset.clone(), }), - Action::BridgeLock(BridgeLockAction { + Action::BridgeLock(BridgeLock { to: address, amount: 100, asset: asset.clone(), fee_asset: asset.clone(), destination_chain_address: String::new(), }), - Action::BridgeUnlock(BridgeUnlockAction { + Action::BridgeUnlock(BridgeUnlock { to: address, amount: 100, fee_asset: asset.clone(), @@ -92,7 +90,7 @@ fn try_from_list_of_actions_bundleable_general() { assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - ActionGroup::BundleableGeneral + Group::BundleableGeneral )); } @@ -106,17 +104,17 @@ fn from_list_of_actions_bundleable_sudo() { let asset: Denom = "nria".parse().unwrap(); let actions = vec![ - Action::FeeChange(FeeChangeAction { - fee_change: FeeChange::TransferBaseFee, + Action::FeeChange(FeeChange { + fee_change: FeeChangeKind::TransferBaseFee, new_value: 100, }), - Action::FeeAssetChange(FeeAssetChangeAction::Addition(asset)), - Action::IbcRelayerChange(IbcRelayerChangeAction::Addition(address)), + Action::FeeAssetChange(FeeAssetChange::Addition(asset)), + Action::IbcRelayerChange(IbcRelayerChange::Addition(address)), ]; assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - ActionGroup::BundleableSudo + Group::BundleableSudo )); } @@ -128,29 +126,29 @@ fn from_list_of_actions_unbundleable_sudo() { .try_build() .unwrap(); - let actions = vec![Action::SudoAddressChange(SudoAddressChangeAction { + let actions = vec![Action::SudoAddressChange(SudoAddressChange { new_address: address, })]; assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - ActionGroup::UnbundleableSudo + Group::UnbundleableSudo )); - let actions = vec![Action::IbcSudoChange(IbcSudoChangeAction { + let actions = vec![Action::IbcSudoChange(IbcSudoChange { new_address: address, })]; assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - ActionGroup::UnbundleableSudo + Group::UnbundleableSudo )); let actions = vec![ - Action::SudoAddressChange(SudoAddressChangeAction { + Action::SudoAddressChange(SudoAddressChange { new_address: address, }), - Action::SudoAddressChange(SudoAddressChangeAction { + Action::SudoAddressChange(SudoAddressChange { new_address: address, }), ]; @@ -172,7 +170,7 @@ fn from_list_of_actions_unbundleable_general() { let asset: Denom = "nria".parse().unwrap(); - let init_bridge_account_action = InitBridgeAccountAction { + let init_bridge_account_action = InitBridgeAccount { rollup_id: RollupId::from([8; 32]), asset: asset.clone(), fee_asset: asset.clone(), @@ -180,7 +178,7 @@ fn from_list_of_actions_unbundleable_general() { withdrawer_address: Some(address), }; - let sudo_bridge_address_change_action = BridgeSudoChangeAction { + let sudo_bridge_address_change_action = BridgeSudoChange { new_sudo_address: Some(address), bridge_address: address, new_withdrawer_address: Some(address), @@ -191,14 +189,14 @@ fn from_list_of_actions_unbundleable_general() { assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - ActionGroup::UnbundleableGeneral + Group::UnbundleableGeneral )); let actions = vec![sudo_bridge_address_change_action.clone().into()]; assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - ActionGroup::UnbundleableGeneral + Group::UnbundleableGeneral )); let actions = vec![ @@ -223,12 +221,12 @@ fn from_list_of_actions_mixed() { let asset: Denom = "nria".parse().unwrap(); let actions = vec![ - Action::Sequence(SequenceAction { + Action::Sequence(Sequence { rollup_id: RollupId::from([8; 32]), data: vec![].into(), fee_asset: asset.clone(), }), - Action::SudoAddressChange(SudoAddressChangeAction { + Action::SudoAddressChange(SudoAddressChange { new_address: address, }), ]; @@ -248,3 +246,10 @@ fn from_list_of_actions_empty() { "expected ErrorKind::Empty, got {error_kind:?}" ); } + +#[test] +fn should_be_in_expected_order() { + assert!(Group::UnbundleableSudo < Group::BundleableSudo); + assert!(Group::BundleableSudo < Group::UnbundleableGeneral); + assert!(Group::UnbundleableGeneral < Group::BundleableGeneral); +} diff --git a/crates/astria-core/src/protocol/transaction/v1alpha1/action.rs b/crates/astria-core/src/protocol/transaction/v1alpha1/action/mod.rs similarity index 68% rename from crates/astria-core/src/protocol/transaction/v1alpha1/action.rs rename to crates/astria-core/src/protocol/transaction/v1alpha1/action/mod.rs index 5a4ef5d88b..fb34593bd1 100644 --- a/crates/astria-core/src/protocol/transaction/v1alpha1/action.rs +++ b/crates/astria-core/src/protocol/transaction/v1alpha1/action/mod.rs @@ -23,6 +23,8 @@ use crate::{ Protobuf, }; +pub mod group; + #[derive(Clone, Debug)] #[cfg_attr( feature = "serde", @@ -30,46 +32,44 @@ use crate::{ serde(into = "raw::Action", try_from = "raw::Action") )] pub enum Action { - Sequence(SequenceAction), - Transfer(TransferAction), + Sequence(Sequence), + Transfer(Transfer), ValidatorUpdate(ValidatorUpdate), - SudoAddressChange(SudoAddressChangeAction), + SudoAddressChange(SudoAddressChange), Ibc(IbcRelay), - IbcSudoChange(IbcSudoChangeAction), + IbcSudoChange(IbcSudoChange), Ics20Withdrawal(Ics20Withdrawal), - IbcRelayerChange(IbcRelayerChangeAction), - FeeAssetChange(FeeAssetChangeAction), - InitBridgeAccount(InitBridgeAccountAction), - BridgeLock(BridgeLockAction), - BridgeUnlock(BridgeUnlockAction), - BridgeSudoChange(BridgeSudoChangeAction), - FeeChange(FeeChangeAction), + IbcRelayerChange(IbcRelayerChange), + FeeAssetChange(FeeAssetChange), + InitBridgeAccount(InitBridgeAccount), + BridgeLock(BridgeLock), + BridgeUnlock(BridgeUnlock), + BridgeSudoChange(BridgeSudoChange), + FeeChange(FeeChange), } impl Protobuf for Action { - type Error = ActionError; + type Error = Error; type Raw = raw::Action; #[must_use] fn to_raw(&self) -> Self::Raw { use raw::action::Value; let kind = match self { - Action::Sequence(act) => Value::SequenceAction(act.to_raw()), - Action::Transfer(act) => Value::TransferAction(act.to_raw()), - Action::ValidatorUpdate(act) => Value::ValidatorUpdateAction(act.to_raw()), - Action::SudoAddressChange(act) => { - Value::SudoAddressChangeAction(act.clone().into_raw()) - } - Action::Ibc(act) => Value::IbcAction(act.clone().into()), - Action::IbcSudoChange(act) => Value::IbcSudoChangeAction(act.clone().into_raw()), + Action::Sequence(act) => Value::Sequence(act.to_raw()), + Action::Transfer(act) => Value::Transfer(act.to_raw()), + Action::ValidatorUpdate(act) => Value::ValidatorUpdate(act.to_raw()), + Action::SudoAddressChange(act) => Value::SudoAddressChange(act.clone().into_raw()), + Action::Ibc(act) => Value::Ibc(act.clone().into()), + Action::IbcSudoChange(act) => Value::IbcSudoChange(act.clone().into_raw()), Action::Ics20Withdrawal(act) => Value::Ics20Withdrawal(act.to_raw()), - Action::IbcRelayerChange(act) => Value::IbcRelayerChangeAction(act.to_raw()), - Action::FeeAssetChange(act) => Value::FeeAssetChangeAction(act.to_raw()), - Action::InitBridgeAccount(act) => Value::InitBridgeAccountAction(act.to_raw()), - Action::BridgeLock(act) => Value::BridgeLockAction(act.to_raw()), - Action::BridgeUnlock(act) => Value::BridgeUnlockAction(act.to_raw()), - Action::BridgeSudoChange(act) => Value::BridgeSudoChangeAction(act.to_raw()), - Action::FeeChange(act) => Value::FeeChangeAction(act.to_raw()), + Action::IbcRelayerChange(act) => Value::IbcRelayerChange(act.to_raw()), + Action::FeeAssetChange(act) => Value::FeeAssetChange(act.to_raw()), + Action::InitBridgeAccount(act) => Value::InitBridgeAccount(act.to_raw()), + Action::BridgeLock(act) => Value::BridgeLock(act.to_raw()), + Action::BridgeUnlock(act) => Value::BridgeUnlock(act.to_raw()), + Action::BridgeSudoChange(act) => Value::BridgeSudoChange(act.to_raw()), + Action::FeeChange(act) => Value::FeeChange(act.to_raw()), }; raw::Action { value: Some(kind), @@ -82,7 +82,7 @@ impl Protobuf for Action { /// /// Returns an error if conversion of one of the inner raw action variants /// to a native action ([`SequenceAction`] or [`TransferAction`]) fails. - fn try_from_raw_ref(raw: &Self::Raw) -> Result { + fn try_from_raw_ref(raw: &Self::Raw) -> Result { Self::try_from_raw(raw.clone()) } @@ -92,62 +92,57 @@ impl Protobuf for Action { /// /// Returns an error if conversion of one of the inner raw action variants /// to a native action ([`SequenceAction`] or [`TransferAction`]) fails. - fn try_from_raw(proto: raw::Action) -> Result { + fn try_from_raw(proto: raw::Action) -> Result { use raw::action::Value; let raw::Action { value, } = proto; let Some(action) = value else { - return Err(ActionError::unset()); + return Err(Error::unset()); }; let action = match action { - Value::SequenceAction(act) => { - Self::Sequence(SequenceAction::try_from_raw(act).map_err(ActionError::sequence)?) + Value::Sequence(act) => { + Self::Sequence(Sequence::try_from_raw(act).map_err(Error::sequence)?) } - Value::TransferAction(act) => { - Self::Transfer(TransferAction::try_from_raw(act).map_err(ActionError::transfer)?) + Value::Transfer(act) => { + Self::Transfer(Transfer::try_from_raw(act).map_err(Error::transfer)?) } - Value::ValidatorUpdateAction(act) => Self::ValidatorUpdate( - ValidatorUpdate::try_from_raw(act).map_err(ActionError::validator_update)?, + Value::ValidatorUpdate(act) => Self::ValidatorUpdate( + ValidatorUpdate::try_from_raw(act).map_err(Error::validator_update)?, ), - Value::SudoAddressChangeAction(act) => Self::SudoAddressChange( - SudoAddressChangeAction::try_from_raw(act) - .map_err(ActionError::sudo_address_change)?, + Value::SudoAddressChange(act) => Self::SudoAddressChange( + SudoAddressChange::try_from_raw(act).map_err(Error::sudo_address_change)?, ), - Value::IbcSudoChangeAction(act) => Self::IbcSudoChange( - IbcSudoChangeAction::try_from_raw(act).map_err(ActionError::ibc_sudo_change)?, + Value::IbcSudoChange(act) => Self::IbcSudoChange( + IbcSudoChange::try_from_raw(act).map_err(Error::ibc_sudo_change)?, ), - Value::IbcAction(act) => { - Self::Ibc(IbcRelay::try_from(act).map_err(|e| ActionError::ibc(e.into()))?) + Value::Ibc(act) => { + Self::Ibc(IbcRelay::try_from(act).map_err(|e| Error::ibc(e.into()))?) } Value::Ics20Withdrawal(act) => Self::Ics20Withdrawal( - Ics20Withdrawal::try_from_raw(act).map_err(ActionError::ics20_withdrawal)?, - ), - Value::IbcRelayerChangeAction(act) => Self::IbcRelayerChange( - IbcRelayerChangeAction::try_from_raw_ref(&act) - .map_err(ActionError::ibc_relayer_change)?, - ), - Value::FeeAssetChangeAction(act) => Self::FeeAssetChange( - FeeAssetChangeAction::try_from_raw_ref(&act) - .map_err(ActionError::fee_asset_change)?, + Ics20Withdrawal::try_from_raw(act).map_err(Error::ics20_withdrawal)?, ), - Value::InitBridgeAccountAction(act) => Self::InitBridgeAccount( - InitBridgeAccountAction::try_from_raw(act) - .map_err(ActionError::init_bridge_account)?, + Value::IbcRelayerChange(act) => Self::IbcRelayerChange( + IbcRelayerChange::try_from_raw_ref(&act).map_err(Error::ibc_relayer_change)?, ), - Value::BridgeLockAction(act) => Self::BridgeLock( - BridgeLockAction::try_from_raw(act).map_err(ActionError::bridge_lock)?, + Value::FeeAssetChange(act) => Self::FeeAssetChange( + FeeAssetChange::try_from_raw_ref(&act).map_err(Error::fee_asset_change)?, ), - Value::BridgeUnlockAction(act) => Self::BridgeUnlock( - BridgeUnlockAction::try_from_raw(act).map_err(ActionError::bridge_unlock)?, + Value::InitBridgeAccount(act) => Self::InitBridgeAccount( + InitBridgeAccount::try_from_raw(act).map_err(Error::init_bridge_account)?, ), - Value::BridgeSudoChangeAction(act) => Self::BridgeSudoChange( - BridgeSudoChangeAction::try_from_raw(act) - .map_err(ActionError::bridge_sudo_change)?, - ), - Value::FeeChangeAction(act) => Self::FeeChange( - FeeChangeAction::try_from_raw_ref(&act).map_err(ActionError::fee_change)?, + Value::BridgeLock(act) => { + Self::BridgeLock(BridgeLock::try_from_raw(act).map_err(Error::bridge_lock)?) + } + Value::BridgeUnlock(act) => { + Self::BridgeUnlock(BridgeUnlock::try_from_raw(act).map_err(Error::bridge_unlock)?) + } + Value::BridgeSudoChange(act) => Self::BridgeSudoChange( + BridgeSudoChange::try_from_raw(act).map_err(Error::bridge_sudo_change)?, ), + Value::FeeChange(act) => { + Self::FeeChange(FeeChange::try_from_raw_ref(&act).map_err(Error::fee_change)?) + } }; Ok(action) } @@ -156,7 +151,7 @@ impl Protobuf for Action { // TODO: add unit tests for these methods (https://github.com/astriaorg/astria/issues/1593) impl Action { #[must_use] - pub fn as_sequence(&self) -> Option<&SequenceAction> { + pub fn as_sequence(&self) -> Option<&Sequence> { let Self::Sequence(sequence_action) = self else { return None; }; @@ -164,7 +159,7 @@ impl Action { } #[must_use] - pub fn as_transfer(&self) -> Option<&TransferAction> { + pub fn as_transfer(&self) -> Option<&Transfer> { let Self::Transfer(transfer_action) = self else { return None; }; @@ -180,26 +175,26 @@ impl Action { } } -impl From for Action { - fn from(value: SequenceAction) -> Self { +impl From for Action { + fn from(value: Sequence) -> Self { Self::Sequence(value) } } -impl From for Action { - fn from(value: TransferAction) -> Self { +impl From for Action { + fn from(value: Transfer) -> Self { Self::Transfer(value) } } -impl From for Action { - fn from(value: SudoAddressChangeAction) -> Self { +impl From for Action { + fn from(value: SudoAddressChange) -> Self { Self::SudoAddressChange(value) } } -impl From for Action { - fn from(value: IbcSudoChangeAction) -> Self { +impl From for Action { + fn from(value: IbcSudoChange) -> Self { Self::IbcSudoChange(value) } } @@ -216,44 +211,44 @@ impl From for Action { } } -impl From for Action { - fn from(value: IbcRelayerChangeAction) -> Self { +impl From for Action { + fn from(value: IbcRelayerChange) -> Self { Self::IbcRelayerChange(value) } } -impl From for Action { - fn from(value: FeeAssetChangeAction) -> Self { +impl From for Action { + fn from(value: FeeAssetChange) -> Self { Self::FeeAssetChange(value) } } -impl From for Action { - fn from(value: InitBridgeAccountAction) -> Self { +impl From for Action { + fn from(value: InitBridgeAccount) -> Self { Self::InitBridgeAccount(value) } } -impl From for Action { - fn from(value: BridgeLockAction) -> Self { +impl From for Action { + fn from(value: BridgeLock) -> Self { Self::BridgeLock(value) } } -impl From for Action { - fn from(value: BridgeUnlockAction) -> Self { +impl From for Action { + fn from(value: BridgeUnlock) -> Self { Self::BridgeUnlock(value) } } -impl From for Action { - fn from(value: BridgeSudoChangeAction) -> Self { +impl From for Action { + fn from(value: BridgeSudoChange) -> Self { Self::BridgeSudoChange(value) } } -impl From for Action { - fn from(value: FeeChangeAction) -> Self { +impl From for Action { + fn from(value: FeeChange) -> Self { Self::FeeChange(value) } } @@ -265,7 +260,7 @@ impl From for raw::Action { } impl TryFrom for Action { - type Error = ActionError; + type Error = Error; fn try_from(value: raw::Action) -> Result { Self::try_from_raw(value) @@ -299,24 +294,20 @@ impl ActionName for Action { } } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct ActionError(ActionErrorKind); +pub struct Error(ActionErrorKind); -impl ActionError { +impl Error { fn unset() -> Self { Self(ActionErrorKind::Unset) } - fn sequence(inner: SequenceActionError) -> Self { + fn sequence(inner: SequenceError) -> Self { Self(ActionErrorKind::Sequence(inner)) } - fn transfer(inner: TransferActionError) -> Self { + fn transfer(inner: TransferError) -> Self { Self(ActionErrorKind::Transfer(inner)) } @@ -324,11 +315,11 @@ impl ActionError { Self(ActionErrorKind::ValidatorUpdate(inner)) } - fn sudo_address_change(inner: SudoAddressChangeActionError) -> Self { + fn sudo_address_change(inner: SudoAddressChangeError) -> Self { Self(ActionErrorKind::SudoAddressChange(inner)) } - fn ibc_sudo_change(inner: IbcSudoChangeActionError) -> Self { + fn ibc_sudo_change(inner: IbcSudoChangeError) -> Self { Self(ActionErrorKind::IbcSudoChange(inner)) } @@ -340,31 +331,31 @@ impl ActionError { Self(ActionErrorKind::Ics20Withdrawal(inner)) } - fn ibc_relayer_change(inner: IbcRelayerChangeActionError) -> Self { + fn ibc_relayer_change(inner: IbcRelayerChangeError) -> Self { Self(ActionErrorKind::IbcRelayerChange(inner)) } - fn fee_asset_change(inner: FeeAssetChangeActionError) -> Self { + fn fee_asset_change(inner: FeeAssetChangeError) -> Self { Self(ActionErrorKind::FeeAssetChange(inner)) } - fn init_bridge_account(inner: InitBridgeAccountActionError) -> Self { + fn init_bridge_account(inner: InitBridgeAccountError) -> Self { Self(ActionErrorKind::InitBridgeAccount(inner)) } - fn bridge_lock(inner: BridgeLockActionError) -> Self { + fn bridge_lock(inner: BridgeLockError) -> Self { Self(ActionErrorKind::BridgeLock(inner)) } - fn bridge_unlock(inner: BridgeUnlockActionError) -> Self { + fn bridge_unlock(inner: BridgeUnlockError) -> Self { Self(ActionErrorKind::BridgeUnlock(inner)) } - fn bridge_sudo_change(inner: BridgeSudoChangeActionError) -> Self { + fn bridge_sudo_change(inner: BridgeSudoChangeError) -> Self { Self(ActionErrorKind::BridgeSudoChange(inner)) } - fn fee_change(inner: FeeChangeActionError) -> Self { + fn fee_change(inner: FeeChangeError) -> Self { Self(ActionErrorKind::FeeChange(inner)) } } @@ -374,55 +365,55 @@ enum ActionErrorKind { #[error("required action value was not set")] Unset, #[error("sequence action was not valid")] - Sequence(#[source] SequenceActionError), + Sequence(#[source] SequenceError), #[error("transfer action was not valid")] - Transfer(#[source] TransferActionError), + Transfer(#[source] TransferError), #[error("validator update action was not valid")] ValidatorUpdate(#[source] ValidatorUpdateError), #[error("sudo address change action was not valid")] - SudoAddressChange(#[source] SudoAddressChangeActionError), + SudoAddressChange(#[source] SudoAddressChangeError), #[error("ibc sudo address change action was not valid")] - IbcSudoChange(#[source] IbcSudoChangeActionError), + IbcSudoChange(#[source] IbcSudoChangeError), #[error("ibc action was not valid")] Ibc(#[source] Box), #[error("ics20 withdrawal action was not valid")] Ics20Withdrawal(#[source] Ics20WithdrawalError), #[error("ibc relayer change action was not valid")] - IbcRelayerChange(#[source] IbcRelayerChangeActionError), + IbcRelayerChange(#[source] IbcRelayerChangeError), #[error("fee asset change action was not valid")] - FeeAssetChange(#[source] FeeAssetChangeActionError), + FeeAssetChange(#[source] FeeAssetChangeError), #[error("init bridge account action was not valid")] - InitBridgeAccount(#[source] InitBridgeAccountActionError), + InitBridgeAccount(#[source] InitBridgeAccountError), #[error("bridge lock action was not valid")] - BridgeLock(#[source] BridgeLockActionError), + BridgeLock(#[source] BridgeLockError), #[error("bridge unlock action was not valid")] - BridgeUnlock(#[source] BridgeUnlockActionError), + BridgeUnlock(#[source] BridgeUnlockError), #[error("bridge sudo change action was not valid")] - BridgeSudoChange(#[source] BridgeSudoChangeActionError), + BridgeSudoChange(#[source] BridgeSudoChangeError), #[error("fee change action was not valid")] - FeeChange(#[source] FeeChangeActionError), + FeeChange(#[source] FeeChangeError), } #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct SequenceActionError(SequenceActionErrorKind); +pub struct SequenceError(SequenceErrorKind); -impl SequenceActionError { +impl SequenceError { fn field_not_set(field: &'static str) -> Self { - Self(SequenceActionErrorKind::FieldNotSet(field)) + Self(SequenceErrorKind::FieldNotSet(field)) } fn rollup_id_length(inner: IncorrectRollupIdLength) -> Self { - Self(SequenceActionErrorKind::RollupIdLength(inner)) + Self(SequenceErrorKind::RollupIdLength(inner)) } fn fee_asset(inner: asset::ParseDenomError) -> Self { - Self(SequenceActionErrorKind::FeeAsset(inner)) + Self(SequenceErrorKind::FeeAsset(inner)) } } #[derive(Debug, thiserror::Error)] -enum SequenceActionErrorKind { +enum SequenceErrorKind { #[error("the expected field in the raw source type was not set: `{0}`")] FieldNotSet(&'static str), #[error("`rollup_id` field did not contain a valid rollup ID")] @@ -432,29 +423,25 @@ enum SequenceActionErrorKind { } #[derive(Clone, Debug)] -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] -pub struct SequenceAction { +pub struct Sequence { pub rollup_id: RollupId, pub data: Bytes, /// asset to use for fee payment. pub fee_asset: asset::Denom, } -impl Protobuf for SequenceAction { - type Error = SequenceActionError; - type Raw = raw::SequenceAction; +impl Protobuf for Sequence { + type Error = SequenceError; + type Raw = raw::Sequence; #[must_use] - fn to_raw(&self) -> raw::SequenceAction { + fn to_raw(&self) -> raw::Sequence { let Self { rollup_id, data, fee_asset, } = self; - raw::SequenceAction { + raw::Sequence { rollup_id: Some(rollup_id.to_raw()), data: data.clone(), fee_asset: fee_asset.to_string(), @@ -466,17 +453,17 @@ impl Protobuf for SequenceAction { /// # Errors /// Returns `SequenceActionError` if the `proto.rollup_id` field was not 32 bytes. fn try_from_raw_ref(raw: &Self::Raw) -> Result { - let raw::SequenceAction { + let raw::Sequence { rollup_id, data, fee_asset, } = raw; let Some(rollup_id) = rollup_id else { - return Err(SequenceActionError::field_not_set("rollup_id")); + return Err(SequenceError::field_not_set("rollup_id")); }; let rollup_id = - RollupId::try_from_raw(rollup_id).map_err(SequenceActionError::rollup_id_length)?; - let fee_asset = fee_asset.parse().map_err(SequenceActionError::fee_asset)?; + RollupId::try_from_raw(rollup_id).map_err(SequenceError::rollup_id_length)?; + let fee_asset = fee_asset.parse().map_err(SequenceError::fee_asset)?; let data = data.clone(); Ok(Self { rollup_id, @@ -487,11 +474,7 @@ impl Protobuf for SequenceAction { } #[derive(Clone, Debug)] -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] -pub struct TransferAction { +pub struct Transfer { pub to: Address, pub amount: u128, /// asset to be transferred. @@ -500,19 +483,19 @@ pub struct TransferAction { pub fee_asset: asset::Denom, } -impl Protobuf for TransferAction { - type Error = TransferActionError; - type Raw = raw::TransferAction; +impl Protobuf for Transfer { + type Error = TransferError; + type Raw = raw::Transfer; #[must_use] - fn to_raw(&self) -> raw::TransferAction { + fn to_raw(&self) -> raw::Transfer { let Self { to, amount, asset, fee_asset, } = self; - raw::TransferAction { + raw::Transfer { to: Some(to.to_raw()), amount: Some((*amount).into()), asset: asset.to_string(), @@ -526,19 +509,19 @@ impl Protobuf for TransferAction { /// Returns `TransferActionError` if the raw action's `to` address did not have the expected /// length. fn try_from_raw_ref(raw: &Self::Raw) -> Result { - let raw::TransferAction { + let raw::Transfer { to, amount, asset, fee_asset, } = raw; let Some(to) = to else { - return Err(TransferActionError::field_not_set("to")); + return Err(TransferError::field_not_set("to")); }; - let to = Address::try_from_raw(to).map_err(TransferActionError::address)?; + let to = Address::try_from_raw(to).map_err(TransferError::address)?; let amount = amount.map_or(0, Into::into); - let asset = asset.parse().map_err(TransferActionError::asset)?; - let fee_asset = fee_asset.parse().map_err(TransferActionError::fee_asset)?; + let asset = asset.parse().map_err(TransferError::asset)?; + let fee_asset = fee_asset.parse().map_err(TransferError::fee_asset)?; Ok(Self { to, @@ -551,9 +534,9 @@ impl Protobuf for TransferAction { #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct TransferActionError(TransferActionErrorKind); +pub struct TransferError(TransferActionErrorKind); -impl TransferActionError { +impl TransferError { fn field_not_set(field: &'static str) -> Self { Self(TransferActionErrorKind::FieldNotSet(field)) } @@ -736,52 +719,48 @@ impl TryFrom raw::SudoAddressChangeAction { + fn into_raw(self) -> raw::SudoAddressChange { let Self { new_address, } = self; - raw::SudoAddressChangeAction { + raw::SudoAddressChange { new_address: Some(new_address.into_raw()), } } #[must_use] - fn to_raw(&self) -> raw::SudoAddressChangeAction { + fn to_raw(&self) -> raw::SudoAddressChange { let Self { new_address, } = self; - raw::SudoAddressChangeAction { + raw::SudoAddressChange { new_address: Some(new_address.to_raw()), } } - /// Convert from a reference to a raw, unchecked protobuf [`raw::SudoAddressChangeAction`]. + /// Convert from a reference to a raw, unchecked protobuf [`raw::SudoAddressChange`]. /// /// # Errors /// /// Returns an error if the raw action's `new_address` did not have the expected /// length. - fn try_from_raw_ref(proto: &Self::Raw) -> Result { - let raw::SudoAddressChangeAction { + fn try_from_raw_ref(proto: &Self::Raw) -> Result { + let raw::SudoAddressChange { new_address, } = proto; let Some(new_address) = new_address else { - return Err(SudoAddressChangeActionError::field_not_set("new_address")); + return Err(SudoAddressChangeError::field_not_set("new_address")); }; let new_address = - Address::try_from_raw(new_address).map_err(SudoAddressChangeActionError::address)?; + Address::try_from_raw(new_address).map_err(SudoAddressChangeError::address)?; Ok(Self { new_address, }) @@ -790,22 +769,22 @@ impl Protobuf for SudoAddressChangeAction { #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct SudoAddressChangeActionError(SudoAddressChangeActionErrorKind); +pub struct SudoAddressChangeError(SudoAddressChangeErrorKind); -impl SudoAddressChangeActionError { +impl SudoAddressChangeError { fn field_not_set(field: &'static str) -> Self { - Self(SudoAddressChangeActionErrorKind::FieldNotSet(field)) + Self(SudoAddressChangeErrorKind::FieldNotSet(field)) } fn address(source: AddressError) -> Self { - Self(SudoAddressChangeActionErrorKind::Address { + Self(SudoAddressChangeErrorKind::Address { source, }) } } #[derive(Debug, thiserror::Error)] -enum SudoAddressChangeActionErrorKind { +enum SudoAddressChangeErrorKind { #[error("the expected field in the raw source type was not set: `{0}`")] FieldNotSet(&'static str), #[error("`new_address` field did not contain a valid address")] @@ -813,27 +792,23 @@ enum SudoAddressChangeActionErrorKind { } #[derive(Debug, Clone)] -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] -pub struct IbcSudoChangeAction { +pub struct IbcSudoChange { pub new_address: Address, } -impl Protobuf for IbcSudoChangeAction { - type Error = IbcSudoChangeActionError; - type Raw = raw::IbcSudoChangeAction; +impl Protobuf for IbcSudoChange { + type Error = IbcSudoChangeError; + type Raw = raw::IbcSudoChange; - fn into_raw(self) -> raw::IbcSudoChangeAction { - raw::IbcSudoChangeAction { + fn into_raw(self) -> raw::IbcSudoChange { + raw::IbcSudoChange { new_address: Some(self.new_address.into_raw()), } } #[must_use] - fn to_raw(&self) -> raw::IbcSudoChangeAction { - raw::IbcSudoChangeAction { + fn to_raw(&self) -> raw::IbcSudoChange { + raw::IbcSudoChange { new_address: Some(self.new_address.to_raw()), } } @@ -844,15 +819,15 @@ impl Protobuf for IbcSudoChangeAction { /// /// Returns an error if the raw action's `new_address` did not have the expected /// length or if the field was not set. - fn try_from_raw_ref(proto: &Self::Raw) -> Result { - let raw::IbcSudoChangeAction { + fn try_from_raw_ref(proto: &Self::Raw) -> Result { + let raw::IbcSudoChange { new_address, } = proto; let Some(new_address) = new_address else { - return Err(IbcSudoChangeActionError::field_not_set("new_address")); + return Err(IbcSudoChangeError::field_not_set("new_address")); }; let new_address = - Address::try_from_raw(new_address).map_err(IbcSudoChangeActionError::address)?; + Address::try_from_raw(new_address).map_err(IbcSudoChangeError::address)?; Ok(Self { new_address, }) @@ -861,22 +836,22 @@ impl Protobuf for IbcSudoChangeAction { #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct IbcSudoChangeActionError(IbcSudoChangeActionErrorKind); +pub struct IbcSudoChangeError(IbcSudoChangeErrorKind); -impl IbcSudoChangeActionError { +impl IbcSudoChangeError { fn field_not_set(field: &'static str) -> Self { - Self(IbcSudoChangeActionErrorKind::FieldNotSet(field)) + Self(IbcSudoChangeErrorKind::FieldNotSet(field)) } fn address(source: AddressError) -> Self { - Self(IbcSudoChangeActionErrorKind::Address { + Self(IbcSudoChangeErrorKind::Address { source, }) } } #[derive(Debug, thiserror::Error)] -enum IbcSudoChangeActionErrorKind { +enum IbcSudoChangeErrorKind { #[error("the expected field in the raw source type was not set: `{0}`")] FieldNotSet(&'static str), #[error("`new_sudo` field did not contain a valid address")] @@ -1217,32 +1192,24 @@ enum Ics20WithdrawalErrorKind { InvalidDenom { source: asset::ParseDenomError }, } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, Clone)] -pub enum IbcRelayerChangeAction { +pub enum IbcRelayerChange { Addition(Address), Removal(Address), } -impl Protobuf for IbcRelayerChangeAction { - type Error = IbcRelayerChangeActionError; - type Raw = raw::IbcRelayerChangeAction; +impl Protobuf for IbcRelayerChange { + type Error = IbcRelayerChangeError; + type Raw = raw::IbcRelayerChange; #[must_use] - fn to_raw(&self) -> raw::IbcRelayerChangeAction { + fn to_raw(&self) -> raw::IbcRelayerChange { match self { - IbcRelayerChangeAction::Addition(address) => raw::IbcRelayerChangeAction { - value: Some(raw::ibc_relayer_change_action::Value::Addition( - address.to_raw(), - )), + IbcRelayerChange::Addition(address) => raw::IbcRelayerChange { + value: Some(raw::ibc_relayer_change::Value::Addition(address.to_raw())), }, - IbcRelayerChangeAction::Removal(address) => raw::IbcRelayerChangeAction { - value: Some(raw::ibc_relayer_change_action::Value::Removal( - address.to_raw(), - )), + IbcRelayerChange::Removal(address) => raw::IbcRelayerChange { + value: Some(raw::ibc_relayer_change::Value::Removal(address.to_raw())), }, } } @@ -1252,81 +1219,71 @@ impl Protobuf for IbcRelayerChangeAction { /// # Errors /// /// - if the `address` field is invalid - fn try_from_raw_ref( - raw: &raw::IbcRelayerChangeAction, - ) -> Result { + fn try_from_raw_ref(raw: &raw::IbcRelayerChange) -> Result { match raw { - raw::IbcRelayerChangeAction { - value: Some(raw::ibc_relayer_change_action::Value::Addition(address)), + raw::IbcRelayerChange { + value: Some(raw::ibc_relayer_change::Value::Addition(address)), } => { let address = - Address::try_from_raw(address).map_err(IbcRelayerChangeActionError::address)?; - Ok(IbcRelayerChangeAction::Addition(address)) + Address::try_from_raw(address).map_err(IbcRelayerChangeError::address)?; + Ok(IbcRelayerChange::Addition(address)) } - raw::IbcRelayerChangeAction { - value: Some(raw::ibc_relayer_change_action::Value::Removal(address)), + raw::IbcRelayerChange { + value: Some(raw::ibc_relayer_change::Value::Removal(address)), } => { let address = - Address::try_from_raw(address).map_err(IbcRelayerChangeActionError::address)?; - Ok(IbcRelayerChangeAction::Removal(address)) + Address::try_from_raw(address).map_err(IbcRelayerChangeError::address)?; + Ok(IbcRelayerChange::Removal(address)) } - _ => Err(IbcRelayerChangeActionError::missing_address()), + _ => Err(IbcRelayerChangeError::missing_address()), } } } #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct IbcRelayerChangeActionError(IbcRelayerChangeActionErrorKind); +pub struct IbcRelayerChangeError(IbcRelayerChangeErrorKind); -impl IbcRelayerChangeActionError { +impl IbcRelayerChangeError { #[must_use] fn address(source: AddressError) -> Self { - Self(IbcRelayerChangeActionErrorKind::Address { + Self(IbcRelayerChangeErrorKind::Address { source, }) } #[must_use] fn missing_address() -> Self { - Self(IbcRelayerChangeActionErrorKind::MissingAddress) + Self(IbcRelayerChangeErrorKind::MissingAddress) } } #[derive(Debug, thiserror::Error)] -enum IbcRelayerChangeActionErrorKind { +enum IbcRelayerChangeErrorKind { #[error("the `address` was invalid")] Address { source: AddressError }, #[error("the `address` was not set")] MissingAddress, } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, Clone)] -pub enum FeeAssetChangeAction { +pub enum FeeAssetChange { Addition(asset::Denom), Removal(asset::Denom), } -impl Protobuf for FeeAssetChangeAction { - type Error = FeeAssetChangeActionError; - type Raw = raw::FeeAssetChangeAction; +impl Protobuf for FeeAssetChange { + type Error = FeeAssetChangeError; + type Raw = raw::FeeAssetChange; #[must_use] - fn to_raw(&self) -> raw::FeeAssetChangeAction { + fn to_raw(&self) -> raw::FeeAssetChange { match self { - FeeAssetChangeAction::Addition(asset) => raw::FeeAssetChangeAction { - value: Some(raw::fee_asset_change_action::Value::Addition( - asset.to_string(), - )), + FeeAssetChange::Addition(asset) => raw::FeeAssetChange { + value: Some(raw::fee_asset_change::Value::Addition(asset.to_string())), }, - FeeAssetChangeAction::Removal(asset) => raw::FeeAssetChangeAction { - value: Some(raw::fee_asset_change_action::Value::Removal( - asset.to_string(), - )), + FeeAssetChange::Removal(asset) => raw::FeeAssetChange { + value: Some(raw::fee_asset_change::Value::Removal(asset.to_string())), }, } } @@ -1336,61 +1293,51 @@ impl Protobuf for FeeAssetChangeAction { /// # Errors /// /// - if the `asset` field is invalid - fn try_from_raw_ref( - raw: &raw::FeeAssetChangeAction, - ) -> Result { + fn try_from_raw_ref(raw: &raw::FeeAssetChange) -> Result { match raw { - raw::FeeAssetChangeAction { - value: Some(raw::fee_asset_change_action::Value::Addition(asset)), + raw::FeeAssetChange { + value: Some(raw::fee_asset_change::Value::Addition(asset)), } => { - let asset = asset - .parse() - .map_err(FeeAssetChangeActionError::invalid_asset)?; - Ok(FeeAssetChangeAction::Addition(asset)) + let asset = asset.parse().map_err(FeeAssetChangeError::invalid_asset)?; + Ok(FeeAssetChange::Addition(asset)) } - raw::FeeAssetChangeAction { - value: Some(raw::fee_asset_change_action::Value::Removal(asset)), + raw::FeeAssetChange { + value: Some(raw::fee_asset_change::Value::Removal(asset)), } => { - let asset = asset - .parse() - .map_err(FeeAssetChangeActionError::invalid_asset)?; - Ok(FeeAssetChangeAction::Removal(asset)) + let asset = asset.parse().map_err(FeeAssetChangeError::invalid_asset)?; + Ok(FeeAssetChange::Removal(asset)) } - _ => Err(FeeAssetChangeActionError::missing_asset()), + _ => Err(FeeAssetChangeError::missing_asset()), } } } #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct FeeAssetChangeActionError(FeeAssetChangeActionErrorKind); +pub struct FeeAssetChangeError(FeeAssetChangeErrorKind); -impl FeeAssetChangeActionError { +impl FeeAssetChangeError { #[must_use] fn invalid_asset(err: asset::ParseDenomError) -> Self { - Self(FeeAssetChangeActionErrorKind::InvalidAsset(err)) + Self(FeeAssetChangeErrorKind::InvalidAsset(err)) } #[must_use] fn missing_asset() -> Self { - Self(FeeAssetChangeActionErrorKind::MissingAsset) + Self(FeeAssetChangeErrorKind::MissingAsset) } } #[derive(Debug, thiserror::Error)] -enum FeeAssetChangeActionErrorKind { +enum FeeAssetChangeErrorKind { #[error("the `asset` field was invalid")] InvalidAsset(#[source] asset::ParseDenomError), #[error("the `asset` field was not set")] MissingAsset, } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, Clone)] -pub struct InitBridgeAccountAction { +pub struct InitBridgeAccount { // the rollup ID to register for the sender of this action pub rollup_id: RollupId, // the assets accepted by the bridge account @@ -1406,13 +1353,13 @@ pub struct InitBridgeAccountAction { pub withdrawer_address: Option
, } -impl Protobuf for InitBridgeAccountAction { - type Error = InitBridgeAccountActionError; - type Raw = raw::InitBridgeAccountAction; +impl Protobuf for InitBridgeAccount { + type Error = InitBridgeAccountError; + type Raw = raw::InitBridgeAccount; #[must_use] - fn into_raw(self) -> raw::InitBridgeAccountAction { - raw::InitBridgeAccountAction { + fn into_raw(self) -> raw::InitBridgeAccount { + raw::InitBridgeAccount { rollup_id: Some(self.rollup_id.to_raw()), asset: self.asset.to_string(), fee_asset: self.fee_asset.to_string(), @@ -1422,8 +1369,8 @@ impl Protobuf for InitBridgeAccountAction { } #[must_use] - fn to_raw(&self) -> raw::InitBridgeAccountAction { - raw::InitBridgeAccountAction { + fn to_raw(&self) -> raw::InitBridgeAccount { + raw::InitBridgeAccount { rollup_id: Some(self.rollup_id.to_raw()), asset: self.asset.to_string(), fee_asset: self.fee_asset.to_string(), @@ -1440,34 +1387,32 @@ impl Protobuf for InitBridgeAccountAction { /// - if the `rollup_id` field is invalid /// - if the `sudo_address` field is invalid /// - if the `withdrawer_address` field is invalid - fn try_from_raw( - proto: raw::InitBridgeAccountAction, - ) -> Result { + fn try_from_raw(proto: raw::InitBridgeAccount) -> Result { let Some(rollup_id) = proto.rollup_id else { - return Err(InitBridgeAccountActionError::field_not_set("rollup_id")); + return Err(InitBridgeAccountError::field_not_set("rollup_id")); }; let rollup_id = RollupId::try_from_raw(&rollup_id) - .map_err(InitBridgeAccountActionError::invalid_rollup_id)?; + .map_err(InitBridgeAccountError::invalid_rollup_id)?; let asset = proto .asset .parse() - .map_err(InitBridgeAccountActionError::invalid_asset)?; + .map_err(InitBridgeAccountError::invalid_asset)?; let fee_asset = proto .fee_asset .parse() - .map_err(InitBridgeAccountActionError::invalid_fee_asset)?; + .map_err(InitBridgeAccountError::invalid_fee_asset)?; let sudo_address = proto .sudo_address .as_ref() .map(Address::try_from_raw) .transpose() - .map_err(InitBridgeAccountActionError::invalid_sudo_address)?; + .map_err(InitBridgeAccountError::invalid_sudo_address)?; let withdrawer_address = proto .withdrawer_address .as_ref() .map(Address::try_from_raw) .transpose() - .map_err(InitBridgeAccountActionError::invalid_withdrawer_address)?; + .map_err(InitBridgeAccountError::invalid_withdrawer_address)?; Ok(Self { rollup_id, @@ -1486,51 +1431,49 @@ impl Protobuf for InitBridgeAccountAction { /// - if the `rollup_id` field is invalid /// - if the `sudo_address` field is invalid /// - if the `withdrawer_address` field is invalid - fn try_from_raw_ref(proto: &Self::Raw) -> Result { + fn try_from_raw_ref(proto: &Self::Raw) -> Result { Self::try_from_raw(proto.clone()) } } #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct InitBridgeAccountActionError(InitBridgeAccountActionErrorKind); +pub struct InitBridgeAccountError(InitBridgeAccountErrorKind); -impl InitBridgeAccountActionError { +impl InitBridgeAccountError { #[must_use] fn field_not_set(field: &'static str) -> Self { - Self(InitBridgeAccountActionErrorKind::FieldNotSet(field)) + Self(InitBridgeAccountErrorKind::FieldNotSet(field)) } #[must_use] fn invalid_rollup_id(err: IncorrectRollupIdLength) -> Self { - Self(InitBridgeAccountActionErrorKind::InvalidRollupId(err)) + Self(InitBridgeAccountErrorKind::InvalidRollupId(err)) } #[must_use] fn invalid_asset(err: asset::ParseDenomError) -> Self { - Self(InitBridgeAccountActionErrorKind::InvalidAsset(err)) + Self(InitBridgeAccountErrorKind::InvalidAsset(err)) } #[must_use] fn invalid_fee_asset(err: asset::ParseDenomError) -> Self { - Self(InitBridgeAccountActionErrorKind::InvalidFeeAsset(err)) + Self(InitBridgeAccountErrorKind::InvalidFeeAsset(err)) } #[must_use] fn invalid_sudo_address(err: AddressError) -> Self { - Self(InitBridgeAccountActionErrorKind::InvalidSudoAddress(err)) + Self(InitBridgeAccountErrorKind::InvalidSudoAddress(err)) } #[must_use] fn invalid_withdrawer_address(err: AddressError) -> Self { - Self(InitBridgeAccountActionErrorKind::InvalidWithdrawerAddress( - err, - )) + Self(InitBridgeAccountErrorKind::InvalidWithdrawerAddress(err)) } } #[derive(Debug, thiserror::Error)] -enum InitBridgeAccountActionErrorKind { +enum InitBridgeAccountErrorKind { #[error("the expected field in the raw source type was not set: `{0}`")] FieldNotSet(&'static str), #[error("the `rollup_id` field was invalid")] @@ -1545,12 +1488,8 @@ enum InitBridgeAccountActionErrorKind { InvalidWithdrawerAddress(#[source] AddressError), } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, Clone)] -pub struct BridgeLockAction { +pub struct BridgeLock { pub to: Address, pub amount: u128, // asset to be transferred. @@ -1561,13 +1500,13 @@ pub struct BridgeLockAction { pub destination_chain_address: String, } -impl Protobuf for BridgeLockAction { - type Error = BridgeLockActionError; - type Raw = raw::BridgeLockAction; +impl Protobuf for BridgeLock { + type Error = BridgeLockError; + type Raw = raw::BridgeLock; #[must_use] - fn into_raw(self) -> raw::BridgeLockAction { - raw::BridgeLockAction { + fn into_raw(self) -> raw::BridgeLock { + raw::BridgeLock { to: Some(self.to.to_raw()), amount: Some(self.amount.into()), asset: self.asset.to_string(), @@ -1577,8 +1516,8 @@ impl Protobuf for BridgeLockAction { } #[must_use] - fn to_raw(&self) -> raw::BridgeLockAction { - raw::BridgeLockAction { + fn to_raw(&self) -> raw::BridgeLock { + raw::BridgeLock { to: Some(self.to.to_raw()), amount: Some(self.amount.into()), asset: self.asset.to_string(), @@ -1595,22 +1534,20 @@ impl Protobuf for BridgeLockAction { /// - if the `to` field is invalid /// - if the `asset` field is invalid /// - if the `fee_asset` field is invalid - fn try_from_raw(proto: raw::BridgeLockAction) -> Result { + fn try_from_raw(proto: raw::BridgeLock) -> Result { let Some(to) = proto.to else { - return Err(BridgeLockActionError::field_not_set("to")); + return Err(BridgeLockError::field_not_set("to")); }; - let to = Address::try_from_raw(&to).map_err(BridgeLockActionError::address)?; - let amount = proto - .amount - .ok_or(BridgeLockActionError::missing_amount())?; + let to = Address::try_from_raw(&to).map_err(BridgeLockError::address)?; + let amount = proto.amount.ok_or(BridgeLockError::missing_amount())?; let asset = proto .asset .parse() - .map_err(BridgeLockActionError::invalid_asset)?; + .map_err(BridgeLockError::invalid_asset)?; let fee_asset = proto .fee_asset .parse() - .map_err(BridgeLockActionError::invalid_fee_asset)?; + .map_err(BridgeLockError::invalid_fee_asset)?; Ok(Self { to, amount: amount.into(), @@ -1628,46 +1565,46 @@ impl Protobuf for BridgeLockAction { /// - if the `to` field is invalid /// - if the `asset` field is invalid /// - if the `fee_asset` field is invalid - fn try_from_raw_ref(proto: &raw::BridgeLockAction) -> Result { + fn try_from_raw_ref(proto: &raw::BridgeLock) -> Result { Self::try_from_raw(proto.clone()) } } #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct BridgeLockActionError(BridgeLockActionErrorKind); +pub struct BridgeLockError(BridgeLockErrorKind); -impl BridgeLockActionError { +impl BridgeLockError { #[must_use] fn field_not_set(field: &'static str) -> Self { - Self(BridgeLockActionErrorKind::FieldNotSet(field)) + Self(BridgeLockErrorKind::FieldNotSet(field)) } #[must_use] fn address(source: AddressError) -> Self { - Self(BridgeLockActionErrorKind::Address { + Self(BridgeLockErrorKind::Address { source, }) } #[must_use] fn missing_amount() -> Self { - Self(BridgeLockActionErrorKind::MissingAmount) + Self(BridgeLockErrorKind::MissingAmount) } #[must_use] fn invalid_asset(err: asset::ParseDenomError) -> Self { - Self(BridgeLockActionErrorKind::InvalidAsset(err)) + Self(BridgeLockErrorKind::InvalidAsset(err)) } #[must_use] fn invalid_fee_asset(err: asset::ParseDenomError) -> Self { - Self(BridgeLockActionErrorKind::InvalidFeeAsset(err)) + Self(BridgeLockErrorKind::InvalidFeeAsset(err)) } } #[derive(Debug, thiserror::Error)] -enum BridgeLockActionErrorKind { +enum BridgeLockErrorKind { #[error("the expected field in the raw source type was not set: `{0}`")] FieldNotSet(&'static str), #[error("the `to` field was invalid")] @@ -1680,12 +1617,8 @@ enum BridgeLockActionErrorKind { InvalidFeeAsset(#[source] asset::ParseDenomError), } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, Clone, PartialEq, Eq)] -pub struct BridgeUnlockAction { +pub struct BridgeUnlock { pub to: Address, pub amount: u128, // asset to use for fee payment. @@ -1700,13 +1633,13 @@ pub struct BridgeUnlockAction { pub rollup_withdrawal_event_id: String, } -impl Protobuf for BridgeUnlockAction { - type Error = BridgeUnlockActionError; - type Raw = raw::BridgeUnlockAction; +impl Protobuf for BridgeUnlock { + type Error = BridgeUnlockError; + type Raw = raw::BridgeUnlock; #[must_use] - fn into_raw(self) -> raw::BridgeUnlockAction { - raw::BridgeUnlockAction { + fn into_raw(self) -> raw::BridgeUnlock { + raw::BridgeUnlock { to: Some(self.to.into_raw()), amount: Some(self.amount.into()), fee_asset: self.fee_asset.to_string(), @@ -1718,8 +1651,8 @@ impl Protobuf for BridgeUnlockAction { } #[must_use] - fn to_raw(&self) -> raw::BridgeUnlockAction { - raw::BridgeUnlockAction { + fn to_raw(&self) -> raw::BridgeUnlock { + raw::BridgeUnlock { to: Some(self.to.to_raw()), amount: Some(self.amount.into()), fee_asset: self.fee_asset.to_string(), @@ -1739,8 +1672,8 @@ impl Protobuf for BridgeUnlockAction { /// - if the `amount` field is invalid /// - if the `fee_asset` field is invalid /// - if the `from` field is invalid - fn try_from_raw(proto: raw::BridgeUnlockAction) -> Result { - let raw::BridgeUnlockAction { + fn try_from_raw(proto: raw::BridgeUnlock) -> Result { + let raw::BridgeUnlock { to, amount, fee_asset, @@ -1750,18 +1683,14 @@ impl Protobuf for BridgeUnlockAction { rollup_withdrawal_event_id, } = proto; let to = to - .ok_or_else(|| BridgeUnlockActionError::field_not_set("to")) - .and_then(|to| Address::try_from_raw(&to).map_err(BridgeUnlockActionError::address))?; - let amount = amount.ok_or_else(|| BridgeUnlockActionError::field_not_set("amount"))?; - let fee_asset = fee_asset - .parse() - .map_err(BridgeUnlockActionError::fee_asset)?; + .ok_or_else(|| BridgeUnlockError::field_not_set("to")) + .and_then(|to| Address::try_from_raw(&to).map_err(BridgeUnlockError::address))?; + let amount = amount.ok_or_else(|| BridgeUnlockError::field_not_set("amount"))?; + let fee_asset = fee_asset.parse().map_err(BridgeUnlockError::fee_asset)?; let bridge_address = bridge_address - .ok_or_else(|| BridgeUnlockActionError::field_not_set("bridge_address")) - .and_then(|to| { - Address::try_from_raw(&to).map_err(BridgeUnlockActionError::bridge_address) - })?; + .ok_or_else(|| BridgeUnlockError::field_not_set("bridge_address")) + .and_then(|to| Address::try_from_raw(&to).map_err(BridgeUnlockError::bridge_address))?; Ok(Self { to, amount: amount.into(), @@ -1782,45 +1711,45 @@ impl Protobuf for BridgeUnlockAction { /// - if the `amount` field is invalid /// - if the `fee_asset` field is invalid /// - if the `from` field is invalid - fn try_from_raw_ref(proto: &raw::BridgeUnlockAction) -> Result { + fn try_from_raw_ref(proto: &raw::BridgeUnlock) -> Result { Self::try_from_raw(proto.clone()) } } #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct BridgeUnlockActionError(BridgeUnlockActionErrorKind); +pub struct BridgeUnlockError(BridgeUnlockErrorKind); -impl BridgeUnlockActionError { +impl BridgeUnlockError { #[must_use] fn field_not_set(field: &'static str) -> Self { - Self(BridgeUnlockActionErrorKind::FieldNotSet(field)) + Self(BridgeUnlockErrorKind::FieldNotSet(field)) } #[must_use] fn address(source: AddressError) -> Self { - Self(BridgeUnlockActionErrorKind::Address { + Self(BridgeUnlockErrorKind::Address { source, }) } #[must_use] fn fee_asset(source: asset::ParseDenomError) -> Self { - Self(BridgeUnlockActionErrorKind::FeeAsset { + Self(BridgeUnlockErrorKind::FeeAsset { source, }) } #[must_use] fn bridge_address(source: AddressError) -> Self { - Self(BridgeUnlockActionErrorKind::BridgeAddress { + Self(BridgeUnlockErrorKind::BridgeAddress { source, }) } } #[derive(Debug, thiserror::Error)] -enum BridgeUnlockActionErrorKind { +enum BridgeUnlockErrorKind { #[error("the expected field in the raw source type was not set: `{0}`")] FieldNotSet(&'static str), #[error("the `to` field was invalid")] @@ -1831,25 +1760,21 @@ enum BridgeUnlockActionErrorKind { BridgeAddress { source: AddressError }, } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, Clone)] -pub struct BridgeSudoChangeAction { +pub struct BridgeSudoChange { pub bridge_address: Address, pub new_sudo_address: Option
, pub new_withdrawer_address: Option
, pub fee_asset: asset::Denom, } -impl Protobuf for BridgeSudoChangeAction { - type Error = BridgeSudoChangeActionError; - type Raw = raw::BridgeSudoChangeAction; +impl Protobuf for BridgeSudoChange { + type Error = BridgeSudoChangeError; + type Raw = raw::BridgeSudoChange; #[must_use] - fn into_raw(self) -> raw::BridgeSudoChangeAction { - raw::BridgeSudoChangeAction { + fn into_raw(self) -> raw::BridgeSudoChange { + raw::BridgeSudoChange { bridge_address: Some(self.bridge_address.to_raw()), new_sudo_address: self.new_sudo_address.map(Address::into_raw), new_withdrawer_address: self.new_withdrawer_address.map(Address::into_raw), @@ -1858,8 +1783,8 @@ impl Protobuf for BridgeSudoChangeAction { } #[must_use] - fn to_raw(&self) -> raw::BridgeSudoChangeAction { - raw::BridgeSudoChangeAction { + fn to_raw(&self) -> raw::BridgeSudoChange { + raw::BridgeSudoChange { bridge_address: Some(self.bridge_address.to_raw()), new_sudo_address: self.new_sudo_address.as_ref().map(Address::to_raw), new_withdrawer_address: self.new_withdrawer_address.as_ref().map(Address::to_raw), @@ -1876,30 +1801,28 @@ impl Protobuf for BridgeSudoChangeAction { /// - if the `new_sudo_address` field is invalid /// - if the `new_withdrawer_address` field is invalid /// - if the `fee_asset` field is invalid - fn try_from_raw( - proto: raw::BridgeSudoChangeAction, - ) -> Result { + fn try_from_raw(proto: raw::BridgeSudoChange) -> Result { let Some(bridge_address) = proto.bridge_address else { - return Err(BridgeSudoChangeActionError::field_not_set("bridge_address")); + return Err(BridgeSudoChangeError::field_not_set("bridge_address")); }; let bridge_address = Address::try_from_raw(&bridge_address) - .map_err(BridgeSudoChangeActionError::invalid_bridge_address)?; + .map_err(BridgeSudoChangeError::invalid_bridge_address)?; let new_sudo_address = proto .new_sudo_address .as_ref() .map(Address::try_from_raw) .transpose() - .map_err(BridgeSudoChangeActionError::invalid_new_sudo_address)?; + .map_err(BridgeSudoChangeError::invalid_new_sudo_address)?; let new_withdrawer_address = proto .new_withdrawer_address .as_ref() .map(Address::try_from_raw) .transpose() - .map_err(BridgeSudoChangeActionError::invalid_new_withdrawer_address)?; + .map_err(BridgeSudoChangeError::invalid_new_withdrawer_address)?; let fee_asset = proto .fee_asset .parse() - .map_err(BridgeSudoChangeActionError::invalid_fee_asset)?; + .map_err(BridgeSudoChangeError::invalid_fee_asset)?; Ok(Self { bridge_address, @@ -1918,46 +1841,44 @@ impl Protobuf for BridgeSudoChangeAction { /// - if the `new_sudo_address` field is invalid /// - if the `new_withdrawer_address` field is invalid /// - if the `fee_asset` field is invalid - fn try_from_raw_ref( - proto: &raw::BridgeSudoChangeAction, - ) -> Result { + fn try_from_raw_ref(proto: &raw::BridgeSudoChange) -> Result { Self::try_from_raw(proto.clone()) } } #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct BridgeSudoChangeActionError(BridgeSudoChangeActionErrorKind); +pub struct BridgeSudoChangeError(BridgeSudoChangeErrorKind); -impl BridgeSudoChangeActionError { +impl BridgeSudoChangeError { #[must_use] fn field_not_set(field: &'static str) -> Self { - Self(BridgeSudoChangeActionErrorKind::FieldNotSet(field)) + Self(BridgeSudoChangeErrorKind::FieldNotSet(field)) } #[must_use] fn invalid_bridge_address(err: AddressError) -> Self { - Self(BridgeSudoChangeActionErrorKind::InvalidBridgeAddress(err)) + Self(BridgeSudoChangeErrorKind::InvalidBridgeAddress(err)) } #[must_use] fn invalid_new_sudo_address(err: AddressError) -> Self { - Self(BridgeSudoChangeActionErrorKind::InvalidNewSudoAddress(err)) + Self(BridgeSudoChangeErrorKind::InvalidNewSudoAddress(err)) } #[must_use] fn invalid_new_withdrawer_address(err: AddressError) -> Self { - Self(BridgeSudoChangeActionErrorKind::InvalidNewWithdrawerAddress(err)) + Self(BridgeSudoChangeErrorKind::InvalidNewWithdrawerAddress(err)) } #[must_use] fn invalid_fee_asset(err: asset::ParseDenomError) -> Self { - Self(BridgeSudoChangeActionErrorKind::InvalidFeeAsset(err)) + Self(BridgeSudoChangeErrorKind::InvalidFeeAsset(err)) } } #[derive(Debug, thiserror::Error)] -enum BridgeSudoChangeActionErrorKind { +enum BridgeSudoChangeErrorKind { #[error("the expected field in the raw source type was not set: `{0}`")] FieldNotSet(&'static str), #[error("the `bridge_address` field was invalid")] @@ -1971,7 +1892,7 @@ enum BridgeSudoChangeActionErrorKind { } #[derive(Debug, Clone)] -pub enum FeeChange { +pub enum FeeChangeKind { TransferBaseFee, SequenceBaseFee, SequenceByteCostMultiplier, @@ -1981,46 +1902,40 @@ pub enum FeeChange { Ics20WithdrawalBaseFee, } -#[expect( - clippy::module_name_repetitions, - reason = "for parity with the Protobuf spec" -)] #[derive(Debug, Clone)] -pub struct FeeChangeAction { - pub fee_change: FeeChange, +pub struct FeeChange { + pub fee_change: FeeChangeKind, pub new_value: u128, } -impl Protobuf for FeeChangeAction { - type Error = FeeChangeActionError; - type Raw = raw::FeeChangeAction; +impl Protobuf for FeeChange { + type Error = FeeChangeError; + type Raw = raw::FeeChange; #[must_use] - fn to_raw(&self) -> raw::FeeChangeAction { - raw::FeeChangeAction { + fn to_raw(&self) -> raw::FeeChange { + raw::FeeChange { value: Some(match self.fee_change { - FeeChange::TransferBaseFee => { - raw::fee_change_action::Value::TransferBaseFee(self.new_value.into()) + FeeChangeKind::TransferBaseFee => { + raw::fee_change::Value::TransferBaseFee(self.new_value.into()) } - FeeChange::SequenceBaseFee => { - raw::fee_change_action::Value::SequenceBaseFee(self.new_value.into()) + FeeChangeKind::SequenceBaseFee => { + raw::fee_change::Value::SequenceBaseFee(self.new_value.into()) } - FeeChange::SequenceByteCostMultiplier => { - raw::fee_change_action::Value::SequenceByteCostMultiplier(self.new_value.into()) + FeeChangeKind::SequenceByteCostMultiplier => { + raw::fee_change::Value::SequenceByteCostMultiplier(self.new_value.into()) } - FeeChange::InitBridgeAccountBaseFee => { - raw::fee_change_action::Value::InitBridgeAccountBaseFee(self.new_value.into()) + FeeChangeKind::InitBridgeAccountBaseFee => { + raw::fee_change::Value::InitBridgeAccountBaseFee(self.new_value.into()) } - FeeChange::BridgeLockByteCostMultiplier => { - raw::fee_change_action::Value::BridgeLockByteCostMultiplier( - self.new_value.into(), - ) + FeeChangeKind::BridgeLockByteCostMultiplier => { + raw::fee_change::Value::BridgeLockByteCostMultiplier(self.new_value.into()) } - FeeChange::BridgeSudoChangeBaseFee => { - raw::fee_change_action::Value::BridgeSudoChangeBaseFee(self.new_value.into()) + FeeChangeKind::BridgeSudoChangeBaseFee => { + raw::fee_change::Value::BridgeSudoChangeBaseFee(self.new_value.into()) } - FeeChange::Ics20WithdrawalBaseFee => { - raw::fee_change_action::Value::Ics20WithdrawalBaseFee(self.new_value.into()) + FeeChangeKind::Ics20WithdrawalBaseFee => { + raw::fee_change::Value::Ics20WithdrawalBaseFee(self.new_value.into()) } }), } @@ -2032,30 +1947,30 @@ impl Protobuf for FeeChangeAction { /// /// - if the fee change `value` field is missing /// - if the `new_value` field is missing - fn try_from_raw_ref(proto: &raw::FeeChangeAction) -> Result { + fn try_from_raw_ref(proto: &raw::FeeChange) -> Result { let (fee_change, new_value) = match proto.value { - Some(raw::fee_change_action::Value::TransferBaseFee(new_value)) => { - (FeeChange::TransferBaseFee, new_value) + Some(raw::fee_change::Value::TransferBaseFee(new_value)) => { + (FeeChangeKind::TransferBaseFee, new_value) } - Some(raw::fee_change_action::Value::SequenceBaseFee(new_value)) => { - (FeeChange::SequenceBaseFee, new_value) + Some(raw::fee_change::Value::SequenceBaseFee(new_value)) => { + (FeeChangeKind::SequenceBaseFee, new_value) } - Some(raw::fee_change_action::Value::SequenceByteCostMultiplier(new_value)) => { - (FeeChange::SequenceByteCostMultiplier, new_value) + Some(raw::fee_change::Value::SequenceByteCostMultiplier(new_value)) => { + (FeeChangeKind::SequenceByteCostMultiplier, new_value) } - Some(raw::fee_change_action::Value::InitBridgeAccountBaseFee(new_value)) => { - (FeeChange::InitBridgeAccountBaseFee, new_value) + Some(raw::fee_change::Value::InitBridgeAccountBaseFee(new_value)) => { + (FeeChangeKind::InitBridgeAccountBaseFee, new_value) } - Some(raw::fee_change_action::Value::BridgeLockByteCostMultiplier(new_value)) => { - (FeeChange::BridgeLockByteCostMultiplier, new_value) + Some(raw::fee_change::Value::BridgeLockByteCostMultiplier(new_value)) => { + (FeeChangeKind::BridgeLockByteCostMultiplier, new_value) } - Some(raw::fee_change_action::Value::BridgeSudoChangeBaseFee(new_value)) => { - (FeeChange::BridgeSudoChangeBaseFee, new_value) + Some(raw::fee_change::Value::BridgeSudoChangeBaseFee(new_value)) => { + (FeeChangeKind::BridgeSudoChangeBaseFee, new_value) } - Some(raw::fee_change_action::Value::Ics20WithdrawalBaseFee(new_value)) => { - (FeeChange::Ics20WithdrawalBaseFee, new_value) + Some(raw::fee_change::Value::Ics20WithdrawalBaseFee(new_value)) => { + (FeeChangeKind::Ics20WithdrawalBaseFee, new_value) } - None => return Err(FeeChangeActionError::missing_value_to_change()), + None => return Err(FeeChangeError::missing_value_to_change()), }; Ok(Self { @@ -2067,16 +1982,16 @@ impl Protobuf for FeeChangeAction { #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct FeeChangeActionError(FeeChangeActionErrorKind); +pub struct FeeChangeError(FeeChangeErrorKind); -impl FeeChangeActionError { +impl FeeChangeError { fn missing_value_to_change() -> Self { - Self(FeeChangeActionErrorKind::MissingValueToChange) + Self(FeeChangeErrorKind::MissingValueToChange) } } #[derive(Debug, thiserror::Error)] -enum FeeChangeActionErrorKind { +enum FeeChangeErrorKind { #[error("the value which to change was missing")] MissingValueToChange, } diff --git a/crates/astria-core/src/protocol/transaction/v1alpha1/action_group/mod.rs b/crates/astria-core/src/protocol/transaction/v1alpha1/action_group/mod.rs deleted file mode 100644 index fe526a1452..0000000000 --- a/crates/astria-core/src/protocol/transaction/v1alpha1/action_group/mod.rs +++ /dev/null @@ -1,207 +0,0 @@ -#[cfg(test)] -mod tests; - -use std::fmt::{ - self, - Debug, -}; - -use penumbra_ibc::IbcRelay; - -use super::{ - action::{ - ActionName, - BridgeLockAction, - BridgeSudoChangeAction, - BridgeUnlockAction, - FeeAssetChangeAction, - FeeChangeAction, - IbcRelayerChangeAction, - IbcSudoChangeAction, - Ics20Withdrawal, - InitBridgeAccountAction, - SequenceAction, - SudoAddressChangeAction, - TransferAction, - ValidatorUpdate, - }, - Action, -}; - -trait BelongsToGroup { - const GROUP: ActionGroup; -} - -macro_rules! impl_belong_to_group { - ($(($act:ty, $group:expr)),*$(,)?) => { - $( - impl BelongsToGroup for $act { - const GROUP: ActionGroup = $group; - } - )* - } -} - -impl_belong_to_group!( - (SequenceAction, ActionGroup::BundleableGeneral), - (TransferAction, ActionGroup::BundleableGeneral), - (ValidatorUpdate, ActionGroup::BundleableGeneral), - (SudoAddressChangeAction, ActionGroup::UnbundleableSudo), - (IbcRelayerChangeAction, ActionGroup::BundleableSudo), - (Ics20Withdrawal, ActionGroup::BundleableGeneral), - (InitBridgeAccountAction, ActionGroup::UnbundleableGeneral), - (BridgeLockAction, ActionGroup::BundleableGeneral), - (BridgeUnlockAction, ActionGroup::BundleableGeneral), - (BridgeSudoChangeAction, ActionGroup::UnbundleableGeneral), - (FeeChangeAction, ActionGroup::BundleableSudo), - (FeeAssetChangeAction, ActionGroup::BundleableSudo), - (IbcRelay, ActionGroup::BundleableGeneral), - (IbcSudoChangeAction, ActionGroup::UnbundleableSudo), -); - -impl Action { - const fn group(&self) -> ActionGroup { - match self { - Action::Sequence(_) => SequenceAction::GROUP, - Action::Transfer(_) => TransferAction::GROUP, - Action::ValidatorUpdate(_) => ValidatorUpdate::GROUP, - Action::SudoAddressChange(_) => SudoAddressChangeAction::GROUP, - Action::IbcRelayerChange(_) => IbcRelayerChangeAction::GROUP, - Action::Ics20Withdrawal(_) => Ics20Withdrawal::GROUP, - Action::InitBridgeAccount(_) => InitBridgeAccountAction::GROUP, - Action::BridgeLock(_) => BridgeLockAction::GROUP, - Action::BridgeUnlock(_) => BridgeUnlockAction::GROUP, - Action::BridgeSudoChange(_) => BridgeSudoChangeAction::GROUP, - Action::FeeChange(_) => FeeChangeAction::GROUP, - Action::FeeAssetChange(_) => FeeAssetChangeAction::GROUP, - Action::Ibc(_) => IbcRelay::GROUP, - Action::IbcSudoChange(_) => IbcSudoChangeAction::GROUP, - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub(super) enum ActionGroup { - BundleableGeneral, - UnbundleableGeneral, - BundleableSudo, - UnbundleableSudo, -} - -impl ActionGroup { - pub(super) fn is_bundleable(self) -> bool { - matches!( - self, - ActionGroup::BundleableGeneral | ActionGroup::BundleableSudo - ) - } - - pub(super) fn is_bundleable_sudo(self) -> bool { - matches!(self, ActionGroup::BundleableSudo) - } -} - -impl fmt::Display for ActionGroup { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ActionGroup::BundleableGeneral => write!(f, "bundleable general"), - ActionGroup::UnbundleableGeneral => write!(f, "unbundleable general"), - ActionGroup::BundleableSudo => write!(f, "bundleable sudo"), - ActionGroup::UnbundleableSudo => write!(f, "unbundleable sudo"), - } - } -} - -#[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub struct Error(ErrorKind); - -impl Error { - fn mixed( - original_group: ActionGroup, - additional_group: ActionGroup, - action: &'static str, - ) -> Self { - Self(ErrorKind::Mixed { - original_group, - additional_group, - action, - }) - } - - fn not_bundleable(group: ActionGroup) -> Self { - Self(ErrorKind::NotBundleable { - group, - }) - } - - fn empty() -> Self { - Self(ErrorKind::Empty) - } -} - -#[derive(Debug, thiserror::Error)] -enum ErrorKind { - #[error( - "input contains mixed `ActionGroup` types. original group: {original_group}, additional \ - group: {additional_group}, triggering action: {action}" - )] - Mixed { - original_group: ActionGroup, - additional_group: ActionGroup, - action: &'static str, - }, - #[error("attempted to create bundle with non bundleable `ActionGroup` type: {group}")] - NotBundleable { group: ActionGroup }, - #[error("actions cannot be empty")] - Empty, -} - -#[derive(Clone, Debug)] -pub(super) struct Actions { - group: ActionGroup, - inner: Vec, -} - -impl Actions { - pub(super) fn actions(&self) -> &[Action] { - &self.inner - } - - #[must_use] - pub(super) fn into_actions(self) -> Vec { - self.inner - } - - pub(super) fn group(&self) -> ActionGroup { - self.group - } - - pub(super) fn try_from_list_of_actions(actions: Vec) -> Result { - let mut actions_iter = actions.iter(); - let group = match actions_iter.next() { - Some(action) => action.group(), - None => { - // empty `actions` - return Err(Error::empty()); - } - }; - - // assert size constraints on non-bundleable action groups - if actions.len() > 1 && !group.is_bundleable() { - return Err(Error::not_bundleable(group)); - } - - // assert the rest of the actions have the same group as the first - for action in actions_iter { - if action.group() != group { - return Err(Error::mixed(group, action.group(), action.name())); - } - } - - Ok(Self { - group, - inner: actions, - }) - } -} diff --git a/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs b/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs index 457c357c7b..f91de71b22 100644 --- a/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs +++ b/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs @@ -1,11 +1,9 @@ -use action_group::Actions; use bytes::Bytes; use prost::{ Message as _, Name as _, }; -use super::raw; use crate::{ crypto::{ self, @@ -13,6 +11,7 @@ use crate::{ SigningKey, VerificationKey, }, + generated::protocol::transactions::v1alpha1 as raw, primitive::v1::{ asset, TransactionId, @@ -22,8 +21,14 @@ use crate::{ }; pub mod action; -pub mod action_group; -pub use action::Action; +use action::group::Actions; +pub use action::{ + group::{ + Error, + Group, + }, + Action, +}; #[derive(Debug, thiserror::Error)] #[error(transparent)] @@ -178,6 +183,11 @@ impl SignedTransaction { self.transaction.actions.actions() } + #[must_use] + pub fn group(&self) -> Group { + self.transaction.actions.group() + } + #[must_use] pub fn is_bundleable_sudo_action_group(&self) -> bool { self.transaction.actions.group().is_bundleable_sudo() @@ -322,7 +332,7 @@ impl UnsignedTransaction { .chain_id(params.chain_id) .nonce(params.nonce) .try_build() - .map_err(UnsignedTransactionError::action_group) + .map_err(UnsignedTransactionError::group) } /// Attempt to convert from a protobuf [`pbjson_types::Any`]. @@ -347,7 +357,7 @@ impl UnsignedTransaction { pub struct UnsignedTransactionError(UnsignedTransactionErrorKind); impl UnsignedTransactionError { - fn action(inner: action::ActionError) -> Self { + fn action(inner: action::Error) -> Self { Self(UnsignedTransactionErrorKind::Action(inner)) } @@ -365,15 +375,15 @@ impl UnsignedTransactionError { Self(UnsignedTransactionErrorKind::DecodeAny(inner)) } - fn action_group(inner: action_group::Error) -> Self { - Self(UnsignedTransactionErrorKind::ActionGroup(inner)) + fn group(inner: action::group::Error) -> Self { + Self(UnsignedTransactionErrorKind::Group(inner)) } } #[derive(Debug, thiserror::Error)] enum UnsignedTransactionErrorKind { #[error("`actions` field is invalid")] - Action(#[source] action::ActionError), + Action(#[source] action::Error), #[error("`params` field is unset")] UnsetParams(), #[error( @@ -388,7 +398,7 @@ enum UnsignedTransactionErrorKind { )] DecodeAny(#[source] prost::DecodeError), #[error("`actions` field does not form a valid group of actions")] - ActionGroup(#[source] action_group::Error), + Group(#[source] action::group::Error), } #[derive(Default)] @@ -432,11 +442,11 @@ impl UnsignedTransactionBuilder { /// Constructs a [`UnsignedTransaction`] from the configured builder. /// /// # Errors - /// Returns an error if the actions do not make a valid `ActionGroup`. + /// Returns an error if the actions do not make a valid [`action::Group`]. /// /// Returns an error if the set chain ID does not contain a chain name that can be turned into /// a bech32 human readable prefix (everything before the first dash i.e. `-`). - pub fn try_build(self) -> Result { + pub fn try_build(self) -> Result { let Self { nonce, chain_id, @@ -570,7 +580,7 @@ mod tests { use super::*; use crate::{ primitive::v1::Address, - protocol::transaction::v1alpha1::action::TransferAction, + protocol::transaction::v1alpha1::action::Transfer, }; const ASTRIA_ADDRESS_PREFIX: &str = "astria"; @@ -592,7 +602,7 @@ mod tests { 227, 96, 127, 152, 22, 47, 146, 10, ]); - let transfer = TransferAction { + let transfer = Transfer { to: Address::builder() .array([0; 20]) .prefix(ASTRIA_ADDRESS_PREFIX) @@ -627,7 +637,7 @@ mod tests { 178, 63, 69, 238, 27, 96, 95, 213, 135, 120, 87, 106, 196, ]); - let transfer = TransferAction { + let transfer = Transfer { to: Address::builder() .array([0; 20]) .prefix(ASTRIA_ADDRESS_PREFIX) diff --git a/crates/astria-core/src/sequencerblock/v1alpha1/block.rs b/crates/astria-core/src/sequencerblock/v1alpha1/block.rs index bd8a1a4dc8..46fa1eab99 100644 --- a/crates/astria-core/src/sequencerblock/v1alpha1/block.rs +++ b/crates/astria-core/src/sequencerblock/v1alpha1/block.rs @@ -797,7 +797,7 @@ impl SequencerBlock { .map_err(SequencerBlockError::raw_signed_transaction_conversion)?; for action in signed_tx.into_unsigned().into_actions() { // XXX: The fee asset is dropped. We shjould explain why that's ok. - if let action::Action::Sequence(action::SequenceAction { + if let action::Action::Sequence(action::Sequence { rollup_id, data, fee_asset: _, diff --git a/crates/astria-sequencer-client/src/tests/http.rs b/crates/astria-sequencer-client/src/tests/http.rs index c23f14b1d1..a1223b9e75 100644 --- a/crates/astria-sequencer-client/src/tests/http.rs +++ b/crates/astria-sequencer-client/src/tests/http.rs @@ -5,7 +5,7 @@ use astria_core::{ generated::protocol::asset::v1alpha1::AllowedFeeAssetsResponse, primitive::v1::Address, protocol::transaction::v1alpha1::{ - action::TransferAction, + action::Transfer, SignedTransaction, UnsignedTransaction, }, @@ -148,7 +148,7 @@ fn create_signed_transaction() -> SignedTransaction { let alice_key = SigningKey::from(alice_secret_bytes); let actions = vec![ - TransferAction { + Transfer { to: bob_address(), amount: 333_333, asset: "nria".parse().unwrap(), diff --git a/crates/astria-sequencer/Cargo.toml b/crates/astria-sequencer/Cargo.toml index a31c86ac27..5f5f2cec24 100644 --- a/crates/astria-sequencer/Cargo.toml +++ b/crates/astria-sequencer/Cargo.toml @@ -47,6 +47,7 @@ tower-actor = "0.1.0" tower-http = { version = "0.4", features = ["cors"] } async-trait = { workspace = true } +base64 = { workspace = true } bytes = { workspace = true } divan = { workspace = true, optional = true } futures = { workspace = true } diff --git a/crates/astria-sequencer/local.env.example b/crates/astria-sequencer/local.env.example index 05cb7937a0..eaee8c607d 100644 --- a/crates/astria-sequencer/local.env.example +++ b/crates/astria-sequencer/local.env.example @@ -10,6 +10,9 @@ ASTRIA_SEQUENCER_DB_FILEPATH="/tmp/astria_db" # Only used if the "mint" feature is enabled ASTRIA_SEQUENCER_ENABLE_MINT=false +# Set size of mempool's parked container +ASTRIA_SEQUENCER_MEMPOOL_PARKED_MAX_TX_COUNT=200 + # Socket address for gRPC server ASTRIA_SEQUENCER_GRPC_ADDR="127.0.0.1:8080" # Log level for the sequencer diff --git a/crates/astria-sequencer/src/accounts/action.rs b/crates/astria-sequencer/src/accounts/action.rs index b02a77c1de..32b2a482b0 100644 --- a/crates/astria-sequencer/src/accounts/action.rs +++ b/crates/astria-sequencer/src/accounts/action.rs @@ -1,7 +1,4 @@ -use astria_core::{ - protocol::transaction::v1alpha1::action::TransferAction, - Protobuf as _, -}; +use astria_core::protocol::transaction::v1alpha1::action::Transfer; use astria_eyre::eyre::{ ensure, OptionExt as _, @@ -30,7 +27,7 @@ use crate::{ }; #[async_trait::async_trait] -impl ActionHandler for TransferAction { +impl ActionHandler for Transfer { async fn check_stateless(&self) -> Result<()> { Ok(()) } @@ -58,7 +55,7 @@ impl ActionHandler for TransferAction { } pub(crate) async fn execute_transfer( - action: &TransferAction, + action: &Transfer, from: &TAddress, mut state: S, ) -> Result<()> @@ -71,7 +68,7 @@ where .await .wrap_err("failed to get transfer base fee")?; state - .get_and_increase_block_fees(&action.fee_asset, fee, TransferAction::full_name()) + .get_and_increase_block_fees::(&action.fee_asset, fee) .await .wrap_err("failed to add to block fees")?; @@ -114,7 +111,7 @@ where } pub(crate) async fn check_transfer( - action: &TransferAction, + action: &Transfer, from: &TAddress, state: &S, ) -> Result<()> diff --git a/crates/astria-sequencer/src/accounts/snapshots/astria_sequencer__accounts__state_ext__tests__storage_keys_have_not_changed-2.snap b/crates/astria-sequencer/src/accounts/snapshots/astria_sequencer__accounts__state_ext__tests__storage_keys_have_not_changed-2.snap deleted file mode 100644 index 9b2ee0652b..0000000000 --- a/crates/astria-sequencer/src/accounts/snapshots/astria_sequencer__accounts__state_ext__tests__storage_keys_have_not_changed-2.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: crates/astria-sequencer/src/accounts/state_ext.rs -assertion_line: 855 -expression: nonce_storage_key(&address) ---- -accounts/1c0c490f1b5528d8173c5de46d131160e4b2c0c3/nonce diff --git a/crates/astria-sequencer/src/accounts/snapshots/astria_sequencer__accounts__state_ext__tests__storage_keys_have_not_changed.snap b/crates/astria-sequencer/src/accounts/snapshots/astria_sequencer__accounts__state_ext__tests__storage_keys_have_not_changed.snap deleted file mode 100644 index 9125e1ba51..0000000000 --- a/crates/astria-sequencer/src/accounts/snapshots/astria_sequencer__accounts__state_ext__tests__storage_keys_have_not_changed.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: crates/astria-sequencer/src/accounts/state_ext.rs -assertion_line: 854 -expression: "balance_storage_key(&address, &asset)" ---- -accounts/1c0c490f1b5528d8173c5de46d131160e4b2c0c3/balance/be429a02d00837245167a2616674a979a2ac6f9806468b48a975b156ad711320 diff --git a/crates/astria-sequencer/src/accounts/state_ext.rs b/crates/astria-sequencer/src/accounts/state_ext.rs index 1aca12616c..5348d0ee2d 100644 --- a/crates/astria-sequencer/src/accounts/state_ext.rs +++ b/crates/astria-sequencer/src/accounts/state_ext.rs @@ -1,4 +1,5 @@ use std::{ + borrow::Cow, fmt::Display, pin::Pin, task::{ @@ -27,44 +28,18 @@ use futures::Stream; use pin_project_lite::pin_project; use tracing::instrument; -use super::storage; +use super::storage::{ + self, + keys::{ + self, + extract_asset_from_key, + }, +}; use crate::{ accounts::AddressBytes, storage::StoredValue, }; -const ACCOUNTS_PREFIX: &str = "accounts"; -const TRANSFER_BASE_FEE_STORAGE_KEY: &str = "transferfee"; - -struct StorageKey<'a, T>(&'a T); -impl<'a, T: AddressBytes> std::fmt::Display for StorageKey<'a, T> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(ACCOUNTS_PREFIX)?; - f.write_str("/")?; - for byte in self.0.address_bytes() { - f.write_fmt(format_args!("{byte:02x}"))?; - } - Ok(()) - } -} - -fn balance_storage_key<'a, TAddress, TAsset>(address: &TAddress, asset: &'a TAsset) -> String -where - TAddress: AddressBytes, - asset::IbcPrefixed: From<&'a TAsset>, -{ - let asset: asset::IbcPrefixed = asset.into(); - format!( - "{}/balance/{}", - StorageKey(address), - crate::storage_keys::hunks::Asset::from(asset) - ) -} - -fn nonce_storage_key(address: &T) -> String { - format!("{}/nonce", StorageKey(address)) -} - pin_project! { /// A stream of IBC prefixed assets for a given account. pub(crate) struct AccountAssetsStream { @@ -141,15 +116,6 @@ where } } -fn extract_asset_from_key(s: &str) -> Result { - Ok(s.strip_prefix("accounts/") - .and_then(|s| s.split_once("/balance/").map(|(_, asset)| asset)) - .ok_or_eyre("failed to strip prefix from account balance key")? - .parse::() - .context("failed to parse storage key suffix as address hunk")? - .get()) -} - #[async_trait] pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt { #[instrument(skip_all)] @@ -157,7 +123,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt { &self, address: &T, ) -> AccountAssetsStream { - let prefix = format!("{}/balance/", StorageKey(address)); + let prefix = keys::balance_prefix(address); AccountAssetsStream { underlying: self.prefix_keys(&prefix), } @@ -168,7 +134,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt { &self, address: &T, ) -> AccountAssetBalancesStream { - let prefix = format!("{}/balance/", StorageKey(address)); + let prefix = keys::balance_prefix(address); AccountAssetBalancesStream { underlying: self.prefix_raw(&prefix), } @@ -183,10 +149,10 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt { where TAddress: AddressBytes, TAsset: Sync + Display, - asset::IbcPrefixed: From<&'a TAsset> + Send + Sync, + &'a TAsset: Into>, { let Some(bytes) = self - .get_raw(&balance_storage_key(address, asset)) + .get_raw(&keys::balance(address, asset)) .await .map_err(anyhow_to_eyre) .wrap_err("failed reading raw account balance from state")? @@ -201,7 +167,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt { #[instrument(skip_all)] async fn get_account_nonce(&self, address: &T) -> Result { let bytes = self - .get_raw(&nonce_storage_key(address)) + .get_raw(&keys::nonce(address)) .await .map_err(anyhow_to_eyre) .wrap_err("failed reading raw account nonce from state")?; @@ -217,7 +183,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt { #[instrument(skip_all)] async fn get_transfer_base_fee(&self) -> Result { let bytes = self - .get_raw(TRANSFER_BASE_FEE_STORAGE_KEY) + .get_raw(keys::TRANSFER_BASE_FEE) .await .map_err(anyhow_to_eyre) .wrap_err("failed reading raw transfer base fee from state")?; @@ -244,12 +210,12 @@ pub(crate) trait StateWriteExt: StateWrite { where TAddress: AddressBytes, TAsset: Display, - asset::IbcPrefixed: From<&'a TAsset> + Send, + &'a TAsset: Into>, { let bytes = StoredValue::from(storage::Balance::from(balance)) .serialize() .wrap_err("failed to serialize balance")?; - self.put_raw(balance_storage_key(address, asset), bytes); + self.put_raw(keys::balance(address, asset), bytes); Ok(()) } @@ -258,7 +224,7 @@ pub(crate) trait StateWriteExt: StateWrite { let bytes = StoredValue::from(storage::Nonce::from(nonce)) .serialize() .wrap_err("failed to serialize nonce")?; - self.put_raw(nonce_storage_key(address), bytes); + self.put_raw(keys::nonce(address), bytes); Ok(()) } @@ -272,7 +238,7 @@ pub(crate) trait StateWriteExt: StateWrite { where TAddress: AddressBytes, TAsset: Sync + Display, - asset::IbcPrefixed: From<&'a TAsset> + Send, + &'a TAsset: Into>, { let balance = self .get_account_balance(address, asset) @@ -299,7 +265,7 @@ pub(crate) trait StateWriteExt: StateWrite { where TAddress: AddressBytes, TAsset: Sync + Display, - asset::IbcPrefixed: From<&'a TAsset> + Send, + &'a TAsset: Into>, { let balance = self .get_account_balance(address, asset) @@ -321,7 +287,7 @@ pub(crate) trait StateWriteExt: StateWrite { let bytes = StoredValue::from(storage::Fee::from(fee)) .serialize() .wrap_err("failed to serialize fee")?; - self.put_raw(TRANSFER_BASE_FEE_STORAGE_KEY.to_string(), bytes); + self.put_raw(keys::TRANSFER_BASE_FEE.to_string(), bytes); Ok(()) } } @@ -330,17 +296,10 @@ impl StateWriteExt for T {} #[cfg(test)] mod tests { - use astria_core::primitive::v1::Address; use cnidarium::StateDelta; use futures::TryStreamExt as _; - use insta::assert_snapshot; - use super::{ - balance_storage_key, - nonce_storage_key, - StateReadExt as _, - StateWriteExt as _, - }; + use super::*; use crate::{ assets::{ StateReadExt as _, @@ -352,14 +311,15 @@ mod tests { }, }; - fn asset_0() -> astria_core::primitive::v1::asset::Denom { + fn asset_0() -> asset::Denom { "asset_0".parse().unwrap() } - fn asset_1() -> astria_core::primitive::v1::asset::Denom { + fn asset_1() -> asset::Denom { "asset_1".parse().unwrap() } - fn asset_2() -> astria_core::primitive::v1::asset::Denom { + + fn asset_2() -> asset::Denom { "asset_2".parse().unwrap() } @@ -834,20 +794,4 @@ mod tests { let retrieved_fee = state.get_transfer_base_fee().await.unwrap(); assert_eq!(retrieved_fee, 123); } - - #[test] - fn storage_keys_have_not_changed() { - let address: Address = "astria1rsxyjrcm255ds9euthjx6yc3vrjt9sxrm9cfgm" - .parse() - .unwrap(); - let asset = "an/asset/with/a/prefix" - .parse::() - .unwrap(); - assert_eq!( - balance_storage_key(&address, &asset), - balance_storage_key(&address, &asset.to_ibc_prefixed()) - ); - assert_snapshot!(balance_storage_key(&address, &asset)); - assert_snapshot!(nonce_storage_key(&address)); - } } diff --git a/crates/astria-sequencer/src/accounts/storage/keys.rs b/crates/astria-sequencer/src/accounts/storage/keys.rs new file mode 100644 index 0000000000..e23e368bcf --- /dev/null +++ b/crates/astria-sequencer/src/accounts/storage/keys.rs @@ -0,0 +1,113 @@ +use std::borrow::Cow; + +use astria_core::primitive::v1::asset::IbcPrefixed; +use astria_eyre::eyre::{ + OptionExt as _, + Result, + WrapErr as _, +}; + +use crate::{ + accounts::AddressBytes, + storage::keys::{ + AccountPrefixer, + Asset, + }, +}; + +pub(in crate::accounts) const TRANSFER_BASE_FEE: &str = "accounts/transfer_base_fee"; +const COMPONENT_PREFIX: &str = "accounts/"; +const BALANCE_PREFIX: &str = "balance/"; +const NONCE: &str = "nonce"; + +/// Example: `accounts/gGhH....zZ4=/balance/`. +/// |base64 chars| +pub(in crate::accounts) fn balance_prefix(address: &TAddress) -> String { + format!( + "{}/{BALANCE_PREFIX}", + AccountPrefixer::new(COMPONENT_PREFIX, address) + ) +} + +/// Example: `accounts/gGhH....zZ4=/balance/0202....0202`. +/// |base64 chars| |64 hex chars| +pub(in crate::accounts) fn balance<'a, TAddress, TAsset>( + address: &TAddress, + asset: &'a TAsset, +) -> String +where + TAddress: AddressBytes, + &'a TAsset: Into>, +{ + format!( + "{}/{BALANCE_PREFIX}{}", + AccountPrefixer::new(COMPONENT_PREFIX, address), + Asset::from(asset) + ) +} + +/// Example: `accounts/gGhH....zZ4=/nonce`. +/// |base64 chars| +pub(in crate::accounts) fn nonce(address: &TAddress) -> String { + format!( + "{}/{NONCE}", + AccountPrefixer::new(COMPONENT_PREFIX, address) + ) +} + +pub(in crate::accounts) fn extract_asset_from_key(key: &str) -> Result { + Ok(key + .strip_prefix(COMPONENT_PREFIX) + .and_then(|s| s.split_once(BALANCE_PREFIX).map(|(_, asset)| asset)) + .ok_or_eyre("failed to strip prefix from account balance key")? + .parse::() + .wrap_err("failed to parse storage key suffix as address hunk")? + .get()) +} + +#[cfg(test)] +mod tests { + use astria_core::primitive::v1::{ + asset::Denom, + Address, + }; + + use super::*; + + fn address() -> Address { + "astria1rsxyjrcm255ds9euthjx6yc3vrjt9sxrm9cfgm" + .parse() + .unwrap() + } + + fn asset() -> Denom { + "an/asset/with/a/prefix".parse().unwrap() + } + + #[test] + fn keys_should_not_change() { + insta::assert_snapshot!(TRANSFER_BASE_FEE); + insta::assert_snapshot!(balance(&address(), &asset())); + insta::assert_snapshot!(nonce(&address())); + } + + #[test] + fn keys_should_have_component_prefix() { + assert!(TRANSFER_BASE_FEE.starts_with(COMPONENT_PREFIX)); + assert!(balance(&address(), &asset()).starts_with(COMPONENT_PREFIX)); + assert!(nonce(&address()).starts_with(COMPONENT_PREFIX)); + } + + #[test] + fn balance_prefix_should_be_prefix_of_balance_key() { + assert!(balance(&address(), &asset()).starts_with(&balance_prefix(&address()))); + } + + #[test] + fn should_extract_asset_from_key() { + let asset = IbcPrefixed::new([2; 32]); + let key = balance(&[1; 20], &asset); + let recovered_asset = extract_asset_from_key(&key).unwrap(); + assert_eq!(asset, recovered_asset); + } +} diff --git a/crates/astria-sequencer/src/accounts/storage/mod.rs b/crates/astria-sequencer/src/accounts/storage/mod.rs index 5fb23de750..8d61ec9f93 100644 --- a/crates/astria-sequencer/src/accounts/storage/mod.rs +++ b/crates/astria-sequencer/src/accounts/storage/mod.rs @@ -1,3 +1,4 @@ +pub(super) mod keys; mod values; pub(crate) use values::Value; diff --git a/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change-2.snap b/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change-2.snap new file mode 100644 index 0000000000..f3ff1952e1 --- /dev/null +++ b/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change-2.snap @@ -0,0 +1,6 @@ +--- +source: crates/astria-sequencer/src/accounts/storage/keys.rs +assertion_line: 90 +expression: "balance(&address(), &asset())" +--- +accounts/HAxJDxtVKNgXPF3kbRMRYOSywMM=/balance/ibc/be429a02d00837245167a2616674a979a2ac6f9806468b48a975b156ad711320 diff --git a/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change-3.snap b/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change-3.snap new file mode 100644 index 0000000000..6febfe41e9 --- /dev/null +++ b/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change-3.snap @@ -0,0 +1,6 @@ +--- +source: crates/astria-sequencer/src/accounts/storage/keys.rs +assertion_line: 91 +expression: nonce(&address()) +--- +accounts/HAxJDxtVKNgXPF3kbRMRYOSywMM=/nonce diff --git a/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change.snap b/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change.snap new file mode 100644 index 0000000000..a57562a2da --- /dev/null +++ b/crates/astria-sequencer/src/accounts/storage/snapshots/astria_sequencer__accounts__storage__keys__tests__keys_should_not_change.snap @@ -0,0 +1,6 @@ +--- +source: crates/astria-sequencer/src/accounts/storage/keys.rs +assertion_line: 79 +expression: TRANSFER_BASE_FEE_KEY +--- +accounts/transfer_base_fee diff --git a/crates/astria-sequencer/src/address/state_ext.rs b/crates/astria-sequencer/src/address/state_ext.rs index a0c074777b..0f5cd5bf30 100644 --- a/crates/astria-sequencer/src/address/state_ext.rs +++ b/crates/astria-sequencer/src/address/state_ext.rs @@ -18,12 +18,12 @@ use cnidarium::{ }; use tracing::instrument; -use super::storage; +use super::storage::{ + self, + keys, +}; use crate::storage::StoredValue; -const BASE_PREFIX_KEY: &str = "prefixes/base"; -const IBC_COMPAT_PREFIX_KEY: &str = "prefixes/ibc-compat"; - #[async_trait] pub(crate) trait StateReadExt: StateRead { async fn ensure_base_prefix(&self, address: &Address) -> Result<()> { @@ -54,7 +54,7 @@ pub(crate) trait StateReadExt: StateRead { #[instrument(skip_all, err)] async fn get_base_prefix(&self) -> Result { let Some(bytes) = self - .get_raw(BASE_PREFIX_KEY) + .get_raw(keys::BASE_PREFIX) .await .map_err(anyhow_to_eyre) .wrap_err("failed reading address base prefix from state")? @@ -69,7 +69,7 @@ pub(crate) trait StateReadExt: StateRead { #[instrument(skip_all, err)] async fn get_ibc_compat_prefix(&self) -> Result { let Some(bytes) = self - .get_raw(IBC_COMPAT_PREFIX_KEY) + .get_raw(keys::IBC_COMPAT_PREFIX) .await .map_err(anyhow_to_eyre) .wrap_err("failed reading address ibc compat prefix from state")? @@ -91,7 +91,7 @@ pub(crate) trait StateWriteExt: StateWrite { let bytes = StoredValue::from(storage::AddressPrefix::from(prefix.as_str())) .serialize() .context("failed to serialize base prefix")?; - self.put_raw(BASE_PREFIX_KEY.to_string(), bytes); + self.put_raw(keys::BASE_PREFIX.to_string(), bytes); Ok(()) } @@ -100,7 +100,7 @@ pub(crate) trait StateWriteExt: StateWrite { let bytes = StoredValue::from(storage::AddressPrefix::from(prefix.as_str())) .serialize() .context("failed to serialize ibc-compat prefix")?; - self.put_raw(IBC_COMPAT_PREFIX_KEY.to_string(), bytes); + self.put_raw(keys::IBC_COMPAT_PREFIX.to_string(), bytes); Ok(()) } } @@ -111,10 +111,7 @@ impl StateWriteExt for T {} mod tests { use cnidarium::StateDelta; - use super::{ - StateReadExt as _, - StateWriteExt as _, - }; + use super::*; #[tokio::test] async fn put_and_get_base_prefix() { diff --git a/crates/astria-sequencer/src/address/storage/keys.rs b/crates/astria-sequencer/src/address/storage/keys.rs new file mode 100644 index 0000000000..af58a1d79f --- /dev/null +++ b/crates/astria-sequencer/src/address/storage/keys.rs @@ -0,0 +1,21 @@ +pub(in crate::address) const BASE_PREFIX: &str = "address/prefixes/base"; +pub(in crate::address) const IBC_COMPAT_PREFIX: &str = "address/prefixes/ibc_compat"; + +#[cfg(test)] +mod tests { + use super::*; + + const COMPONENT_PREFIX: &str = "address/"; + + #[test] + fn keys_should_not_change() { + insta::assert_snapshot!(BASE_PREFIX); + insta::assert_snapshot!(IBC_COMPAT_PREFIX); + } + + #[test] + fn keys_should_have_component_prefix() { + assert!(BASE_PREFIX.starts_with(COMPONENT_PREFIX)); + assert!(IBC_COMPAT_PREFIX.starts_with(COMPONENT_PREFIX)); + } +} diff --git a/crates/astria-sequencer/src/address/storage/mod.rs b/crates/astria-sequencer/src/address/storage/mod.rs index 9d97b02d12..66527bffe6 100644 --- a/crates/astria-sequencer/src/address/storage/mod.rs +++ b/crates/astria-sequencer/src/address/storage/mod.rs @@ -1,3 +1,4 @@ +pub(super) mod keys; mod values; pub(super) use values::AddressPrefix; diff --git a/crates/astria-sequencer/src/address/storage/snapshots/astria_sequencer__address__storage__keys__tests__keys_should_not_change-2.snap b/crates/astria-sequencer/src/address/storage/snapshots/astria_sequencer__address__storage__keys__tests__keys_should_not_change-2.snap new file mode 100644 index 0000000000..78e5051afb --- /dev/null +++ b/crates/astria-sequencer/src/address/storage/snapshots/astria_sequencer__address__storage__keys__tests__keys_should_not_change-2.snap @@ -0,0 +1,6 @@ +--- +source: crates/astria-sequencer/src/address/storage/keys.rs +assertion_line: 11 +expression: IBC_COMPAT_PREFIX_KEY +--- +address/prefixes/ibc_compat diff --git a/crates/astria-sequencer/src/address/storage/snapshots/astria_sequencer__address__storage__keys__tests__keys_should_not_change.snap b/crates/astria-sequencer/src/address/storage/snapshots/astria_sequencer__address__storage__keys__tests__keys_should_not_change.snap new file mode 100644 index 0000000000..d0121e06ae --- /dev/null +++ b/crates/astria-sequencer/src/address/storage/snapshots/astria_sequencer__address__storage__keys__tests__keys_should_not_change.snap @@ -0,0 +1,6 @@ +--- +source: crates/astria-sequencer/src/address/storage/keys.rs +assertion_line: 10 +expression: BASE_PREFIX_KEY +--- +address/prefixes/base diff --git a/crates/astria-sequencer/src/app/mod.rs b/crates/astria-sequencer/src/app/mod.rs index 688c6c1ece..935b11fabd 100644 --- a/crates/astria-sequencer/src/app/mod.rs +++ b/crates/astria-sequencer/src/app/mod.rs @@ -10,6 +10,8 @@ mod tests_app; #[cfg(test)] mod tests_block_fees; #[cfg(test)] +mod tests_block_ordering; +#[cfg(test)] mod tests_breaking_changes; #[cfg(test)] mod tests_execute_transaction; @@ -25,7 +27,10 @@ use astria_core::{ abci::AbciErrorCode, genesis::v1alpha1::GenesisAppState, transaction::v1alpha1::{ - action::ValidatorUpdate, + action::{ + group::Group, + ValidatorUpdate, + }, Action, SignedTransaction, }, @@ -543,6 +548,7 @@ impl App { let mut failed_tx_count: usize = 0; let mut execution_results = Vec::new(); let mut excluded_txs: usize = 0; + let mut current_tx_group = Group::BundleableGeneral; // get copy of transactions to execute from mempool let pending_txs = self @@ -598,6 +604,20 @@ impl App { continue; } + // ensure transaction's group is less than or equal to current action group + let tx_group = tx.group(); + if tx_group > current_tx_group { + debug!( + transaction_hash = %tx_hash_base64, + block_size_constraints = %json(&block_size_constraints), + "excluding transaction: group is higher priority than previously included transactions" + ); + excluded_txs = excluded_txs.saturating_add(1); + + // note: we don't remove the tx from mempool as it may be valid in the future + continue; + } + // execute tx and store in `execution_results` list on success match self.execute_transaction(tx.clone()).await { Ok(events) => { @@ -628,6 +648,12 @@ impl App { // due to an invalid nonce, as it may be valid in the future. // if it's invalid due to the nonce being too low, it'll be // removed from the mempool in `update_mempool_after_finalization`. + // + // this is important for possible out-of-order transaction + // groups fed into prepare_proposal. a transaction with a higher + // nonce might be in a higher priority group than a transaction + // from the same account wiht a lower nonce. this higher nonce + // could execute in the next block fine. } else { failed_tx_count = failed_tx_count.saturating_add(1); @@ -645,6 +671,9 @@ impl App { } } } + + // update current action group to tx's action group + current_tx_group = tx_group; } if failed_tx_count > 0 { @@ -692,8 +721,8 @@ impl App { txs: Vec, block_size_constraints: &mut BlockSizeConstraints, ) -> Result> { - let mut excluded_tx_count = 0u32; let mut execution_results = Vec::new(); + let mut current_tx_group = Group::BundleableGeneral; for tx in txs { let bytes = tx.to_raw().encode_to_vec(); @@ -713,10 +742,19 @@ impl App { transaction_hash = %telemetry::display::base64(&tx_hash), block_size_constraints = %json(&block_size_constraints), tx_data_bytes = tx_sequence_data_bytes, - "excluding transaction: max block sequenced data limit reached" + "transaction error: max block sequenced data limit passed" ); - excluded_tx_count = excluded_tx_count.saturating_add(1); - continue; + bail!("max block sequenced data limit passed"); + } + + // ensure transaction's group is less than or equal to current action group + let tx_group = tx.group(); + if tx_group > current_tx_group { + debug!( + transaction_hash = %telemetry::display::base64(&tx_hash), + "transaction error: block has incorrect transaction group ordering" + ); + bail!("transactions have incorrect transaction group ordering"); } // execute tx and store in `execution_results` list on success @@ -737,19 +775,14 @@ impl App { debug!( transaction_hash = %telemetry::display::base64(&tx_hash), error = AsRef::::as_ref(&e), - "failed to execute transaction, not including in block" + "transaction error: failed to execute transaction" ); - excluded_tx_count = excluded_tx_count.saturating_add(1); + bail!("transaction failed to execute"); } } - } - if excluded_tx_count > 0 { - info!( - excluded_tx_count = excluded_tx_count, - included_tx_count = execution_results.len(), - "excluded transactions from block" - ); + // update current action group to tx's action group + current_tx_group = tx_group; } Ok(execution_results) diff --git a/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_execute_transaction_with_every_action_snapshot.snap b/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_execute_transaction_with_every_action_snapshot.snap index ce1e424533..00738ae01d 100644 --- a/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_execute_transaction_with_every_action_snapshot.snap +++ b/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_execute_transaction_with_every_action_snapshot.snap @@ -4,36 +4,36 @@ assertion_line: 350 expression: app.app_hash.as_bytes() --- [ - 152, - 102, + 65, + 106, + 222, + 239, + 12, 37, - 231, - 116, + 108, + 130, 83, - 54, - 99, - 99, - 61, + 78, + 58, + 50, + 178, + 164, + 93, + 245, 18, - 167, - 133, - 246, - 157, - 153, - 240, 12, - 160, - 204, - 116, - 164, - 109, - 125, - 163, - 141, - 253, - 161, - 54, - 116, - 76, - 131 + 205, + 129, + 14, + 158, + 134, + 107, + 50, + 190, + 88, + 71, + 110, + 9, + 148, + 233 ] diff --git a/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_finalize_block_snapshot.snap b/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_finalize_block_snapshot.snap index 991e89c41c..e36d49f879 100644 --- a/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_finalize_block_snapshot.snap +++ b/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_finalize_block_snapshot.snap @@ -1,39 +1,39 @@ --- source: crates/astria-sequencer/src/app/tests_breaking_changes.rs -assertion_line: 159 +assertion_line: 157 expression: app.app_hash.as_bytes() --- [ - 185, - 5, - 77, - 15, - 122, - 4, - 105, + 65, + 14, + 103, + 92, + 219, + 56, + 251, + 135, + 182, + 207, + 215, + 245, + 234, + 148, + 33, 34, - 166, - 43, - 138, - 143, - 70, - 189, - 121, - 106, - 150, - 128, - 112, + 179, + 40, + 146, + 17, + 236, + 227, + 125, + 197, + 76, 142, - 173, - 98, - 148, - 152, - 2, - 3, - 100, - 153, - 98, - 154, - 77, - 199 + 194, + 180, + 9, + 157, + 73, + 63 ] diff --git a/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_genesis_snapshot.snap b/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_genesis_snapshot.snap index 30a896d96f..d1fd6ce989 100644 --- a/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_genesis_snapshot.snap +++ b/crates/astria-sequencer/src/app/snapshots/astria_sequencer__app__tests_breaking_changes__app_genesis_snapshot.snap @@ -1,39 +1,39 @@ --- source: crates/astria-sequencer/src/app/tests_breaking_changes.rs -assertion_line: 78 +assertion_line: 77 expression: app.app_hash.as_bytes() --- [ - 216, - 255, - 55, - 240, + 66, + 163, + 122, 253, - 150, - 85, - 195, - 135, - 107, - 242, - 140, - 90, - 79, - 175, - 169, - 15, - 89, - 132, 159, - 196, - 65, - 113, - 174, - 207, - 46, - 107, - 126, - 6, + 247, + 85, + 105, + 254, + 245, + 230, + 91, + 25, + 173, + 179, + 227, + 231, + 2, + 69, + 165, 1, - 239, - 84 + 169, + 100, + 210, + 97, + 33, + 91, + 87, + 140, + 222, + 83, + 57 ] diff --git a/crates/astria-sequencer/src/app/state_ext.rs b/crates/astria-sequencer/src/app/state_ext.rs index cd51110c84..b9a2e3b78e 100644 --- a/crates/astria-sequencer/src/app/state_ext.rs +++ b/crates/astria-sequencer/src/app/state_ext.rs @@ -14,24 +14,18 @@ use cnidarium::{ use tendermint::Time; use tracing::instrument; -use super::storage; +use super::storage::{ + self, + keys, +}; use crate::storage::StoredValue; -const CHAIN_ID_KEY: &str = "chain_id"; -const REVISION_NUMBER_KEY: &str = "revision_number"; -const BLOCK_HEIGHT_KEY: &str = "block_height"; -const BLOCK_TIMESTAMP_KEY: &str = "block_timestamp"; - -fn storage_version_by_height_key(height: u64) -> Vec { - format!("storage_version/{height}").into() -} - #[async_trait] pub(crate) trait StateReadExt: StateRead { #[instrument(skip_all)] async fn get_chain_id(&self) -> Result { let Some(bytes) = self - .get_raw(CHAIN_ID_KEY) + .get_raw(keys::CHAIN_ID) .await .map_err(anyhow_to_eyre) .wrap_err("failed to read raw chain_id from state")? @@ -46,7 +40,7 @@ pub(crate) trait StateReadExt: StateRead { #[instrument(skip_all)] async fn get_revision_number(&self) -> Result { let Some(bytes) = self - .get_raw(REVISION_NUMBER_KEY) + .get_raw(keys::REVISION_NUMBER) .await .map_err(anyhow_to_eyre) .wrap_err("failed to read raw revision number from state")? @@ -61,7 +55,7 @@ pub(crate) trait StateReadExt: StateRead { #[instrument(skip_all)] async fn get_block_height(&self) -> Result { let Some(bytes) = self - .get_raw(BLOCK_HEIGHT_KEY) + .get_raw(keys::BLOCK_HEIGHT) .await .map_err(anyhow_to_eyre) .wrap_err("failed to read raw block_height from state")? @@ -76,7 +70,7 @@ pub(crate) trait StateReadExt: StateRead { #[instrument(skip_all)] async fn get_block_timestamp(&self) -> Result