diff --git a/crates/astria-core/src/sequencer.rs b/crates/astria-core/src/sequencer.rs
index 940b67c99..4138e96b6 100644
--- a/crates/astria-core/src/sequencer.rs
+++ b/crates/astria-core/src/sequencer.rs
@@ -2,7 +2,10 @@
pub use penumbra_ibc::params::IBCParameters;
use crate::primitive::v1::{
- asset,
+ asset::{
+ self,
+ TracePrefixed,
+ },
Address,
};
@@ -26,7 +29,7 @@ pub struct GenesisState {
authority_sudo_address: Address,
ibc_sudo_address: Address,
ibc_relayer_addresses: Vec
,
- native_asset_base_denomination: String,
+ native_asset_base_denomination: TracePrefixed,
ibc_params: IBCParameters,
allowed_fee_assets: Vec,
fees: Fees,
@@ -59,7 +62,7 @@ impl GenesisState {
}
#[must_use]
- pub fn native_asset_base_denomination(&self) -> &str {
+ pub fn native_asset_base_denomination(&self) -> &TracePrefixed {
&self.native_asset_base_denomination
}
@@ -140,7 +143,7 @@ pub struct UncheckedGenesisState {
pub authority_sudo_address: Address,
pub ibc_sudo_address: Address,
pub ibc_relayer_addresses: Vec,
- pub native_asset_base_denomination: String,
+ pub native_asset_base_denomination: TracePrefixed,
pub ibc_params: IBCParameters,
pub allowed_fee_assets: Vec,
pub fees: Fees,
@@ -295,7 +298,7 @@ mod tests {
authority_sudo_address: alice(),
ibc_sudo_address: alice(),
ibc_relayer_addresses: vec![alice(), bob()],
- native_asset_base_denomination: "nria".to_string(),
+ native_asset_base_denomination: "nria".parse().unwrap(),
ibc_params: IBCParameters {
ibc_enabled: true,
inbound_ics20_transfers_enabled: true,
diff --git a/crates/astria-sequencer-utils/src/genesis_example.rs b/crates/astria-sequencer-utils/src/genesis_example.rs
index f089dd746..05d66baa0 100644
--- a/crates/astria-sequencer-utils/src/genesis_example.rs
+++ b/crates/astria-sequencer-utils/src/genesis_example.rs
@@ -68,7 +68,7 @@ fn genesis_state() -> GenesisState {
authority_sudo_address: alice(),
ibc_sudo_address: alice(),
ibc_relayer_addresses: vec![alice(), bob()],
- native_asset_base_denomination: "nria".to_string(),
+ native_asset_base_denomination: "nria".parse().unwrap(),
ibc_params: IBCParameters {
ibc_enabled: true,
inbound_ics20_transfers_enabled: true,
diff --git a/crates/astria-sequencer/src/accounts/action.rs b/crates/astria-sequencer/src/accounts/action.rs
index 051258cf8..8d4853ea6 100644
--- a/crates/astria-sequencer/src/accounts/action.rs
+++ b/crates/astria-sequencer/src/accounts/action.rs
@@ -11,8 +11,11 @@ use astria_core::{
use tracing::instrument;
use crate::{
- accounts,
- accounts::StateReadExt as _,
+ accounts::{
+ self,
+ StateReadExt as _,
+ },
+ address,
assets,
bridge::StateReadExt as _,
transaction::action_handler::ActionHandler,
@@ -81,15 +84,16 @@ where
#[async_trait::async_trait]
impl ActionHandler for TransferAction {
async fn check_stateless(&self) -> Result<()> {
- crate::address::ensure_base_prefix(&self.to).context("destination address is invalid")?;
Ok(())
}
- async fn check_stateful(
- &self,
- state: &S,
- from: Address,
- ) -> Result<()> {
+ async fn check_stateful(&self, state: &S, from: Address) -> Result<()>
+ where
+ S: accounts::StateReadExt + address::StateReadExt + 'static,
+ {
+ state.ensure_base_prefix(&self.to).await.context(
+ "failed ensuring that the destination address matches the permitted base prefix",
+ )?;
ensure!(
state
.get_bridge_account_rollup_id(&from)
diff --git a/crates/astria-sequencer/src/accounts/component.rs b/crates/astria-sequencer/src/accounts/component.rs
index 2e4addba3..615cb24bb 100644
--- a/crates/astria-sequencer/src/accounts/component.rs
+++ b/crates/astria-sequencer/src/accounts/component.rs
@@ -10,9 +10,9 @@ use tendermint::abci::request::{
};
use tracing::instrument;
-use super::state_ext::StateWriteExt;
use crate::{
- assets::get_native_asset,
+ accounts,
+ assets,
component::Component,
};
@@ -24,11 +24,17 @@ impl Component for AccountsComponent {
type AppState = astria_core::sequencer::GenesisState;
#[instrument(name = "AccountsComponent::init_chain", skip_all)]
- async fn init_chain(mut state: S, app_state: &Self::AppState) -> Result<()> {
- let native_asset = get_native_asset();
+ async fn init_chain(mut state: S, app_state: &Self::AppState) -> Result<()>
+ where
+ S: accounts::StateWriteExt + assets::StateReadExt,
+ {
+ let native_asset = state
+ .get_native_asset()
+ .await
+ .context("failed to read native asset from state")?;
for account in app_state.accounts() {
state
- .put_account_balance(account.address, native_asset, account.balance)
+ .put_account_balance(account.address, &native_asset, account.balance)
.context("failed writing account balance to state")?;
}
@@ -39,7 +45,7 @@ impl Component for AccountsComponent {
}
#[instrument(name = "AccountsComponent::begin_block", skip_all)]
- async fn begin_block(
+ async fn begin_block(
_state: &mut Arc,
_begin_block: &BeginBlock,
) -> Result<()> {
@@ -47,7 +53,7 @@ impl Component for AccountsComponent {
}
#[instrument(name = "AccountsComponent::end_block", skip_all)]
- async fn end_block(
+ async fn end_block(
_state: &mut Arc,
_end_block: &EndBlock,
) -> Result<()> {
diff --git a/crates/astria-sequencer/src/accounts/state_ext.rs b/crates/astria-sequencer/src/accounts/state_ext.rs
index a3d70710d..fa0fe00a6 100644
--- a/crates/astria-sequencer/src/accounts/state_ext.rs
+++ b/crates/astria-sequencer/src/accounts/state_ext.rs
@@ -3,9 +3,14 @@ use anyhow::{
Result,
};
use astria_core::{
+ crypto::{
+ SigningKey,
+ VerificationKey,
+ },
primitive::v1::{
asset,
Address,
+ ADDRESS_LEN,
},
protocol::account::v1alpha1::AssetBalance,
};
@@ -36,12 +41,49 @@ struct Fee(u128);
const ACCOUNTS_PREFIX: &str = "accounts";
const TRANSFER_BASE_FEE_STORAGE_KEY: &str = "transferfee";
-struct StorageKey<'a>(&'a Address);
-impl<'a> std::fmt::Display for StorageKey<'a> {
+trait GetAddressBytes: Send + Sync {
+ fn get_address_bytes(&self) -> [u8; ADDRESS_LEN];
+}
+
+impl GetAddressBytes for Address {
+ fn get_address_bytes(&self) -> [u8; ADDRESS_LEN] {
+ self.bytes()
+ }
+}
+
+impl GetAddressBytes for [u8; ADDRESS_LEN] {
+ fn get_address_bytes(&self) -> [u8; ADDRESS_LEN] {
+ *self
+ }
+}
+
+impl GetAddressBytes for SigningKey {
+ fn get_address_bytes(&self) -> [u8; ADDRESS_LEN] {
+ self.verification_key().get_address_bytes()
+ }
+}
+
+impl GetAddressBytes for VerificationKey {
+ fn get_address_bytes(&self) -> [u8; ADDRESS_LEN] {
+ self.address_bytes()
+ }
+}
+
+impl<'a, T> GetAddressBytes for &'a T
+where
+ T: GetAddressBytes,
+{
+ fn get_address_bytes(&self) -> [u8; ADDRESS_LEN] {
+ (*self).get_address_bytes()
+ }
+}
+
+struct StorageKey<'a, T>(&'a T);
+impl<'a, T: GetAddressBytes> 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.bytes() {
+ for byte in self.0.get_address_bytes() {
f.write_fmt(format_args!("{byte:02x}"))?;
}
Ok(())
@@ -59,16 +101,14 @@ fn balance_storage_key>(
)
}
-fn nonce_storage_key(address: Address) -> String {
+fn nonce_storage_key(address: T) -> String {
format!("{}/nonce", StorageKey(&address))
}
#[async_trait]
-pub(crate) trait StateReadExt: StateRead {
+pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt {
#[instrument(skip_all)]
async fn get_account_balances(&self, address: Address) -> Result> {
- use crate::assets::StateReadExt as _;
-
let prefix = format!("{}/balance/", StorageKey(&address));
let mut balances: Vec = Vec::new();
@@ -94,10 +134,13 @@ pub(crate) trait StateReadExt: StateRead {
let Balance(balance) =
Balance::try_from_slice(&value).context("invalid balance bytes")?;
- let native_asset = crate::assets::get_native_asset();
+ let native_asset = self
+ .get_native_asset()
+ .await
+ .context("failed to read native asset from state")?;
if asset == native_asset.to_ibc_prefixed() {
balances.push(AssetBalance {
- denom: native_asset.clone(),
+ denom: native_asset.into(),
balance,
});
continue;
@@ -134,7 +177,7 @@ pub(crate) trait StateReadExt: StateRead {
}
#[instrument(skip_all)]
- async fn get_account_nonce(&self, address: Address) -> Result {
+ async fn get_account_nonce(&self, address: T) -> Result {
let bytes = self
.get_raw(&nonce_storage_key(address))
.await
@@ -264,9 +307,19 @@ mod tests {
StateReadExt as _,
StateWriteExt as _,
};
- use crate::accounts::state_ext::{
- balance_storage_key,
- nonce_storage_key,
+ use crate::{
+ accounts::state_ext::{
+ balance_storage_key,
+ nonce_storage_key,
+ },
+ assets::{
+ StateReadExt as _,
+ StateWriteExt as _,
+ },
+ test_utils::{
+ astria_address,
+ nria,
+ },
};
fn asset_0() -> astria_core::primitive::v1::asset::Denom {
@@ -287,7 +340,7 @@ mod tests {
let state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let nonce_expected = 0u32;
// uninitialized accounts return zero
@@ -308,7 +361,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let nonce_expected = 0u32;
// can write new
@@ -346,7 +399,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let nonce_expected = 2u32;
// can write new
@@ -363,7 +416,7 @@ mod tests {
);
// writing additional account preserves first account's values
- let address_1 = crate::address::base_prefixed([41u8; 20]);
+ let address_1 = astria_address(&[41u8; 20]);
let nonce_expected_1 = 3u32;
state
@@ -394,7 +447,7 @@ mod tests {
let state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let asset = asset_0();
let amount_expected = 0u128;
@@ -416,7 +469,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let asset = asset_0();
let mut amount_expected = 1u128;
@@ -458,7 +511,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let asset = asset_0();
let amount_expected = 1u128;
@@ -478,7 +531,7 @@ mod tests {
// writing to other accounts does not affect original account
// create needed variables
- let address_1 = crate::address::base_prefixed([41u8; 20]);
+ let address_1 = astria_address(&[41u8; 20]);
let amount_expected_1 = 2u128;
state
@@ -511,7 +564,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let asset_0 = asset_0();
let asset_1 = asset_1();
let amount_expected_0 = 1u128;
@@ -550,7 +603,7 @@ mod tests {
let state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
// see that call was ok
let balances = state
@@ -562,21 +615,20 @@ mod tests {
#[tokio::test]
async fn get_account_balances() {
- use crate::assets::StateWriteExt as _;
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
// need to set native asset in order to use `get_account_balances()`
- crate::assets::initialize_native_asset("nria");
+ state.put_native_asset(&nria());
- let asset_0 = crate::assets::get_native_asset();
+ let asset_0 = state.get_native_asset().await.unwrap();
let asset_1 = asset_1();
let asset_2 = asset_2();
// also need to add assets to the ibc state
state
- .put_ibc_asset(&asset_0.clone().unwrap_trace_prefixed())
+ .put_ibc_asset(&asset_0.clone())
.expect("should be able to call other trait method on state object");
state
.put_ibc_asset(&asset_1.clone().unwrap_trace_prefixed())
@@ -586,18 +638,14 @@ mod tests {
.expect("should be able to call other trait method on state object");
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let amount_expected_0 = 1u128;
let amount_expected_1 = 2u128;
let amount_expected_2 = 3u128;
// add balances to the account
state
- .put_account_balance(
- address,
- asset_0.clone().unwrap_trace_prefixed(),
- amount_expected_0,
- )
+ .put_account_balance(address, asset_0.clone(), amount_expected_0)
.expect("putting an account balance should not fail");
state
.put_account_balance(address, &asset_1, amount_expected_1)
@@ -615,7 +663,7 @@ mod tests {
balances,
vec![
AssetBalance {
- denom: asset_0.clone(),
+ denom: asset_0.into(),
balance: amount_expected_0,
},
AssetBalance {
@@ -637,7 +685,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let asset = asset_0();
let amount_increase = 2u128;
@@ -678,7 +726,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let asset = asset_0();
let amount_increase = 2u128;
@@ -720,7 +768,7 @@ mod tests {
let mut state = StateDelta::new(snapshot);
// create needed variables
- let address = crate::address::base_prefixed([42u8; 20]);
+ let address = astria_address(&[42u8; 20]);
let asset = asset_0();
let amount_increase = 2u128;
diff --git a/crates/astria-sequencer/src/address/mod.rs b/crates/astria-sequencer/src/address/mod.rs
index 65a9b0000..35bea31ad 100644
--- a/crates/astria-sequencer/src/address/mod.rs
+++ b/crates/astria-sequencer/src/address/mod.rs
@@ -1,111 +1,5 @@
-use anyhow::ensure;
-use astria_core::primitive::v1::{
- Address,
- AddressError,
- ADDRESS_LEN,
-};
-
mod state_ext;
-#[cfg(not(test))]
-pub(crate) use regular::*;
pub(crate) use state_ext::{
StateReadExt,
StateWriteExt,
};
-#[cfg(test)]
-pub(crate) use testonly::*;
-
-pub(crate) fn base_prefixed(arr: [u8; ADDRESS_LEN]) -> Address {
- Address::builder()
- .array(arr)
- .prefix(get_base_prefix())
- .try_build()
- .expect("the prefix must have been set as a valid bech32 prefix, so this should never fail")
-}
-
-pub(crate) fn try_base_prefixed(slice: &[u8]) -> Result {
- Address::builder()
- .slice(slice)
- .prefix(get_base_prefix())
- .try_build()
-}
-
-pub(crate) fn ensure_base_prefix(address: &Address) -> anyhow::Result<()> {
- ensure!(
- get_base_prefix() == address.prefix(),
- "address has prefix `{}` but only `{}` is permitted",
- address.prefix(),
- crate::address::get_base_prefix(),
- );
- Ok(())
-}
-
-#[cfg(not(test))]
-mod regular {
- //! Logic to be used for a normal debug or release build of sequencer.
-
- use std::sync::OnceLock;
-
- use anyhow::Context as _;
-
- static BASE_PREFIX: OnceLock = OnceLock::new();
-
- pub(crate) fn initialize_base_prefix(base_prefix: &str) -> anyhow::Result<()> {
- // construct a dummy address to see if we can construct it; fail otherwise.
- try_construct_dummy_address_from_prefix(base_prefix)
- .context("failed constructing a dummy address from the provided prefix")?;
-
- BASE_PREFIX.set(base_prefix.to_string()).expect(
- "THIS IS A BUG: attempted to set the base prefix more than once; it should only be set
- once when serving the `InitChain` consensus request, or immediately after Sequencer is
- restarted. It cannot be initialized twice or concurrently from more than one task or \
- thread.",
- );
-
- Ok(())
- }
-
- pub(crate) fn get_base_prefix() -> &'static str {
- BASE_PREFIX
- .get()
- .expect(
- "the base prefix must have been set while serving the `InitChain` consensus \
- request or upon Sequencer restart; if not set, the chain was initialized \
- incorrectly, or the base prefix not read from storage",
- )
- .as_str()
- }
-
- fn try_construct_dummy_address_from_prefix(
- s: &str,
- ) -> Result<(), astria_core::primitive::v1::AddressError> {
- use astria_core::primitive::v1::{
- Address,
- ADDRESS_LEN,
- };
- // construct a dummy address to see if we can construct it; fail otherwise.
- Address::builder()
- .array([0u8; ADDRESS_LEN])
- .prefix(s)
- .try_build()
- .map(|_| ())
- }
-}
-
-#[cfg(test)]
-mod testonly {
- // allow: this has to match the definition of the non-test function
- #[allow(clippy::unnecessary_wraps)]
- pub(crate) fn initialize_base_prefix(base_prefix: &str) -> anyhow::Result<()> {
- assert_eq!(
- base_prefix,
- get_base_prefix(),
- "all tests should be initialized with a \"astria\" as the base prefix"
- );
- Ok(())
- }
-
- pub(crate) fn get_base_prefix() -> &'static str {
- "astria"
- }
-}
diff --git a/crates/astria-sequencer/src/address/state_ext.rs b/crates/astria-sequencer/src/address/state_ext.rs
index 917e6ce42..924479107 100644
--- a/crates/astria-sequencer/src/address/state_ext.rs
+++ b/crates/astria-sequencer/src/address/state_ext.rs
@@ -1,8 +1,10 @@
use anyhow::{
bail,
+ ensure,
Context as _,
Result,
};
+use astria_core::primitive::v1::Address;
use async_trait::async_trait;
use cnidarium::{
StateRead,
@@ -16,6 +18,31 @@ fn base_prefix_key() -> &'static str {
#[async_trait]
pub(crate) trait StateReadExt: StateRead {
+ async fn ensure_base_prefix(&self, address: &Address) -> anyhow::Result<()> {
+ let prefix = self
+ .get_base_prefix()
+ .await
+ .context("failed to read base prefix from state")?;
+ ensure!(
+ prefix == address.prefix(),
+ "address has prefix `{}` but only `{prefix}` is permitted",
+ address.prefix(),
+ );
+ Ok(())
+ }
+
+ async fn try_base_prefixed(&self, slice: &[u8]) -> anyhow::Result {
+ let prefix = self
+ .get_base_prefix()
+ .await
+ .context("failed to read base prefix from state")?;
+ Address::builder()
+ .slice(slice)
+ .prefix(prefix)
+ .try_build()
+ .context("failed to construct address from byte slice and state-provided base prefix")
+ }
+
#[instrument(skip_all)]
async fn get_base_prefix(&self) -> Result {
let Some(bytes) = self
@@ -34,13 +61,28 @@ impl StateReadExt for T {}
#[async_trait]
pub(crate) trait StateWriteExt: StateWrite {
#[instrument(skip_all)]
- fn put_base_prefix(&mut self, prefix: &str) {
+ fn put_base_prefix(&mut self, prefix: &str) -> anyhow::Result<()> {
+ try_construct_dummy_address_from_prefix(prefix)
+ .context("failed constructing a dummy address from the provided prefix")?;
self.put_raw(base_prefix_key().into(), prefix.into());
+ Ok(())
}
}
impl StateWriteExt for T {}
+fn try_construct_dummy_address_from_prefix(
+ s: &str,
+) -> Result<(), astria_core::primitive::v1::AddressError> {
+ use astria_core::primitive::v1::ADDRESS_LEN;
+ // construct a dummy address to see if we can construct it; fail otherwise.
+ Address::builder()
+ .array([0u8; ADDRESS_LEN])
+ .prefix(s)
+ .try_build()
+ .map(|_| ())
+}
+
#[cfg(test)]
mod test {
use cnidarium::StateDelta;
@@ -56,7 +98,7 @@ mod test {
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
- state.put_base_prefix("astria");
+ state.put_base_prefix("astria").unwrap();
assert_eq!("astria", &state.get_base_prefix().await.unwrap());
}
}
diff --git a/crates/astria-sequencer/src/api_state_ext.rs b/crates/astria-sequencer/src/api_state_ext.rs
index 79c8c1512..ec3fe43a4 100644
--- a/crates/astria-sequencer/src/api_state_ext.rs
+++ b/crates/astria-sequencer/src/api_state_ext.rs
@@ -390,6 +390,7 @@ mod test {
use rand::Rng;
use super::*;
+ use crate::test_utils::astria_address;
// creates new sequencer block, optionally shifting all values except the height by 1
fn make_test_sequencer_block(height: u32) -> SequencerBlock {
@@ -400,7 +401,7 @@ mod test {
let mut deposits = vec![];
for _ in 0..2 {
let rollup_id = RollupId::new(rng.gen());
- let bridge_address = crate::address::base_prefixed([rng.gen(); 20]);
+ let bridge_address = astria_address(&[rng.gen(); 20]);
let amount = rng.gen::();
let asset = "testasset".parse().unwrap();
let destination_chain_address = rng.gen::().to_string();
diff --git a/crates/astria-sequencer/src/app/mod.rs b/crates/astria-sequencer/src/app/mod.rs
index 6e052d0c1..cc59071f1 100644
--- a/crates/astria-sequencer/src/app/mod.rs
+++ b/crates/astria-sequencer/src/app/mod.rs
@@ -14,7 +14,6 @@ use std::{
use anyhow::{
anyhow,
- bail,
ensure,
Context,
};
@@ -216,22 +215,16 @@ impl App {
.try_begin_transaction()
.expect("state Arc should not be referenced elsewhere");
- crate::address::initialize_base_prefix(&genesis_state.address_prefixes().base)
- .context("failed setting global base prefix")?;
- state_tx.put_base_prefix(&genesis_state.address_prefixes().base);
+ state_tx
+ .put_base_prefix(&genesis_state.address_prefixes().base)
+ .context("failed to write base prefix to state")?;
- crate::assets::initialize_native_asset(genesis_state.native_asset_base_denomination());
- let Some(native_asset) = crate::assets::get_native_asset()
- .as_trace_prefixed()
- .cloned()
- else {
- bail!("native asset must be trace-prefixed, not of form `ibc/`")
- };
+ let native_asset = genesis_state.native_asset_base_denomination();
+ state_tx.put_native_asset(native_asset);
state_tx
- .put_ibc_asset(&native_asset)
- .context("failed to put native asset")?;
+ .put_ibc_asset(native_asset)
+ .context("failed to commit native asset as ibc asset to state")?;
- state_tx.put_native_asset(&native_asset);
state_tx.put_chain_id_and_revision_number(chain_id.try_into().context("invalid chain ID")?);
state_tx.put_block_height(0);
@@ -1149,7 +1142,7 @@ async fn update_mempool_after_finalization(
mempool: &mut Mempool,
state: S,
) -> anyhow::Result<()> {
- let current_account_nonce_getter = |address: Address| state.get_account_nonce(address);
+ let current_account_nonce_getter = |address: [u8; 20]| state.get_account_nonce(address);
mempool.run_maintenance(current_account_nonce_getter).await
}
diff --git a/crates/astria-sequencer/src/app/test_utils.rs b/crates/astria-sequencer/src/app/test_utils.rs
index d942e99ec..6ef60fac9 100644
--- a/crates/astria-sequencer/src/app/test_utils.rs
+++ b/crates/astria-sequencer/src/app/test_utils.rs
@@ -1,10 +1,6 @@
use astria_core::{
crypto::SigningKey,
- primitive::v1::{
- Address,
- RollupId,
- ADDRESS_LEN,
- },
+ primitive::v1::RollupId,
protocol::transaction::v1alpha1::{
action::{
SequenceAction,
@@ -29,57 +25,46 @@ use crate::{
app::App,
mempool::Mempool,
metrics::Metrics,
+ test_utils::astria_address_from_hex_string,
};
-// attempts to decode the given hex string into an address.
-pub(crate) fn address_from_hex_string(s: &str) -> Address {
- let bytes = hex::decode(s).unwrap();
- let arr: [u8; ADDRESS_LEN] = bytes.try_into().unwrap();
- crate::address::base_prefixed(arr)
-}
-
pub(crate) const ALICE_ADDRESS: &str = "1c0c490f1b5528d8173c5de46d131160e4b2c0c3";
pub(crate) const BOB_ADDRESS: &str = "34fec43c7fcab9aef3b3cf8aba855e41ee69ca3a";
pub(crate) const CAROL_ADDRESS: &str = "60709e2d391864b732b4f0f51e387abb76743871";
pub(crate) const JUDY_ADDRESS: &str = "bc5b91da07778eeaf622d0dcf4d7b4233525998d";
pub(crate) const TED_ADDRESS: &str = "4c4f91d8a918357ab5f6f19c1e179968fc39bb44";
-pub(crate) fn get_alice_signing_key_and_address() -> (SigningKey, Address) {
+pub(crate) fn get_alice_signing_key() -> SigningKey {
// this secret key corresponds to ALICE_ADDRESS
let alice_secret_bytes: [u8; 32] =
hex::decode("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90")
.unwrap()
.try_into()
.unwrap();
- let alice_signing_key = SigningKey::from(alice_secret_bytes);
- let alice = crate::address::base_prefixed(alice_signing_key.verification_key().address_bytes());
- (alice_signing_key, alice)
+ SigningKey::from(alice_secret_bytes)
}
-pub(crate) fn get_bridge_signing_key_and_address() -> (SigningKey, Address) {
+pub(crate) fn get_bridge_signing_key() -> SigningKey {
let bridge_secret_bytes: [u8; 32] =
hex::decode("db4982e01f3eba9e74ac35422fcd49aa2b47c3c535345c7e7da5220fe3a0ce79")
.unwrap()
.try_into()
.unwrap();
- let bridge_signing_key = SigningKey::from(bridge_secret_bytes);
- let bridge =
- crate::address::base_prefixed(bridge_signing_key.verification_key().address_bytes());
- (bridge_signing_key, bridge)
+ SigningKey::from(bridge_secret_bytes)
}
pub(crate) fn default_genesis_accounts() -> Vec {
vec![
Account {
- address: address_from_hex_string(ALICE_ADDRESS),
+ address: astria_address_from_hex_string(ALICE_ADDRESS),
balance: 10u128.pow(19),
},
Account {
- address: address_from_hex_string(BOB_ADDRESS),
+ address: astria_address_from_hex_string(BOB_ADDRESS),
balance: 10u128.pow(19),
},
Account {
- address: address_from_hex_string(CAROL_ADDRESS),
+ address: astria_address_from_hex_string(CAROL_ADDRESS),
balance: 10u128.pow(19),
},
]
@@ -101,14 +86,14 @@ pub(crate) fn unchecked_genesis_state() -> UncheckedGenesisState {
UncheckedGenesisState {
accounts: default_genesis_accounts(),
address_prefixes: AddressPrefixes {
- base: crate::address::get_base_prefix().to_string(),
+ base: crate::test_utils::ASTRIA_PREFIX.into(),
},
- authority_sudo_address: address_from_hex_string(JUDY_ADDRESS),
- ibc_sudo_address: address_from_hex_string(TED_ADDRESS),
+ authority_sudo_address: astria_address_from_hex_string(JUDY_ADDRESS),
+ ibc_sudo_address: astria_address_from_hex_string(TED_ADDRESS),
ibc_relayer_addresses: vec![],
- native_asset_base_denomination: "nria".to_string(),
+ native_asset_base_denomination: crate::test_utils::nria(),
ibc_params: IBCParameters::default(),
- allowed_fee_assets: vec!["nria".parse().unwrap()],
+ allowed_fee_assets: vec![crate::test_utils::nria().into()],
fees: default_fees(),
}
}
@@ -153,7 +138,6 @@ pub(crate) async fn initialize_app(
}
pub(crate) fn get_mock_tx(nonce: u32) -> SignedTransaction {
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
let tx = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(nonce)
@@ -169,5 +153,5 @@ pub(crate) fn get_mock_tx(nonce: u32) -> SignedTransaction {
],
};
- tx.into_signed(&alice_signing_key)
+ tx.into_signed(&get_alice_signing_key())
}
diff --git a/crates/astria-sequencer/src/app/tests_app.rs b/crates/astria-sequencer/src/app/tests_app.rs
index c34047f79..762a27ba1 100644
--- a/crates/astria-sequencer/src/app/tests_app.rs
+++ b/crates/astria-sequencer/src/app/tests_app.rs
@@ -41,7 +41,7 @@ use super::*;
use crate::{
accounts::StateReadExt as _,
app::test_utils::*,
- assets::get_native_asset,
+ assets::StateReadExt as _,
authority::{
StateReadExt as _,
StateWriteExt as _,
@@ -53,7 +53,12 @@ use crate::{
},
proposal::commitment::generate_rollup_datas_commitment,
state_ext::StateReadExt as _,
- test_utils::verification_key,
+ test_utils::{
+ astria_address,
+ astria_address_from_hex_string,
+ nria,
+ verification_key,
+ },
};
fn default_tendermint_header() -> Header {
@@ -91,7 +96,7 @@ async fn app_genesis_and_init_chain() {
assert_eq!(
balance,
app.state
- .get_account_balance(address, get_native_asset())
+ .get_account_balance(address, nria())
.await
.unwrap(),
);
@@ -177,7 +182,6 @@ async fn app_commit() {
let (mut app, storage) = initialize_app_with_storage(None, vec![]).await;
assert_eq!(app.state.get_block_height().await.unwrap(), 0);
- let native_asset = get_native_asset();
for Account {
address,
balance,
@@ -186,7 +190,7 @@ async fn app_commit() {
assert_eq!(
balance,
app.state
- .get_account_balance(address, native_asset)
+ .get_account_balance(address, nria())
.await
.unwrap()
);
@@ -205,10 +209,7 @@ async fn app_commit() {
} in default_genesis_accounts()
{
assert_eq!(
- snapshot
- .get_account_balance(address, native_asset)
- .await
- .unwrap(),
+ snapshot.get_account_balance(address, nria()).await.unwrap(),
balance
);
}
@@ -218,11 +219,10 @@ async fn app_commit() {
async fn app_transfer_block_fees_to_sudo() {
let (mut app, storage) = initialize_app_with_storage(None, vec![]).await;
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
- let native_asset = get_native_asset().clone();
+ let alice = get_alice_signing_key();
// transfer funds from Alice to Bob; use native token for fee payment
- let bob_address = address_from_hex_string(BOB_ADDRESS);
+ let bob_address = astria_address_from_hex_string(BOB_ADDRESS);
let amount = 333_333;
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -233,14 +233,14 @@ async fn app_transfer_block_fees_to_sudo() {
TransferAction {
to: bob_address,
amount,
- asset: native_asset.clone(),
- fee_asset: native_asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
}
.into(),
],
};
- let signed_tx = tx.into_signed(&alice_signing_key);
+ let signed_tx = tx.into_signed(&alice);
let proposer_address: tendermint::account::Id = [99u8; 20].to_vec().try_into().unwrap();
@@ -268,7 +268,7 @@ async fn app_transfer_block_fees_to_sudo() {
let transfer_fee = app.state.get_transfer_base_fee().await.unwrap();
assert_eq!(
app.state
- .get_account_balance(address_from_hex_string(JUDY_ADDRESS), native_asset)
+ .get_account_balance(astria_address_from_hex_string(JUDY_ADDRESS), nria())
.await
.unwrap(),
transfer_fee,
@@ -285,17 +285,16 @@ async fn app_create_sequencer_block_with_sequenced_data_and_deposits() {
use crate::api_state_ext::StateReadExt as _;
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let (mut app, storage) = initialize_app_with_storage(None, vec![]).await;
- let bridge_address = crate::address::base_prefixed([99; 20]);
+ let bridge_address = astria_address(&[99; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset().clone();
let mut state_tx = StateDelta::new(app.state.clone());
state_tx.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
state_tx
- .put_bridge_account_ibc_asset(&bridge_address, &asset)
+ .put_bridge_account_ibc_asset(&bridge_address, nria())
.unwrap();
app.apply(state_tx);
app.prepare_commit(storage.clone()).await.unwrap();
@@ -305,14 +304,14 @@ async fn app_create_sequencer_block_with_sequenced_data_and_deposits() {
let lock_action = BridgeLockAction {
to: bridge_address,
amount,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
destination_chain_address: "nootwashere".to_string(),
};
let sequence_action = SequenceAction {
rollup_id,
data: b"hello world".to_vec(),
- fee_asset: asset.clone(),
+ fee_asset: nria().into(),
};
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -322,13 +321,13 @@ async fn app_create_sequencer_block_with_sequenced_data_and_deposits() {
actions: vec![lock_action.into(), sequence_action.into()],
};
- let signed_tx = tx.into_signed(&alice_signing_key);
+ let signed_tx = tx.into_signed(&alice);
let expected_deposit = Deposit::new(
bridge_address,
rollup_id,
amount,
- asset,
+ nria().into(),
"nootwashere".to_string(),
);
let deposits = HashMap::from_iter(vec![(rollup_id, vec![expected_deposit.clone()])]);
@@ -375,12 +374,12 @@ async fn app_create_sequencer_block_with_sequenced_data_and_deposits() {
#[tokio::test]
#[allow(clippy::too_many_lines)]
async fn app_execution_results_match_proposal_vs_after_proposal() {
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let (mut app, storage) = initialize_app_with_storage(None, vec![]).await;
- let bridge_address = crate::address::base_prefixed([99; 20]);
+ let bridge_address = astria_address(&[99; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset().clone();
+ let asset = nria().clone();
let mut state_tx = StateDelta::new(app.state.clone());
state_tx.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
@@ -395,14 +394,14 @@ async fn app_execution_results_match_proposal_vs_after_proposal() {
let lock_action = BridgeLockAction {
to: bridge_address,
amount,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
destination_chain_address: "nootwashere".to_string(),
};
let sequence_action = SequenceAction {
rollup_id,
data: b"hello world".to_vec(),
- fee_asset: asset.clone(),
+ fee_asset: nria().into(),
};
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -412,13 +411,13 @@ async fn app_execution_results_match_proposal_vs_after_proposal() {
actions: vec![lock_action.into(), sequence_action.into()],
};
- let signed_tx = tx.into_signed(&alice_signing_key);
+ let signed_tx = tx.into_signed(&alice);
let expected_deposit = Deposit::new(
bridge_address,
rollup_id,
amount,
- asset,
+ nria().into(),
"nootwashere".to_string(),
);
let deposits = HashMap::from_iter(vec![(rollup_id, vec![expected_deposit.clone()])]);
@@ -527,7 +526,7 @@ async fn app_prepare_proposal_cometbft_max_bytes_overflow_ok() {
app.commit(storage.clone()).await;
// create txs which will cause cometBFT overflow
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let tx_pass = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(0)
@@ -537,12 +536,12 @@ async fn app_prepare_proposal_cometbft_max_bytes_overflow_ok() {
SequenceAction {
rollup_id: RollupId::from([1u8; 32]),
data: vec![1u8; 100_000],
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
}
- .into_signed(&alice_signing_key);
+ .into_signed(&alice);
let tx_overflow = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(1)
@@ -552,12 +551,12 @@ async fn app_prepare_proposal_cometbft_max_bytes_overflow_ok() {
SequenceAction {
rollup_id: RollupId::from([1u8; 32]),
data: vec![1u8; 100_000],
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
}
- .into_signed(&alice_signing_key);
+ .into_signed(&alice);
app.mempool.insert(tx_pass, 0).await.unwrap();
app.mempool.insert(tx_overflow, 0).await.unwrap();
@@ -600,7 +599,7 @@ async fn app_prepare_proposal_sequencer_max_bytes_overflow_ok() {
app.commit(storage.clone()).await;
// create txs which will cause sequencer overflow (max is currently 256_000 bytes)
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let tx_pass = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(0)
@@ -610,12 +609,12 @@ async fn app_prepare_proposal_sequencer_max_bytes_overflow_ok() {
SequenceAction {
rollup_id: RollupId::from([1u8; 32]),
data: vec![1u8; 200_000],
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
}
- .into_signed(&alice_signing_key);
+ .into_signed(&alice);
let tx_overflow = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(1)
@@ -625,12 +624,12 @@ async fn app_prepare_proposal_sequencer_max_bytes_overflow_ok() {
SequenceAction {
rollup_id: RollupId::from([1u8; 32]),
data: vec![1u8; 100_000],
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
}
- .into_signed(&alice_signing_key);
+ .into_signed(&alice);
app.mempool.insert(tx_pass, 0).await.unwrap();
app.mempool.insert(tx_overflow, 0).await.unwrap();
@@ -680,7 +679,7 @@ async fn app_end_block_validator_updates() {
];
let mut app = initialize_app(None, initial_validator_set).await;
- let proposer_address = crate::address::base_prefixed([0u8; 20]);
+ let proposer_address = astria_address(&[0u8; 20]);
let validator_updates = vec![
ValidatorUpdate {
diff --git a/crates/astria-sequencer/src/app/tests_breaking_changes.rs b/crates/astria-sequencer/src/app/tests_breaking_changes.rs
index 209a6317e..b7c11a8bf 100644
--- a/crates/astria-sequencer/src/app/tests_breaking_changes.rs
+++ b/crates/astria-sequencer/src/app/tests_breaking_changes.rs
@@ -50,36 +50,41 @@ use tendermint::{
use crate::{
app::test_utils::{
- address_from_hex_string,
default_fees,
default_genesis_accounts,
- get_alice_signing_key_and_address,
- get_bridge_signing_key_and_address,
+ get_alice_signing_key,
+ get_bridge_signing_key,
initialize_app,
initialize_app_with_storage,
BOB_ADDRESS,
CAROL_ADDRESS,
},
- assets::get_native_asset,
bridge::StateWriteExt as _,
proposal::commitment::generate_rollup_datas_commitment,
+ test_utils::{
+ astria_address,
+ astria_address_from_hex_string,
+ nria,
+ ASTRIA_PREFIX,
+ },
};
/// XXX: This should be expressed in terms of `crate::app::test_utils::unchecked_genesis_state` to
/// be consistent everywhere. `get_alice_signing_key` already is, why not this?
fn unchecked_genesis_state() -> UncheckedGenesisState {
- let (_, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
UncheckedGenesisState {
accounts: vec![],
address_prefixes: AddressPrefixes {
- base: crate::address::get_base_prefix().to_string(),
+ base: ASTRIA_PREFIX.into(),
},
authority_sudo_address: alice_address,
ibc_sudo_address: alice_address,
ibc_relayer_addresses: vec![],
- native_asset_base_denomination: "nria".to_string(),
+ native_asset_base_denomination: nria(),
ibc_params: IBCParameters::default(),
- allowed_fee_assets: vec!["nria".parse().unwrap()],
+ allowed_fee_assets: vec![nria().into()],
fees: default_fees(),
}
}
@@ -92,17 +97,16 @@ async fn app_genesis_snapshot() {
#[tokio::test]
async fn app_finalize_block_snapshot() {
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let (mut app, storage) = initialize_app_with_storage(None, vec![]).await;
- let bridge_address = crate::address::base_prefixed([99; 20]);
+ let bridge_address = astria_address(&[99; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset().clone();
let mut state_tx = StateDelta::new(app.state.clone());
state_tx.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
state_tx
- .put_bridge_account_ibc_asset(&bridge_address, &asset)
+ .put_bridge_account_ibc_asset(&bridge_address, nria())
.unwrap();
app.apply(state_tx);
@@ -115,14 +119,14 @@ async fn app_finalize_block_snapshot() {
let lock_action = BridgeLockAction {
to: bridge_address,
amount,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
destination_chain_address: "nootwashere".to_string(),
};
let sequence_action = SequenceAction {
rollup_id,
data: b"hello world".to_vec(),
- fee_asset: asset.clone(),
+ fee_asset: nria().into(),
};
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -132,13 +136,13 @@ async fn app_finalize_block_snapshot() {
actions: vec![lock_action.into(), sequence_action.into()],
};
- let signed_tx = tx.into_signed(&alice_signing_key);
+ let signed_tx = tx.into_signed(&alice);
let expected_deposit = Deposit::new(
bridge_address,
rollup_id,
amount,
- asset,
+ nria().into(),
"nootwashere".to_string(),
);
let deposits = HashMap::from_iter(vec![(rollup_id, vec![expected_deposit.clone()])]);
@@ -180,10 +184,11 @@ async fn app_execute_transaction_with_every_action_snapshot() {
SudoAddressChangeAction,
};
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
- let (bridge_signing_key, bridge_address) = get_bridge_signing_key_and_address();
- let bob_address = address_from_hex_string(BOB_ADDRESS);
- let carol_address = address_from_hex_string(CAROL_ADDRESS);
+ let alice = get_alice_signing_key();
+ let bridge = get_bridge_signing_key();
+ let bridge_address = astria_address(&bridge.address_bytes());
+ let bob_address = astria_address_from_hex_string(BOB_ADDRESS);
+ let carol_address = astria_address_from_hex_string(CAROL_ADDRESS);
let mut accounts = default_genesis_accounts();
accounts.push(Account {
address: bridge_address,
@@ -205,7 +210,6 @@ async fn app_execute_transaction_with_every_action_snapshot() {
};
let rollup_id = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset().clone();
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -216,14 +220,14 @@ async fn app_execute_transaction_with_every_action_snapshot() {
TransferAction {
to: bob_address,
amount: 333_333,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
}
.into(),
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data: b"hello world".to_vec(),
- fee_asset: asset.clone(),
+ fee_asset: nria().into(),
}
.into(),
Action::ValidatorUpdate(update.clone()),
@@ -241,7 +245,7 @@ async fn app_execute_transaction_with_every_action_snapshot() {
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
let tx = UnsignedTransaction {
@@ -252,15 +256,15 @@ async fn app_execute_transaction_with_every_action_snapshot() {
actions: vec![
InitBridgeAccountAction {
rollup_id,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
sudo_address: None,
withdrawer_address: None,
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&bridge_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&bridge));
app.execute_transaction(signed_tx).await.unwrap();
let tx = UnsignedTransaction {
@@ -272,15 +276,15 @@ async fn app_execute_transaction_with_every_action_snapshot() {
BridgeLockAction {
to: bridge_address,
amount: 100,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
destination_chain_address: "nootwashere".to_string(),
}
.into(),
BridgeUnlockAction {
to: bob_address,
amount: 10,
- fee_asset: asset.clone(),
+ fee_asset: nria().into(),
memo: "{}".into(),
bridge_address: None,
}
@@ -289,13 +293,13 @@ async fn app_execute_transaction_with_every_action_snapshot() {
bridge_address,
new_sudo_address: Some(bob_address),
new_withdrawer_address: Some(bob_address),
- fee_asset: asset.clone(),
+ fee_asset: nria().into(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&bridge_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&bridge));
app.execute_transaction(signed_tx).await.unwrap();
app.prepare_commit(storage.clone()).await.unwrap();
diff --git a/crates/astria-sequencer/src/app/tests_execute_transaction.rs b/crates/astria-sequencer/src/app/tests_execute_transaction.rs
index a596f6d6e..f0c83ddfa 100644
--- a/crates/astria-sequencer/src/app/tests_execute_transaction.rs
+++ b/crates/astria-sequencer/src/app/tests_execute_transaction.rs
@@ -34,10 +34,7 @@ use tendermint::abci::EventAttributeIndexExt as _;
use crate::{
accounts::StateReadExt as _,
app::test_utils::*,
- assets::{
- get_native_asset,
- StateReadExt as _,
- },
+ assets::StateReadExt as _,
authority::StateReadExt as _,
bridge::{
StateReadExt as _,
@@ -45,32 +42,32 @@ use crate::{
},
ibc::StateReadExt as _,
sequence::calculate_fee_from_state,
+ test_utils::{
+ astria_address,
+ astria_address_from_hex_string,
+ nria,
+ },
transaction::{
InvalidChainId,
InvalidNonce,
},
};
-const DEFAULT_NATIVE_ASSET_DENOM: &str = "nria";
-fn default_native_asset() -> asset::Denom {
- DEFAULT_NATIVE_ASSET_DENOM.parse().unwrap()
-}
-
/// XXX: This should be expressed in terms of `crate::app::test_utils::unchecked_genesis_state` to
/// be consistent everywhere. `get_alice_sining_key` already is, why not this??
fn unchecked_genesis_state() -> UncheckedGenesisState {
- let (_, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
UncheckedGenesisState {
accounts: default_genesis_accounts(),
address_prefixes: AddressPrefixes {
- base: crate::address::get_base_prefix().to_string(),
+ base: crate::test_utils::ASTRIA_PREFIX.into(),
},
- authority_sudo_address: alice_address,
- ibc_sudo_address: alice_address,
+ authority_sudo_address: crate::test_utils::astria_address(&alice.address_bytes()),
+ ibc_sudo_address: crate::test_utils::astria_address(&alice.address_bytes()),
ibc_relayer_addresses: vec![],
- native_asset_base_denomination: DEFAULT_NATIVE_ASSET_DENOM.to_string(),
+ native_asset_base_denomination: crate::test_utils::nria(),
ibc_params: IBCParameters::default(),
- allowed_fee_assets: vec![default_native_asset()],
+ allowed_fee_assets: vec![crate::test_utils::nria().into()],
fees: default_fees(),
}
}
@@ -88,8 +85,9 @@ async fn app_execute_transaction_transfer() {
let mut app = initialize_app(None, vec![]).await;
// transfer funds from Alice to Bob
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
- let bob_address = address_from_hex_string(BOB_ADDRESS);
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
+ let bob_address = astria_address_from_hex_string(BOB_ADDRESS);
let value = 333_333;
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -100,20 +98,19 @@ async fn app_execute_transaction_transfer() {
TransferAction {
to: bob_address,
amount: value,
- asset: get_native_asset().clone(),
- fee_asset: get_native_asset().clone(),
+ asset: crate::test_utils::nria().into(),
+ fee_asset: crate::test_utils::nria().into(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
- let native_asset = get_native_asset();
assert_eq!(
app.state
- .get_account_balance(bob_address, native_asset)
+ .get_account_balance(bob_address, nria())
.await
.unwrap(),
value + 10u128.pow(19)
@@ -121,7 +118,7 @@ async fn app_execute_transaction_transfer() {
let transfer_fee = app.state.get_transfer_base_fee().await.unwrap();
assert_eq!(
app.state
- .get_account_balance(alice_address, native_asset)
+ .get_account_balance(alice_address, nria())
.await
.unwrap(),
10u128.pow(19) - (value + transfer_fee),
@@ -137,17 +134,18 @@ async fn app_execute_transaction_transfer_not_native_token() {
let mut app = initialize_app(None, vec![]).await;
// create some asset to be transferred and update Alice's balance of it
- let asset = test_asset();
let value = 333_333;
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
+
let mut state_tx = StateDelta::new(app.state.clone());
state_tx
- .put_account_balance(alice_address, &asset, value)
+ .put_account_balance(alice_address, &test_asset(), value)
.unwrap();
app.apply(state_tx);
// transfer funds from Alice to Bob; use native token for fee payment
- let bob_address = address_from_hex_string(BOB_ADDRESS);
+ let bob_address = astria_address_from_hex_string(BOB_ADDRESS);
let tx = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(0)
@@ -157,27 +155,26 @@ async fn app_execute_transaction_transfer_not_native_token() {
TransferAction {
to: bob_address,
amount: value,
- asset: asset.clone(),
- fee_asset: get_native_asset().clone(),
+ asset: test_asset(),
+ fee_asset: nria().into(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
- let native_asset = get_native_asset();
assert_eq!(
app.state
- .get_account_balance(bob_address, native_asset)
+ .get_account_balance(bob_address, nria())
.await
.unwrap(),
10u128.pow(19), // genesis balance
);
assert_eq!(
app.state
- .get_account_balance(bob_address, &asset)
+ .get_account_balance(bob_address, test_asset())
.await
.unwrap(),
value, // transferred amount
@@ -186,14 +183,14 @@ async fn app_execute_transaction_transfer_not_native_token() {
let transfer_fee = app.state.get_transfer_base_fee().await.unwrap();
assert_eq!(
app.state
- .get_account_balance(alice_address, native_asset)
+ .get_account_balance(alice_address, nria())
.await
.unwrap(),
10u128.pow(19) - transfer_fee, // genesis balance - fee
);
assert_eq!(
app.state
- .get_account_balance(alice_address, &asset)
+ .get_account_balance(alice_address, test_asset())
.await
.unwrap(),
0, // 0 since all funds of `asset` were transferred
@@ -211,7 +208,7 @@ async fn app_execute_transaction_transfer_balance_too_low_for_fee() {
// create a new key; will have 0 balance
let keypair = SigningKey::new(OsRng);
- let bob = address_from_hex_string(BOB_ADDRESS);
+ let bob = astria_address_from_hex_string(BOB_ADDRESS);
// 0-value transfer; only fee is deducted from sender
let tx = UnsignedTransaction {
@@ -223,8 +220,8 @@ async fn app_execute_transaction_transfer_balance_too_low_for_fee() {
TransferAction {
to: bob,
amount: 0,
- asset: get_native_asset().clone(),
- fee_asset: get_native_asset().clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
}
.into(),
],
@@ -250,7 +247,8 @@ async fn app_execute_transaction_sequence() {
state_tx.put_sequence_action_byte_cost_multiplier(1);
app.apply(state_tx);
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let data = b"hello world".to_vec();
let fee = calculate_fee_from_state(&data, &app.state).await.unwrap();
@@ -263,19 +261,19 @@ async fn app_execute_transaction_sequence() {
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data,
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
assert_eq!(
app.state
- .get_account_balance(alice_address, get_native_asset())
+ .get_account_balance(alice_address, nria())
.await
.unwrap(),
10u128.pow(19) - fee,
@@ -286,11 +284,9 @@ async fn app_execute_transaction_sequence() {
async fn app_execute_transaction_invalid_fee_asset() {
let mut app = initialize_app(None, vec![]).await;
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let data = b"hello world".to_vec();
- let fee_asset = test_asset();
-
let tx = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(0)
@@ -300,19 +296,20 @@ async fn app_execute_transaction_invalid_fee_asset() {
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data,
- fee_asset,
+ fee_asset: test_asset(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
assert!(app.execute_transaction(signed_tx).await.is_err());
}
#[tokio::test]
async fn app_execute_transaction_validator_update() {
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let mut app = initialize_app(Some(genesis_state()), vec![]).await;
@@ -329,7 +326,7 @@ async fn app_execute_transaction_validator_update() {
actions: vec![Action::ValidatorUpdate(update.clone())],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
@@ -343,7 +340,8 @@ async fn app_execute_transaction_validator_update() {
#[tokio::test]
async fn app_execute_transaction_ibc_relayer_change_addition() {
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let mut app = initialize_app(Some(genesis_state()), vec![]).await;
@@ -355,7 +353,7 @@ async fn app_execute_transaction_ibc_relayer_change_addition() {
actions: vec![IbcRelayerChangeAction::Addition(alice_address).into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
assert!(app.state.is_ibc_relayer(&alice_address).await.unwrap());
@@ -363,7 +361,8 @@ async fn app_execute_transaction_ibc_relayer_change_addition() {
#[tokio::test]
async fn app_execute_transaction_ibc_relayer_change_deletion() {
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let genesis_state = UncheckedGenesisState {
ibc_relayer_addresses: vec![alice_address],
@@ -381,7 +380,7 @@ async fn app_execute_transaction_ibc_relayer_change_deletion() {
actions: vec![IbcRelayerChangeAction::Removal(alice_address).into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
assert!(!app.state.is_ibc_relayer(&alice_address).await.unwrap());
@@ -389,10 +388,10 @@ async fn app_execute_transaction_ibc_relayer_change_deletion() {
#[tokio::test]
async fn app_execute_transaction_ibc_relayer_change_invalid() {
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
-
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let genesis_state = UncheckedGenesisState {
- ibc_sudo_address: crate::address::base_prefixed([0; 20]),
+ ibc_sudo_address: astria_address(&[0; 20]),
ibc_relayer_addresses: vec![alice_address],
..unchecked_genesis_state()
}
@@ -408,17 +407,18 @@ async fn app_execute_transaction_ibc_relayer_change_invalid() {
actions: vec![IbcRelayerChangeAction::Removal(alice_address).into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
assert!(app.execute_transaction(signed_tx).await.is_err());
}
#[tokio::test]
async fn app_execute_transaction_sudo_address_change() {
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let mut app = initialize_app(Some(genesis_state()), vec![]).await;
- let new_address = address_from_hex_string(BOB_ADDRESS);
+ let new_address = astria_address_from_hex_string(BOB_ADDRESS);
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -430,7 +430,7 @@ async fn app_execute_transaction_sudo_address_change() {
})],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
@@ -440,12 +440,13 @@ async fn app_execute_transaction_sudo_address_change() {
#[tokio::test]
async fn app_execute_transaction_sudo_address_change_error() {
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
- let authority_sudo_address = address_from_hex_string(CAROL_ADDRESS);
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
+ let authority_sudo_address = astria_address_from_hex_string(CAROL_ADDRESS);
let genesis_state = UncheckedGenesisState {
authority_sudo_address,
- ibc_sudo_address: crate::address::base_prefixed([0u8; 20]),
+ ibc_sudo_address: astria_address(&[0u8; 20]),
..unchecked_genesis_state()
}
.try_into()
@@ -462,7 +463,7 @@ async fn app_execute_transaction_sudo_address_change_error() {
})],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
let res = app
.execute_transaction(signed_tx)
.await
@@ -476,38 +477,37 @@ async fn app_execute_transaction_sudo_address_change_error() {
async fn app_execute_transaction_fee_asset_change_addition() {
use astria_core::protocol::transaction::v1alpha1::action::FeeAssetChangeAction;
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let mut app = initialize_app(Some(genesis_state()), vec![]).await;
- let new_asset = test_asset();
-
let tx = UnsignedTransaction {
params: TransactionParams::builder()
.nonce(0)
.chain_id("test")
.build(),
actions: vec![Action::FeeAssetChange(FeeAssetChangeAction::Addition(
- new_asset.clone(),
+ test_asset(),
))],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
- assert!(app.state.is_allowed_fee_asset(&new_asset).await.unwrap());
+ assert!(app.state.is_allowed_fee_asset(&test_asset()).await.unwrap());
}
#[tokio::test]
async fn app_execute_transaction_fee_asset_change_removal() {
use astria_core::protocol::transaction::v1alpha1::action::FeeAssetChangeAction;
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
- let test_asset = test_asset();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let genesis_state = UncheckedGenesisState {
- allowed_fee_assets: vec![default_native_asset(), test_asset.clone()],
+ allowed_fee_assets: vec![nria().into(), test_asset()],
..unchecked_genesis_state()
}
.try_into()
@@ -520,22 +520,22 @@ async fn app_execute_transaction_fee_asset_change_removal() {
.chain_id("test")
.build(),
actions: vec![Action::FeeAssetChange(FeeAssetChangeAction::Removal(
- test_asset.clone(),
+ test_asset(),
))],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
- assert!(!app.state.is_allowed_fee_asset(&test_asset).await.unwrap());
+ assert!(!app.state.is_allowed_fee_asset(test_asset()).await.unwrap());
}
#[tokio::test]
async fn app_execute_transaction_fee_asset_change_invalid() {
use astria_core::protocol::transaction::v1alpha1::action::FeeAssetChangeAction;
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let mut app = initialize_app(Some(genesis_state()), vec![]).await;
@@ -545,11 +545,11 @@ async fn app_execute_transaction_fee_asset_change_invalid() {
.chain_id("test")
.build(),
actions: vec![Action::FeeAssetChange(FeeAssetChangeAction::Removal(
- get_native_asset().clone(),
+ nria().into(),
))],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
let res = app
.execute_transaction(signed_tx)
.await
@@ -563,7 +563,9 @@ async fn app_execute_transaction_fee_asset_change_invalid() {
async fn app_execute_transaction_init_bridge_account_ok() {
use astria_core::protocol::transaction::v1alpha1::action::InitBridgeAccountAction;
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
+
let mut app = initialize_app(None, vec![]).await;
let mut state_tx = StateDelta::new(app.state.clone());
let fee = 12; // arbitrary
@@ -571,11 +573,10 @@ async fn app_execute_transaction_init_bridge_account_ok() {
app.apply(state_tx);
let rollup_id = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset().clone();
let action = InitBridgeAccountAction {
rollup_id,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
sudo_address: None,
withdrawer_address: None,
};
@@ -587,11 +588,11 @@ async fn app_execute_transaction_init_bridge_account_ok() {
actions: vec![action.into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
let before_balance = app
.state
- .get_account_balance(alice_address, &asset)
+ .get_account_balance(alice_address, nria())
.await
.unwrap();
app.execute_transaction(signed_tx).await.unwrap();
@@ -609,11 +610,11 @@ async fn app_execute_transaction_init_bridge_account_ok() {
.get_bridge_account_ibc_asset(&alice_address)
.await
.unwrap(),
- asset.to_ibc_prefixed(),
+ nria().to_ibc_prefixed(),
);
assert_eq!(
app.state
- .get_account_balance(alice_address, &asset)
+ .get_account_balance(alice_address, &nria())
.await
.unwrap(),
before_balance - fee,
@@ -624,15 +625,14 @@ async fn app_execute_transaction_init_bridge_account_ok() {
async fn app_execute_transaction_init_bridge_account_account_already_registered() {
use astria_core::protocol::transaction::v1alpha1::action::InitBridgeAccountAction;
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let mut app = initialize_app(None, vec![]).await;
let rollup_id = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset();
let action = InitBridgeAccountAction {
rollup_id,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
sudo_address: None,
withdrawer_address: None,
};
@@ -645,13 +645,13 @@ async fn app_execute_transaction_init_bridge_account_account_already_registered(
actions: vec![action.into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
let action = InitBridgeAccountAction {
rollup_id,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
sudo_address: None,
withdrawer_address: None,
};
@@ -663,23 +663,23 @@ async fn app_execute_transaction_init_bridge_account_account_already_registered(
actions: vec![action.into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
assert!(app.execute_transaction(signed_tx).await.is_err());
}
#[tokio::test]
async fn app_execute_transaction_bridge_lock_action_ok() {
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
let mut app = initialize_app(None, vec![]).await;
- let bridge_address = crate::address::base_prefixed([99; 20]);
+ let bridge_address = astria_address(&[99; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset().clone();
let mut state_tx = StateDelta::new(app.state.clone());
state_tx.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
state_tx
- .put_bridge_account_ibc_asset(&bridge_address, &asset)
+ .put_bridge_account_ibc_asset(&bridge_address, nria())
.unwrap();
app.apply(state_tx);
@@ -687,8 +687,8 @@ async fn app_execute_transaction_bridge_lock_action_ok() {
let action = BridgeLockAction {
to: bridge_address,
amount,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
destination_chain_address: "nootwashere".to_string(),
};
let tx = UnsignedTransaction {
@@ -699,16 +699,16 @@ async fn app_execute_transaction_bridge_lock_action_ok() {
actions: vec![action.into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
let alice_before_balance = app
.state
- .get_account_balance(alice_address, &asset)
+ .get_account_balance(alice_address, nria())
.await
.unwrap();
let bridge_before_balance = app
.state
- .get_account_balance(bridge_address, &asset)
+ .get_account_balance(bridge_address, nria())
.await
.unwrap();
@@ -719,7 +719,7 @@ async fn app_execute_transaction_bridge_lock_action_ok() {
bridge_address,
rollup_id,
amount,
- asset.clone(),
+ nria().into(),
"nootwashere".to_string(),
);
@@ -732,14 +732,14 @@ async fn app_execute_transaction_bridge_lock_action_ok() {
* crate::bridge::get_deposit_byte_len(&expected_deposit);
assert_eq!(
app.state
- .get_account_balance(alice_address, &asset)
+ .get_account_balance(alice_address, nria())
.await
.unwrap(),
alice_before_balance - (amount + fee)
);
assert_eq!(
app.state
- .get_account_balance(bridge_address, &asset)
+ .get_account_balance(bridge_address, nria())
.await
.unwrap(),
bridge_before_balance + amount
@@ -754,19 +754,18 @@ async fn app_execute_transaction_bridge_lock_action_ok() {
async fn app_execute_transaction_bridge_lock_action_invalid_for_eoa() {
use astria_core::protocol::transaction::v1alpha1::action::BridgeLockAction;
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
let mut app = initialize_app(None, vec![]).await;
// don't actually register this address as a bridge address
- let bridge_address = crate::address::base_prefixed([99; 20]);
- let asset = get_native_asset().clone();
+ let bridge_address = astria_address(&[99; 20]);
let amount = 100;
let action = BridgeLockAction {
to: bridge_address,
amount,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
destination_chain_address: "nootwashere".to_string(),
};
let tx = UnsignedTransaction {
@@ -777,7 +776,7 @@ async fn app_execute_transaction_bridge_lock_action_invalid_for_eoa() {
actions: vec![action.into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
assert!(app.execute_transaction(signed_tx).await.is_err());
}
@@ -785,7 +784,8 @@ async fn app_execute_transaction_bridge_lock_action_invalid_for_eoa() {
async fn app_execute_transaction_invalid_nonce() {
let mut app = initialize_app(None, vec![]).await;
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
// create tx with invalid nonce 1
let data = b"hello world".to_vec();
@@ -798,20 +798,20 @@ async fn app_execute_transaction_invalid_nonce() {
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data,
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
let response = app.execute_transaction(signed_tx).await;
// check that tx was not executed by checking nonce and balance are unchanged
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 0);
assert_eq!(
app.state
- .get_account_balance(alice_address, get_native_asset())
+ .get_account_balance(alice_address, nria())
.await
.unwrap(),
10u128.pow(19),
@@ -831,7 +831,8 @@ async fn app_execute_transaction_invalid_nonce() {
async fn app_execute_transaction_invalid_chain_id() {
let mut app = initialize_app(None, vec![]).await;
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
// create tx with invalid nonce 1
let data = b"hello world".to_vec();
@@ -844,20 +845,20 @@ async fn app_execute_transaction_invalid_chain_id() {
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data,
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
let response = app.execute_transaction(signed_tx).await;
// check that tx was not executed by checking nonce and balance are unchanged
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 0);
assert_eq!(
app.state
- .get_account_balance(alice_address, get_native_asset())
+ .get_account_balance(alice_address, nria())
.await
.unwrap(),
10u128.pow(19),
@@ -881,11 +882,11 @@ async fn app_stateful_check_fails_insufficient_total_balance() {
let mut app = initialize_app(None, vec![]).await;
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
// create a new key; will have 0 balance
let keypair = SigningKey::new(OsRng);
- let keypair_address = crate::address::base_prefixed(keypair.verification_key().address_bytes());
+ let keypair_address = astria_address(&keypair.verification_key().address_bytes());
// figure out needed fee for a single transfer
let data = b"hello world".to_vec();
@@ -903,13 +904,13 @@ async fn app_stateful_check_fails_insufficient_total_balance() {
TransferAction {
to: keypair_address,
amount: fee,
- asset: get_native_asset().clone(),
- fee_asset: get_native_asset().clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
}
.into(),
],
}
- .into_signed(&alice_signing_key);
+ .into_signed(&alice);
// make transfer
app.execute_transaction(Arc::new(signed_tx)).await.unwrap();
@@ -924,13 +925,13 @@ async fn app_stateful_check_fails_insufficient_total_balance() {
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data: data.clone(),
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data: data.clone(),
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
@@ -955,7 +956,7 @@ async fn app_stateful_check_fails_insufficient_total_balance() {
SequenceAction {
rollup_id: RollupId::from_unhashed_bytes(b"testchainid"),
data,
- fee_asset: get_native_asset().clone(),
+ fee_asset: nria().into(),
}
.into(),
],
@@ -971,25 +972,27 @@ async fn app_stateful_check_fails_insufficient_total_balance() {
async fn app_execute_transaction_bridge_lock_unlock_action_ok() {
use crate::accounts::StateWriteExt as _;
- let (alice_signing_key, alice_address) = get_alice_signing_key_and_address();
+ let alice = get_alice_signing_key();
+ let alice_address = astria_address(&alice.address_bytes());
+
let mut app = initialize_app(None, vec![]).await;
let mut state_tx = StateDelta::new(app.state.clone());
- let (bridge_signing_key, bridge_address) = get_bridge_signing_key_and_address();
+ let bridge = get_bridge_signing_key();
+ let bridge_address = astria_address(&bridge.address_bytes());
let rollup_id: RollupId = RollupId::from_unhashed_bytes(b"testchainid");
- let asset = get_native_asset();
// give bridge eoa funds so it can pay for the
// unlock transfer action
let transfer_fee = app.state.get_transfer_base_fee().await.unwrap();
state_tx
- .put_account_balance(bridge_address, asset, transfer_fee)
+ .put_account_balance(bridge_address, nria(), transfer_fee)
.unwrap();
// create bridge account
state_tx.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
state_tx
- .put_bridge_account_ibc_asset(&bridge_address, asset)
+ .put_bridge_account_ibc_asset(&bridge_address, nria())
.unwrap();
state_tx.put_bridge_account_withdrawer_address(&bridge_address, &bridge_address);
app.apply(state_tx);
@@ -998,8 +1001,8 @@ async fn app_execute_transaction_bridge_lock_unlock_action_ok() {
let action = BridgeLockAction {
to: bridge_address,
amount,
- asset: asset.clone(),
- fee_asset: asset.clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
destination_chain_address: "nootwashere".to_string(),
};
let tx = UnsignedTransaction {
@@ -1010,7 +1013,7 @@ async fn app_execute_transaction_bridge_lock_unlock_action_ok() {
actions: vec![action.into()],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
app.execute_transaction(signed_tx).await.unwrap();
assert_eq!(app.state.get_account_nonce(alice_address).await.unwrap(), 1);
@@ -1019,7 +1022,7 @@ async fn app_execute_transaction_bridge_lock_unlock_action_ok() {
let action = BridgeUnlockAction {
to: alice_address,
amount,
- fee_asset: asset.clone(),
+ fee_asset: nria().into(),
memo: "{ \"msg\": \"lilywashere\" }".into(),
bridge_address: None,
};
@@ -1032,13 +1035,13 @@ async fn app_execute_transaction_bridge_lock_unlock_action_ok() {
actions: vec![action.into()],
};
- let signed_tx = Arc::new(tx.into_signed(&bridge_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&bridge));
app.execute_transaction(signed_tx)
.await
.expect("executing bridge unlock action should succeed");
assert_eq!(
app.state
- .get_account_balance(bridge_address, asset)
+ .get_account_balance(bridge_address, nria())
.await
.expect("executing bridge unlock action should succeed"),
0,
@@ -1051,8 +1054,8 @@ async fn transaction_execution_records_fee_event() {
let mut app = initialize_app(None, vec![]).await;
// transfer funds from Alice to Bob
- let (alice_signing_key, _) = get_alice_signing_key_and_address();
- let bob_address = address_from_hex_string(BOB_ADDRESS);
+ let alice = get_alice_signing_key();
+ let bob_address = astria_address_from_hex_string(BOB_ADDRESS);
let value = 333_333;
let tx = UnsignedTransaction {
params: TransactionParams::builder()
@@ -1063,14 +1066,14 @@ async fn transaction_execution_records_fee_event() {
TransferAction {
to: bob_address,
amount: value,
- asset: get_native_asset().clone(),
- fee_asset: get_native_asset().clone(),
+ asset: nria().into(),
+ fee_asset: nria().into(),
}
.into(),
],
};
- let signed_tx = Arc::new(tx.into_signed(&alice_signing_key));
+ let signed_tx = Arc::new(tx.into_signed(&alice));
let events = app.execute_transaction(signed_tx).await.unwrap();
let transfer_fee = app.state.get_transfer_base_fee().await.unwrap();
@@ -1078,7 +1081,7 @@ async fn transaction_execution_records_fee_event() {
assert_eq!(event.kind, "tx.fees");
assert_eq!(
event.attributes[0],
- ("asset", get_native_asset().to_string()).index().into()
+ ("asset", nria().to_string()).index().into()
);
assert_eq!(
event.attributes[1],
diff --git a/crates/astria-sequencer/src/assets/mod.rs b/crates/astria-sequencer/src/assets/mod.rs
index 12468148f..cd334f0de 100644
--- a/crates/astria-sequencer/src/assets/mod.rs
+++ b/crates/astria-sequencer/src/assets/mod.rs
@@ -1,58 +1,7 @@
pub(crate) mod query;
mod state_ext;
-use std::sync::OnceLock;
-
-use astria_core::primitive::v1::asset::Denom;
-#[cfg(test)]
-pub(crate) use intests::*;
-#[cfg(not(test))]
-pub(crate) use regular::*;
pub(crate) use state_ext::{
StateReadExt,
StateWriteExt,
};
-
-pub(crate) static NATIVE_ASSET: OnceLock = OnceLock::new();
-
-#[cfg(not(test))]
-mod regular {
-
- pub(crate) fn initialize_native_asset(native_asset: &str) {
- if super::NATIVE_ASSET.get().is_some() {
- tracing::error!("native asset should only be set once");
- return;
- }
-
- let denom = native_asset
- .parse()
- .expect("being unable to parse the native asset breaks sequencer");
- super::NATIVE_ASSET
- .set(denom)
- .expect("native asset should only be set once");
- }
-
- pub(crate) fn get_native_asset() -> &'static super::Denom {
- super::NATIVE_ASSET
- .get()
- .expect("native asset should be set")
- }
-}
-
-#[cfg(test)]
-mod intests {
- pub(crate) fn initialize_native_asset(native_asset: &str) {
- assert_eq!(
- "nria", native_asset,
- "all tests should be initialized with \"nria\" as the native asset"
- );
- }
-
- pub(crate) fn get_native_asset() -> &'static super::Denom {
- super::NATIVE_ASSET.get_or_init(|| {
- "nria"
- .parse()
- .expect("being unable to parse the native asset breaks sequencer")
- })
- }
-}
diff --git a/crates/astria-sequencer/src/authority/action.rs b/crates/astria-sequencer/src/authority/action.rs
index 60611fff7..baf6220db 100644
--- a/crates/astria-sequencer/src/authority/action.rs
+++ b/crates/astria-sequencer/src/authority/action.rs
@@ -16,16 +16,14 @@ use astria_core::{
use tracing::instrument;
use crate::{
- authority::{
- StateReadExt,
- StateWriteExt,
- },
+ address,
+ authority,
transaction::action_handler::ActionHandler,
};
#[async_trait::async_trait]
impl ActionHandler for ValidatorUpdate {
- async fn check_stateful(
+ async fn check_stateful(
&self,
state: &S,
from: Address,
@@ -58,7 +56,11 @@ impl ActionHandler for ValidatorUpdate {
}
#[instrument(skip_all)]
- async fn execute(&self, state: &mut S, _: Address) -> Result<()> {
+ async fn execute(
+ &self,
+ state: &mut S,
+ _: Address,
+ ) -> Result<()> {
// add validator update in non-consensus state to be used in end_block
let mut validator_updates = state
.get_validator_updates()
@@ -75,18 +77,20 @@ impl ActionHandler for ValidatorUpdate {
#[async_trait::async_trait]
impl ActionHandler for SudoAddressChangeAction {
async fn check_stateless(&self) -> Result<()> {
- crate::address::ensure_base_prefix(&self.new_address)
- .context("desired new sudo address has an unsupported prefix")?;
Ok(())
}
/// check that the signer of the transaction is the current sudo address,
/// as only that address can change the sudo address
- async fn check_stateful(
+ async fn check_stateful(
&self,
state: &S,
from: Address,
) -> Result<()> {
+ state
+ .ensure_base_prefix(&self.new_address)
+ .await
+ .context("desired new sudo address has an unsupported prefix")?;
// ensure signer is the valid `sudo` key in state
let sudo_address = state
.get_sudo_address()
@@ -97,7 +101,7 @@ impl ActionHandler for SudoAddressChangeAction {
}
#[instrument(skip_all)]
- async fn execute(&self, state: &mut S, _: Address) -> Result<()> {
+ async fn execute(&self, state: &mut S, _: Address) -> Result<()> {
state
.put_sudo_address(self.new_address)
.context("failed to put sudo address in state")?;
@@ -109,7 +113,7 @@ impl ActionHandler for SudoAddressChangeAction {
impl ActionHandler for FeeChangeAction {
/// check that the signer of the transaction is the current sudo address,
/// as only that address can change the fee
- async fn check_stateful(
+ async fn check_stateful(
&self,
state: &S,
from: Address,
@@ -124,7 +128,7 @@ impl ActionHandler for FeeChangeAction {
}
#[instrument(skip_all)]
- async fn execute(&self, state: &mut S, _: Address) -> Result<()> {
+ async fn execute(&self, state: &mut S, _: Address) -> Result<()> {
use crate::{
accounts::StateWriteExt as _,
bridge::StateWriteExt as _,
@@ -184,6 +188,7 @@ mod test {
StateReadExt as _,
StateWriteExt as _,
},
+ test_utils::astria_address,
};
#[tokio::test]
@@ -200,7 +205,7 @@ mod test {
};
fee_change
- .execute(&mut state, crate::address::base_prefixed([1; 20]))
+ .execute(&mut state, astria_address(&[1; 20]))
.await
.unwrap();
assert_eq!(state.get_transfer_base_fee().await.unwrap(), 10);
@@ -214,7 +219,7 @@ mod test {
};
fee_change
- .execute(&mut state, crate::address::base_prefixed([1; 20]))
+ .execute(&mut state, astria_address(&[1; 20]))
.await
.unwrap();
assert_eq!(state.get_sequence_action_base_fee().await.unwrap(), 3);
@@ -228,7 +233,7 @@ mod test {
};
fee_change
- .execute(&mut state, crate::address::base_prefixed([1; 20]))
+ .execute(&mut state, astria_address(&[1; 20]))
.await
.unwrap();
assert_eq!(
@@ -248,7 +253,7 @@ mod test {
};
fee_change
- .execute(&mut state, crate::address::base_prefixed([1; 20]))
+ .execute(&mut state, astria_address(&[1; 20]))
.await
.unwrap();
assert_eq!(state.get_init_bridge_account_base_fee().await.unwrap(), 2);
@@ -262,7 +267,7 @@ mod test {
};
fee_change
- .execute(&mut state, crate::address::base_prefixed([1; 20]))
+ .execute(&mut state, astria_address(&[1; 20]))
.await
.unwrap();
assert_eq!(
@@ -281,7 +286,7 @@ mod test {
};
fee_change
- .execute(&mut state, crate::address::base_prefixed([1; 20]))
+ .execute(&mut state, astria_address(&[1; 20]))
.await
.unwrap();
assert_eq!(state.get_ics20_withdrawal_base_fee().await.unwrap(), 2);
diff --git a/crates/astria-sequencer/src/authority/state_ext.rs b/crates/astria-sequencer/src/authority/state_ext.rs
index 20601c443..afdb4856a 100644
--- a/crates/astria-sequencer/src/authority/state_ext.rs
+++ b/crates/astria-sequencer/src/authority/state_ext.rs
@@ -21,6 +21,7 @@ use cnidarium::{
use tracing::instrument;
use super::ValidatorSet;
+use crate::address;
/// Newtype wrapper to read and write an address from rocksdb.
#[derive(BorshSerialize, BorshDeserialize, Debug)]
@@ -31,7 +32,7 @@ const VALIDATOR_SET_STORAGE_KEY: &str = "valset";
const VALIDATOR_UPDATES_KEY: &[u8] = b"valupdates";
#[async_trait]
-pub(crate) trait StateReadExt: StateRead {
+pub(crate) trait StateReadExt: StateRead + address::StateReadExt {
#[instrument(skip_all)]
async fn get_sudo_address(&self) -> Result {
let Some(bytes) = self
@@ -44,7 +45,9 @@ pub(crate) trait StateReadExt: StateRead {
};
let SudoAddress(address_bytes) =
SudoAddress::try_from_slice(&bytes).context("invalid sudo key bytes")?;
- Ok(crate::address::base_prefixed(address_bytes))
+ self.try_base_prefixed(&address_bytes)
+ .await
+ .context("failed constructing address from prefixed stored in state")
}
#[instrument(skip_all)]
@@ -122,7 +125,7 @@ pub(crate) trait StateWriteExt: StateWrite {
impl StateWriteExt for T {}
#[cfg(test)]
-mod test {
+mod tests {
use astria_core::protocol::transaction::v1alpha1::action::ValidatorUpdate;
use cnidarium::StateDelta;
@@ -131,8 +134,13 @@ mod test {
StateWriteExt as _,
};
use crate::{
+ address::StateWriteExt as _,
authority::ValidatorSet,
- test_utils::verification_key,
+ test_utils::{
+ astria_address,
+ verification_key,
+ ASTRIA_PREFIX,
+ },
};
fn empty_validator_set() -> ValidatorSet {
@@ -145,6 +153,8 @@ mod test {
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
// doesn't exist at first
state
.get_sudo_address()
@@ -152,7 +162,7 @@ mod test {
.expect_err("no sudo address should exist at first");
// can write new
- let mut address_expected = crate::address::base_prefixed([42u8; 20]);
+ let mut address_expected = astria_address(&[42u8; 20]);
state
.put_sudo_address(address_expected)
.expect("writing sudo address should not fail");
@@ -166,7 +176,7 @@ mod test {
);
// can rewrite with new value
- address_expected = crate::address::base_prefixed([41u8; 20]);
+ address_expected = astria_address(&[41u8; 20]);
state
.put_sudo_address(address_expected)
.expect("writing sudo address should not fail");
diff --git a/crates/astria-sequencer/src/bridge/bridge_lock_action.rs b/crates/astria-sequencer/src/bridge/bridge_lock_action.rs
index 4daa373f3..232659315 100644
--- a/crates/astria-sequencer/src/bridge/bridge_lock_action.rs
+++ b/crates/astria-sequencer/src/bridge/bridge_lock_action.rs
@@ -19,6 +19,7 @@ use crate::{
StateReadExt as _,
StateWriteExt as _,
},
+ address,
bridge::{
StateReadExt as _,
StateWriteExt as _,
@@ -33,16 +34,18 @@ use crate::{
#[async_trait::async_trait]
impl ActionHandler for BridgeLockAction {
async fn check_stateless(&self) -> Result<()> {
- crate::address::ensure_base_prefix(&self.to)
- .context("destination address has an unsupported prefix")?;
Ok(())
}
- async fn check_stateful(
+ async fn check_stateful(
&self,
state: &S,
from: Address,
) -> Result<()> {
+ state
+ .ensure_base_prefix(&self.to)
+ .await
+ .context("failed check for base prefix of destination address")?;
let transfer_action = TransferAction {
to: self.to,
asset: self.asset.clone(),
@@ -154,6 +157,7 @@ pub(crate) fn get_deposit_byte_len(deposit: &Deposit) -> u128 {
#[cfg(test)]
mod tests {
+ use address::StateWriteExt;
use astria_core::primitive::v1::{
asset,
RollupId,
@@ -161,7 +165,13 @@ mod tests {
use cnidarium::StateDelta;
use super::*;
- use crate::assets::StateWriteExt as _;
+ use crate::{
+ assets::StateWriteExt as _,
+ test_utils::{
+ astria_address,
+ ASTRIA_PREFIX,
+ },
+ };
fn test_asset() -> asset::Denom {
"test".parse().unwrap()
@@ -173,10 +183,12 @@ mod tests {
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
let transfer_fee = 12;
+
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
state.put_transfer_base_fee(transfer_fee).unwrap();
state.put_bridge_lock_byte_cost_multiplier(2);
- let bridge_address = crate::address::base_prefixed([1; 20]);
+ let bridge_address = astria_address(&[1; 20]);
let asset = test_asset();
let bridge_lock = BridgeLockAction {
to: bridge_address,
@@ -193,12 +205,13 @@ mod tests {
.unwrap();
state.put_allowed_fee_asset(&asset);
- let from_address = crate::address::base_prefixed([2; 20]);
+ let from_address = astria_address(&[2; 20]);
// not enough balance; should fail
state
.put_account_balance(from_address, &asset, 100)
.unwrap();
+
assert!(
bridge_lock
.check_stateful(&state, from_address)
@@ -235,7 +248,7 @@ mod tests {
state.put_transfer_base_fee(transfer_fee).unwrap();
state.put_bridge_lock_byte_cost_multiplier(2);
- let bridge_address = crate::address::base_prefixed([1; 20]);
+ let bridge_address = astria_address(&[1; 20]);
let asset = test_asset();
let bridge_lock = BridgeLockAction {
to: bridge_address,
@@ -252,7 +265,7 @@ mod tests {
.unwrap();
state.put_allowed_fee_asset(&asset);
- let from_address = crate::address::base_prefixed([2; 20]);
+ let from_address = astria_address(&[2; 20]);
// not enough balance; should fail
state
diff --git a/crates/astria-sequencer/src/bridge/bridge_sudo_change_action.rs b/crates/astria-sequencer/src/bridge/bridge_sudo_change_action.rs
index 13e21012c..518a9417e 100644
--- a/crates/astria-sequencer/src/bridge/bridge_sudo_change_action.rs
+++ b/crates/astria-sequencer/src/bridge/bridge_sudo_change_action.rs
@@ -11,6 +11,7 @@ use tracing::instrument;
use crate::{
accounts::StateWriteExt as _,
+ address,
assets::StateReadExt as _,
bridge::state_ext::{
StateReadExt as _,
@@ -26,26 +27,31 @@ use crate::{
#[async_trait::async_trait]
impl ActionHandler for BridgeSudoChangeAction {
async fn check_stateless(&self) -> Result<()> {
- crate::address::ensure_base_prefix(&self.bridge_address)
- .context("bridge address has an unsupported prefix")?;
- self.new_sudo_address
- .as_ref()
- .map(crate::address::ensure_base_prefix)
- .transpose()
- .context("new sudo address has an unsupported prefix")?;
- self.new_withdrawer_address
- .as_ref()
- .map(crate::address::ensure_base_prefix)
- .transpose()
- .context("new withdrawer address has an unsupported prefix")?;
Ok(())
}
- async fn check_stateful(
+ async fn check_stateful(
&self,
state: &S,
from: Address,
) -> Result<()> {
+ state
+ .ensure_base_prefix(&self.bridge_address)
+ .await
+ .context("failed check for base prefix of bridge address")?;
+ if let Some(new_sudo_address) = &self.new_sudo_address {
+ state
+ .ensure_base_prefix(new_sudo_address)
+ .await
+ .context("failed check for base prefix of new sudo address")?;
+ }
+ if let Some(new_withdrawer_address) = &self.new_withdrawer_address {
+ state
+ .ensure_base_prefix(new_withdrawer_address)
+ .await
+ .context("failed check for base prefix of new withdrawer address")?;
+ }
+
ensure!(
state
.is_allowed_fee_asset(&self.fee_asset)
@@ -98,27 +104,36 @@ impl ActionHandler for BridgeSudoChangeAction {
#[cfg(test)]
mod tests {
+ use address::StateWriteExt;
use astria_core::primitive::v1::asset;
use cnidarium::StateDelta;
use super::*;
- use crate::assets::StateWriteExt as _;
+ use crate::{
+ assets::StateWriteExt as _,
+ test_utils::{
+ astria_address,
+ ASTRIA_PREFIX,
+ },
+ };
fn test_asset() -> asset::Denom {
"test".parse().unwrap()
}
#[tokio::test]
- async fn bridge_sudo_change_check_stateless_ok() {
+ async fn check_stateless_ok() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
let asset = test_asset();
state.put_allowed_fee_asset(&asset);
- let bridge_address = crate::address::base_prefixed([99; 20]);
- let sudo_address = crate::address::base_prefixed([98; 20]);
+ let bridge_address = astria_address(&[99; 20]);
+ let sudo_address = astria_address(&[98; 20]);
state.put_bridge_account_sudo_address(&bridge_address, &sudo_address);
let action = BridgeSudoChangeAction {
@@ -132,16 +147,18 @@ mod tests {
}
#[tokio::test]
- async fn bridge_sudo_change_check_stateless_unauthorized() {
+ async fn check_stateless_unauthorized() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
let asset = test_asset();
state.put_allowed_fee_asset(&asset);
- let bridge_address = crate::address::base_prefixed([99; 20]);
- let sudo_address = crate::address::base_prefixed([98; 20]);
+ let bridge_address = astria_address(&[99; 20]);
+ let sudo_address = astria_address(&[98; 20]);
state.put_bridge_account_sudo_address(&bridge_address, &sudo_address);
let action = BridgeSudoChangeAction {
@@ -162,16 +179,18 @@ mod tests {
}
#[tokio::test]
- async fn bridge_sudo_change_execute_ok() {
+ async fn execute_ok() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
state.put_bridge_sudo_change_base_fee(10);
let fee_asset = test_asset();
- let bridge_address = crate::address::base_prefixed([99; 20]);
- let new_sudo_address = crate::address::base_prefixed([98; 20]);
- let new_withdrawer_address = crate::address::base_prefixed([97; 20]);
+ let bridge_address = astria_address(&[99; 20]);
+ let new_sudo_address = astria_address(&[98; 20]);
+ let new_withdrawer_address = astria_address(&[97; 20]);
state
.put_account_balance(bridge_address, &fee_asset, 10)
.unwrap();
diff --git a/crates/astria-sequencer/src/bridge/bridge_unlock_action.rs b/crates/astria-sequencer/src/bridge/bridge_unlock_action.rs
index f6f45937c..550cf5dce 100644
--- a/crates/astria-sequencer/src/bridge/bridge_unlock_action.rs
+++ b/crates/astria-sequencer/src/bridge/bridge_unlock_action.rs
@@ -15,6 +15,7 @@ use tracing::instrument;
use crate::{
accounts::action::transfer_check_stateful,
+ address,
bridge::StateReadExt as _,
state_ext::{
StateReadExt,
@@ -26,21 +27,25 @@ use crate::{
#[async_trait::async_trait]
impl ActionHandler for BridgeUnlockAction {
async fn check_stateless(&self) -> Result<()> {
- crate::address::ensure_base_prefix(&self.to)
- .context("destination address has an unsupported prefix")?;
- self.bridge_address
- .as_ref()
- .map(crate::address::ensure_base_prefix)
- .transpose()
- .context("bridge address has an unsupported prefix")?;
Ok(())
}
- async fn check_stateful(
+ async fn check_stateful(
&self,
state: &S,
from: Address,
) -> Result<()> {
+ state
+ .ensure_base_prefix(&self.to)
+ .await
+ .context("failed check for base prefix of destination address")?;
+ if let Some(bridge_address) = &self.bridge_address {
+ state
+ .ensure_base_prefix(bridge_address)
+ .await
+ .context("failed check for base prefix of bridge address")?;
+ }
+
// the bridge address to withdraw funds from
// if unset, use the tx sender's address
let bridge_address = self.bridge_address.unwrap_or(from);
@@ -113,8 +118,13 @@ mod test {
use super::*;
use crate::{
accounts::StateWriteExt as _,
+ address::StateWriteExt as _,
assets::StateWriteExt as _,
- bridge::StateWriteExt,
+ bridge::StateWriteExt as _,
+ test_utils::{
+ astria_address,
+ ASTRIA_PREFIX,
+ },
};
fn test_asset() -> asset::Denom {
@@ -122,16 +132,18 @@ mod test {
}
#[tokio::test]
- async fn bridge_unlock_fail_non_bridge_accounts() {
+ async fn fail_non_bridge_accounts() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
- let state = StateDelta::new(snapshot);
+ let mut state = StateDelta::new(snapshot);
+
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
let asset = test_asset();
let transfer_amount = 100;
- let address = crate::address::base_prefixed([1; 20]);
- let to_address = crate::address::base_prefixed([2; 20]);
+ let address = astria_address(&[1; 20]);
+ let to_address = astria_address(&[2; 20]);
let bridge_unlock = BridgeUnlockAction {
to: to_address,
@@ -153,18 +165,20 @@ mod test {
}
#[tokio::test]
- async fn bridge_unlock_fail_withdrawer_unset_invalid_withdrawer() {
+ async fn fail_withdrawer_unset_invalid_withdrawer() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
let asset = test_asset();
let transfer_amount = 100;
- let sender_address = crate::address::base_prefixed([1; 20]);
- let to_address = crate::address::base_prefixed([2; 20]);
+ let sender_address = astria_address(&[1; 20]);
+ let to_address = astria_address(&[2; 20]);
- let bridge_address = crate::address::base_prefixed([3; 20]);
+ let bridge_address = astria_address(&[3; 20]);
state
.put_bridge_account_ibc_asset(&bridge_address, &asset)
.unwrap();
@@ -190,19 +204,21 @@ mod test {
}
#[tokio::test]
- async fn bridge_unlock_fail_withdrawer_set_invalid_withdrawer() {
+ async fn fail_withdrawer_set_invalid_withdrawer() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
let asset = test_asset();
let transfer_amount = 100;
- let sender_address = crate::address::base_prefixed([1; 20]);
- let to_address = crate::address::base_prefixed([2; 20]);
+ let sender_address = astria_address(&[1; 20]);
+ let to_address = astria_address(&[2; 20]);
- let bridge_address = crate::address::base_prefixed([3; 20]);
- let withdrawer_address = crate::address::base_prefixed([4; 20]);
+ let bridge_address = astria_address(&[3; 20]);
+ let withdrawer_address = astria_address(&[4; 20]);
state.put_bridge_account_withdrawer_address(&bridge_address, &withdrawer_address);
state
.put_bridge_account_ibc_asset(&bridge_address, &asset)
@@ -228,18 +244,20 @@ mod test {
}
#[tokio::test]
- async fn bridge_unlock_fee_check_stateful_from_none() {
+ async fn fee_check_stateful_from_none() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
let asset = test_asset();
let transfer_fee = 10;
let transfer_amount = 100;
state.put_transfer_base_fee(transfer_fee).unwrap();
- let bridge_address = crate::address::base_prefixed([1; 20]);
- let to_address = crate::address::base_prefixed([2; 20]);
+ let bridge_address = astria_address(&[1; 20]);
+ let to_address = astria_address(&[2; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"test_rollup_id");
state.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
@@ -281,18 +299,20 @@ mod test {
}
#[tokio::test]
- async fn bridge_unlock_fee_check_stateful_from_some() {
+ async fn fee_check_stateful_from_some() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
let asset = test_asset();
let transfer_fee = 10;
let transfer_amount = 100;
state.put_transfer_base_fee(transfer_fee).unwrap();
- let bridge_address = crate::address::base_prefixed([1; 20]);
- let to_address = crate::address::base_prefixed([2; 20]);
+ let bridge_address = astria_address(&[1; 20]);
+ let to_address = astria_address(&[2; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"test_rollup_id");
state.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
@@ -301,7 +321,7 @@ mod test {
.unwrap();
state.put_allowed_fee_asset(&asset);
- let withdrawer_address = crate::address::base_prefixed([3; 20]);
+ let withdrawer_address = astria_address(&[3; 20]);
state.put_bridge_account_withdrawer_address(&bridge_address, &withdrawer_address);
let bridge_unlock = BridgeUnlockAction {
@@ -336,7 +356,7 @@ mod test {
}
#[tokio::test]
- async fn bridge_unlock_execute_from_none() {
+ async fn execute_from_none() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
@@ -346,8 +366,8 @@ mod test {
let transfer_amount = 100;
state.put_transfer_base_fee(transfer_fee).unwrap();
- let bridge_address = crate::address::base_prefixed([1; 20]);
- let to_address = crate::address::base_prefixed([2; 20]);
+ let bridge_address = astria_address(&[1; 20]);
+ let to_address = astria_address(&[2; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"test_rollup_id");
state.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
@@ -388,7 +408,7 @@ mod test {
}
#[tokio::test]
- async fn bridge_unlock_execute_from_some() {
+ async fn execute_from_some() {
let storage = cnidarium::TempStorage::new().await.unwrap();
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
@@ -398,8 +418,8 @@ mod test {
let transfer_amount = 100;
state.put_transfer_base_fee(transfer_fee).unwrap();
- let bridge_address = crate::address::base_prefixed([1; 20]);
- let to_address = crate::address::base_prefixed([2; 20]);
+ let bridge_address = astria_address(&[1; 20]);
+ let to_address = astria_address(&[2; 20]);
let rollup_id = RollupId::from_unhashed_bytes(b"test_rollup_id");
state.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
diff --git a/crates/astria-sequencer/src/bridge/init_bridge_account_action.rs b/crates/astria-sequencer/src/bridge/init_bridge_account_action.rs
index a116771e1..986a314bf 100644
--- a/crates/astria-sequencer/src/bridge/init_bridge_account_action.rs
+++ b/crates/astria-sequencer/src/bridge/init_bridge_account_action.rs
@@ -15,6 +15,7 @@ use crate::{
StateReadExt as _,
StateWriteExt as _,
},
+ address,
assets::StateReadExt as _,
bridge::state_ext::{
StateReadExt as _,
@@ -30,26 +31,27 @@ use crate::{
#[async_trait::async_trait]
impl ActionHandler for InitBridgeAccountAction {
async fn check_stateless(&self) -> Result<()> {
- self.withdrawer_address
- .as_ref()
- .map(crate::address::ensure_base_prefix)
- .transpose()
- .context("the withdrawer address has an unsupported prefix")?;
-
- self.sudo_address
- .as_ref()
- .map(crate::address::ensure_base_prefix)
- .transpose()
- .context("the sudo address has an unsupported")?;
-
Ok(())
}
- async fn check_stateful(
+ async fn check_stateful(
&self,
state: &S,
from: Address,
) -> Result<()> {
+ if let Some(withdrawer_address) = &self.withdrawer_address {
+ state
+ .ensure_base_prefix(withdrawer_address)
+ .await
+ .context("failed check for base prefix of withdrawer address")?;
+ }
+ if let Some(sudo_address) = &self.sudo_address {
+ state
+ .ensure_base_prefix(sudo_address)
+ .await
+ .context("failed check for base prefix of sudo address")?;
+ }
+
ensure!(
state.is_allowed_fee_asset(&self.fee_asset).await?,
"invalid fee asset",
diff --git a/crates/astria-sequencer/src/bridge/query.rs b/crates/astria-sequencer/src/bridge/query.rs
index 2a64baf39..3ea29d867 100644
--- a/crates/astria-sequencer/src/bridge/query.rs
+++ b/crates/astria-sequencer/src/bridge/query.rs
@@ -269,9 +269,14 @@ mod test {
use super::*;
use crate::{
- assets::StateWriteExt,
+ address::StateWriteExt as _,
+ assets::StateWriteExt as _,
bridge::StateWriteExt as _,
state_ext::StateWriteExt as _,
+ test_utils::{
+ astria_address,
+ ASTRIA_PREFIX,
+ },
};
#[tokio::test]
@@ -280,11 +285,13 @@ mod test {
let snapshot = storage.latest_snapshot();
let mut state = StateDelta::new(snapshot);
+ state.put_base_prefix(ASTRIA_PREFIX).unwrap();
+
let asset: astria_core::primitive::v1::asset::Denom = "test".parse().unwrap();
let rollup_id = RollupId::from_unhashed_bytes("test");
- let bridge_address = crate::address::base_prefixed([0u8; 20]);
- let sudo_address = crate::address::base_prefixed([1u8; 20]);
- let withdrawer_address = crate::address::base_prefixed([2u8; 20]);
+ let bridge_address = astria_address(&[0u8; 20]);
+ let sudo_address = astria_address(&[1u8; 20]);
+ let withdrawer_address = astria_address(&[2u8; 20]);
state.put_block_height(1);
state.put_bridge_account_rollup_id(&bridge_address, &rollup_id);
state
diff --git a/crates/astria-sequencer/src/bridge/state_ext.rs b/crates/astria-sequencer/src/bridge/state_ext.rs
index a4ad85d2c..3b8ba0b5f 100644
--- a/crates/astria-sequencer/src/bridge/state_ext.rs
+++ b/crates/astria-sequencer/src/bridge/state_ext.rs
@@ -34,6 +34,8 @@ use tracing::{
instrument,
};
+use crate::address;
+
/// Newtype wrapper to read and write a u128 from rocksdb.
#[derive(BorshSerialize, BorshDeserialize, Debug)]
struct Balance(u128);
@@ -139,7 +141,7 @@ fn last_transaction_hash_for_bridge_account_storage_key(address: &Address) -> Ve
}
#[async_trait]
-pub(crate) trait StateReadExt: StateRead {
+pub(crate) trait StateReadExt: StateRead + address::StateReadExt {
#[instrument(skip_all)]
async fn get_bridge_account_rollup_id(&self, address: &Address) -> Result