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 index e39971d95..fe526a145 100644 --- a/crates/astria-core/src/protocol/transaction/v1alpha1/action_group/mod.rs +++ b/crates/astria-core/src/protocol/transaction/v1alpha1/action_group/mod.rs @@ -134,6 +134,10 @@ impl Error { group, }) } + + fn empty() -> Self { + Self(ErrorKind::Empty) + } } #[derive(Debug, thiserror::Error)] @@ -149,10 +153,13 @@ enum ErrorKind { }, #[error("attempted to create bundle with non bundleable `ActionGroup` type: {group}")] NotBundleable { group: ActionGroup }, + #[error("actions cannot be empty")] + Empty, } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(super) struct Actions { + group: ActionGroup, inner: Vec, } @@ -166,8 +173,8 @@ impl Actions { self.inner } - pub(super) fn group(&self) -> Option { - self.inner.first().map(super::action::Action::group) + pub(super) fn group(&self) -> ActionGroup { + self.group } pub(super) fn try_from_list_of_actions(actions: Vec) -> Result { @@ -176,7 +183,7 @@ impl Actions { Some(action) => action.group(), None => { // empty `actions` - return Ok(Self::default()); + return Err(Error::empty()); } }; @@ -193,6 +200,7 @@ impl Actions { } 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 index 6aa2afb35..71169c6a6 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 @@ -92,7 +92,7 @@ fn try_from_list_of_actions_bundleable_general() { assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - Some(ActionGroup::BundleableGeneral) + ActionGroup::BundleableGeneral )); } @@ -116,7 +116,7 @@ fn from_list_of_actions_bundleable_sudo() { assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - Some(ActionGroup::BundleableSudo) + ActionGroup::BundleableSudo )); } @@ -134,7 +134,7 @@ fn from_list_of_actions_unbundleable_sudo() { assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - Some(ActionGroup::UnbundleableSudo) + ActionGroup::UnbundleableSudo )); let actions = vec![Action::IbcSudoChange(IbcSudoChangeAction { @@ -143,7 +143,7 @@ fn from_list_of_actions_unbundleable_sudo() { assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - Some(ActionGroup::UnbundleableSudo) + ActionGroup::UnbundleableSudo )); let actions = vec![ @@ -191,14 +191,14 @@ fn from_list_of_actions_unbundleable_general() { assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - Some(ActionGroup::UnbundleableGeneral) + ActionGroup::UnbundleableGeneral )); let actions = vec![sudo_bridge_address_change_action.clone().into()]; assert!(matches!( Actions::try_from_list_of_actions(actions).unwrap().group(), - Some(ActionGroup::UnbundleableGeneral) + ActionGroup::UnbundleableGeneral )); let actions = vec![ @@ -239,3 +239,12 @@ fn from_list_of_actions_mixed() { "expected ErrorKind::Mixed, got {error_kind:?}" ); } + +#[test] +fn from_list_of_actions_empty() { + let error_kind = Actions::try_from_list_of_actions(vec![]).unwrap_err().0; + assert!( + matches!(error_kind, ErrorKind::Empty { .. }), + "expected ErrorKind::Empty, got {error_kind:?}" + ); +} diff --git a/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs b/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs index c47c6ac68..457c357c7 100644 --- a/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs +++ b/crates/astria-core/src/protocol/transaction/v1alpha1/mod.rs @@ -180,11 +180,7 @@ impl SignedTransaction { #[must_use] pub fn is_bundleable_sudo_action_group(&self) -> bool { - if let Some(group) = self.transaction.actions.group() { - group.is_bundleable_sudo() - } else { - false - } + self.transaction.actions.group().is_bundleable_sudo() } #[must_use]