Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(sequencer): Move all storage keys to a single parent module (ENG-813) #1548

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

101 changes: 22 additions & 79 deletions crates/astria-sequencer/src/accounts/state_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ use pin_project_lite::pin_project;
use tracing::instrument;

use super::AddressBytes;
use crate::storage::verifiable_keys::accounts::{
balance_key,
balance_prefix,
extract_asset_from_key,
nonce_key,
TRANSFER_BASE_FEE_KEY,
};

/// Newtype wrapper to read and write a u32 from rocksdb.
#[derive(BorshSerialize, BorshDeserialize, Debug)]
Expand All @@ -44,36 +51,6 @@ struct Balance(u128);
#[derive(BorshSerialize, BorshDeserialize, Debug)]
struct Fee(u128);

const ACCOUNTS_PREFIX: &str = "accounts";
const TRANSFER_BASE_FEE_STORAGE_KEY: &str = "transferfee";

struct StorageKey<'a, T>(&'a T);
impl<'a, T: AddressBytes> std::fmt::Display for StorageKey<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(ACCOUNTS_PREFIX)?;
f.write_str("/")?;
for byte in self.0.address_bytes() {
f.write_fmt(format_args!("{byte:02x}"))?;
}
Ok(())
}
}

fn balance_storage_key<TAddress: AddressBytes, TAsset: Into<asset::IbcPrefixed>>(
address: TAddress,
asset: TAsset,
) -> String {
format!(
"{}/balance/{}",
StorageKey(&address),
crate::storage_keys::hunks::Asset::from(asset)
)
}

fn nonce_storage_key<T: AddressBytes>(address: T) -> String {
format!("{}/nonce", StorageKey(&address))
}

pin_project! {
/// A stream of IBC prefixed assets for a given account.
pub(crate) struct AccountAssetsStream<St> {
Expand Down Expand Up @@ -153,23 +130,14 @@ where
}
}

fn extract_asset_from_key(s: &str) -> Result<asset::IbcPrefixed> {
Ok(s.strip_prefix("accounts/")
.and_then(|s| s.split_once("/balance/").map(|(_, asset)| asset))
.ok_or_eyre("failed to strip prefix from account balance key")?
.parse::<crate::storage_keys::hunks::Asset>()
.context("failed to parse storage key suffix as address hunk")?
.get())
}

#[async_trait]
pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt {
#[instrument(skip_all)]
fn account_asset_keys(
&self,
address: impl AddressBytes,
) -> AccountAssetsStream<Self::PrefixKeysStream> {
let prefix = format!("{}/balance/", StorageKey(&address));
let prefix = balance_prefix(&address);
AccountAssetsStream {
underlying: self.prefix_keys(&prefix),
}
Expand All @@ -180,7 +148,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt {
&self,
address: impl AddressBytes,
) -> AccountAssetBalancesStream<Self::PrefixRawStream> {
let prefix = format!("{}/balance/", StorageKey(&address));
let prefix = balance_prefix(&address);
AccountAssetBalancesStream {
underlying: self.prefix_raw(&prefix),
}
Expand All @@ -199,7 +167,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt {
TAsset: Into<asset::IbcPrefixed> + std::fmt::Display + Send,
{
let Some(bytes) = self
.get_raw(&balance_storage_key(address, asset))
.get_raw(&balance_key(address, asset))
.await
.map_err(anyhow_to_eyre)
.wrap_err("failed reading raw account balance from state")?
Expand All @@ -213,7 +181,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt {
#[instrument(skip_all)]
async fn get_account_nonce<T: AddressBytes>(&self, address: T) -> Result<u32> {
let bytes = self
.get_raw(&nonce_storage_key(address))
.get_raw(&nonce_key(&address))
.await
.map_err(anyhow_to_eyre)
.wrap_err("failed reading raw account nonce from state")?;
Expand All @@ -229,7 +197,7 @@ pub(crate) trait StateReadExt: StateRead + crate::assets::StateReadExt {
#[instrument(skip_all)]
async fn get_transfer_base_fee(&self) -> Result<u128> {
let bytes = self
.get_raw(TRANSFER_BASE_FEE_STORAGE_KEY)
.get_raw(TRANSFER_BASE_FEE_KEY)
.await
.map_err(anyhow_to_eyre)
.wrap_err("failed reading raw transfer base fee from state")?;
Expand Down Expand Up @@ -257,15 +225,15 @@ pub(crate) trait StateWriteExt: StateWrite {
TAddress: AddressBytes,
TAsset: Into<asset::IbcPrefixed> + std::fmt::Display + Send,
{
let bytes = borsh::to_vec(&Balance(balance)).wrap_err("failed to serialize balance")?;
self.put_raw(balance_storage_key(address, asset), bytes);
let bytes = borsh::to_vec(&Balance(balance)).context("failed to serialize balance")?;
self.put_raw(balance_key(address, asset), bytes);
Ok(())
}

#[instrument(skip_all)]
fn put_account_nonce<T: AddressBytes>(&mut self, address: T, nonce: u32) -> Result<()> {
let bytes = borsh::to_vec(&Nonce(nonce)).wrap_err("failed to serialize nonce")?;
self.put_raw(nonce_storage_key(address), bytes);
let bytes = borsh::to_vec(&Nonce(nonce)).context("failed to serialize nonce")?;
self.put_raw(nonce_key(&address), bytes);
Ok(())
}

Expand Down Expand Up @@ -327,8 +295,8 @@ pub(crate) trait StateWriteExt: StateWrite {

#[instrument(skip_all)]
fn put_transfer_base_fee(&mut self, fee: u128) -> Result<()> {
let bytes = borsh::to_vec(&Fee(fee)).wrap_err("failed to serialize fee")?;
self.put_raw(TRANSFER_BASE_FEE_STORAGE_KEY.to_string(), bytes);
let bytes = borsh::to_vec(&Fee(fee)).context("failed to serialize fee")?;
self.put_raw(TRANSFER_BASE_FEE_KEY.to_string(), bytes);
Ok(())
}
}
Expand All @@ -337,20 +305,11 @@ impl<T: StateWrite> StateWriteExt for T {}

#[cfg(test)]
mod tests {
use astria_core::primitive::v1::Address;
use cnidarium::StateDelta;
use futures::TryStreamExt as _;
use insta::assert_snapshot;

use super::{
StateReadExt as _,
StateWriteExt as _,
};
use super::*;
use crate::{
accounts::state_ext::{
balance_storage_key,
nonce_storage_key,
},
assets::{
StateReadExt as _,
StateWriteExt as _,
Expand All @@ -361,14 +320,14 @@ mod tests {
},
};

fn asset_0() -> astria_core::primitive::v1::asset::Denom {
fn asset_0() -> asset::Denom {
"asset_0".parse().unwrap()
}

fn asset_1() -> astria_core::primitive::v1::asset::Denom {
fn asset_1() -> asset::Denom {
"asset_1".parse().unwrap()
}
fn asset_2() -> astria_core::primitive::v1::asset::Denom {
fn asset_2() -> asset::Denom {
"asset_2".parse().unwrap()
}

Expand Down Expand Up @@ -832,20 +791,4 @@ mod tests {
.await
.expect_err("should not be able to subtract larger balance than what existed");
}

#[test]
fn storage_keys_have_not_changed() {
let address: Address = "astria1rsxyjrcm255ds9euthjx6yc3vrjt9sxrm9cfgm"
.parse()
.unwrap();
let asset = "an/asset/with/a/prefix"
.parse::<astria_core::primitive::v1::asset::Denom>()
.unwrap();
assert_eq!(
balance_storage_key(address, &asset),
balance_storage_key(address, asset.to_ibc_prefixed())
);
assert_snapshot!(balance_storage_key(address, asset));
assert_snapshot!(nonce_storage_key(address));
}
}
19 changes: 8 additions & 11 deletions crates/astria-sequencer/src/address/state_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@ use cnidarium::{
};
use tracing::instrument;

fn base_prefix_key() -> &'static str {
"prefixes/base"
}

fn ibc_compat_prefix_key() -> &'static str {
"prefixes/ibc-compat"
}
use crate::storage::verifiable_keys::address::{
BASE_PREFIX_KEY,
IBC_COMPAT_PREFIX_KEY,
};

#[async_trait]
pub(crate) trait StateReadExt: StateRead {
Expand Down Expand Up @@ -58,7 +55,7 @@ pub(crate) trait StateReadExt: StateRead {
#[instrument(skip_all, err)]
async fn get_base_prefix(&self) -> Result<String> {
let Some(bytes) = self
.get_raw(base_prefix_key())
.get_raw(BASE_PREFIX_KEY)
.await
.map_err(anyhow_to_eyre)
.wrap_err("failed reading address base prefix from state")?
Expand All @@ -73,7 +70,7 @@ pub(crate) trait StateReadExt: StateRead {
#[instrument(skip_all, err)]
async fn get_ibc_compat_prefix(&self) -> Result<String> {
let Some(bytes) = self
.get_raw(ibc_compat_prefix_key())
.get_raw(IBC_COMPAT_PREFIX_KEY)
.await
.map_err(anyhow_to_eyre)
.wrap_err("failed reading address ibc compat prefix from state")?
Expand All @@ -90,12 +87,12 @@ impl<T: ?Sized + StateRead> StateReadExt for T {}
pub(crate) trait StateWriteExt: StateWrite {
#[instrument(skip_all)]
fn put_base_prefix(&mut self, prefix: &str) {
self.put_raw(base_prefix_key().into(), prefix.into());
self.put_raw(BASE_PREFIX_KEY.to_string(), prefix.into());
}

#[instrument(skip_all)]
fn put_ibc_compat_prefix(&mut self, prefix: &str) {
self.put_raw(ibc_compat_prefix_key().into(), prefix.into());
self.put_raw(IBC_COMPAT_PREFIX_KEY.to_string(), prefix.into());
}
}

Expand Down
Loading
Loading