Skip to content

Commit

Permalink
chore(sequencer): add snapshots for storage values to enforce non-sta…
Browse files Browse the repository at this point in the history
…te-breaking changes (#1985)

## Summary
Added snapshot tests for all storage values to ensure that future
changes do not break state.

## Background
The addition of the `BridgeTransfer` action revealed how inserting a
value into the storage `ValueImpl` is a breaking change, since
deserialization would then fail. New values, such as
`BridgeTransferFees` need to be appended instead of inserted. Adding
snapshots for each storage variant's discriminant ensures that there is
an extra level of protection against making a state breaking change.

## Changes
- Added snapshots for the borsch encoding of every `ValueImpl` variant
and every `StoredValue` variant.

## Testing
Manually reviewed every discriminant.

## Changelogs
No updates required.

## Related Issues
closes #1982

---------

Co-authored-by: Jordan Oroshiba <jordan@astria.org>
  • Loading branch information
ethanoroshiba and joroshiba authored Mar 7, 2025
1 parent 46a5213 commit dd99bf9
Show file tree
Hide file tree
Showing 60 changed files with 723 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/accounts/storage/values.rs
expression: "borsh_then_hex(&StoredValue::Accounts(Value(ValueImpl::Nonce(Nonce(0)))))"
---
030100000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/accounts/storage/values.rs
expression: "borsh_then_hex(&ValueImpl::Balance(Balance(0)))"
---
0000000000000000000000000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/accounts/storage/values.rs
expression: "borsh_then_hex(&ValueImpl::Nonce(Nonce(0)))"
---
0100000000
31 changes: 31 additions & 0 deletions crates/astria-sequencer/src/accounts/storage/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,34 @@ impl<'a> TryFrom<crate::storage::StoredValue<'a>> for Nonce {
Ok(nonce)
}
}

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use super::*;
use crate::test_utils::borsh_then_hex;

#[test]
fn value_impl_existing_variants_unchanged() {
assert_snapshot!(
"value_impl_balance",
borsh_then_hex(&ValueImpl::Balance(Balance(0)))
);
assert_snapshot!(
"value_impl_nonce",
borsh_then_hex(&ValueImpl::Nonce(Nonce(0)))
);
}

// Note: This test must be here instead of in `crate::storage` since `ValueImpl` is not
// re-exported.
#[test]
fn stored_value_account_variant_unchanged() {
use crate::storage::StoredValue;
assert_snapshot!(
"stored_value_account_variant",
borsh_then_hex(&StoredValue::Accounts(Value(ValueImpl::Nonce(Nonce(0)))))
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/address/storage/values.rs
expression: "borsh_then_hex(&StoredValue::Address(Value(ValueImpl::AddressPrefix(\"test_prefix\".into()))))"
---
01000b000000746573745f707265666978
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/address/storage/values.rs
expression: "borsh_then_hex(&ValueImpl::AddressPrefix(\"test_prefix\".into()))"
---
000b000000746573745f707265666978
29 changes: 29 additions & 0 deletions crates/astria-sequencer/src/address/storage/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,32 @@ impl<'a> TryFrom<crate::storage::StoredValue<'a>> for AddressPrefix<'a> {
Ok(prefix)
}
}

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use super::*;
use crate::test_utils::borsh_then_hex;

#[test]
fn value_impl_existing_variants_unchanged() {
assert_snapshot!(
"value_impl_address_prefix",
borsh_then_hex(&ValueImpl::AddressPrefix("test_prefix".into()))
);
}

// Note: This test must be here instead of in `crate::storage` since `ValueImpl` is not
// re-exported.
#[test]
fn stored_value_address_variant_unchanged() {
use crate::storage::StoredValue;
assert_snapshot!(
"stored_value_address_variant",
borsh_then_hex(&StoredValue::Address(Value(ValueImpl::AddressPrefix(
"test_prefix".into()
))))
);
}
}
45 changes: 45 additions & 0 deletions crates/astria-sequencer/src/app/storage/values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,48 @@ enum ValueImpl<'a> {
BlockTimestamp(BlockTimestamp),
StorageVersion(StorageVersion),
}

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use super::*;
use crate::test_utils::borsh_then_hex;

#[test]
fn value_impl_existing_variants_unchanged() {
assert_snapshot!(
"value_impl_chain_id",
borsh_then_hex(&ValueImpl::ChainId(
(&tendermint::chain::Id::try_from("test_prefix".to_string()).unwrap()).into()
))
);
assert_snapshot!(
"value_impl_revision_number",
borsh_then_hex(&ValueImpl::RevisionNumber(1.into()))
);
assert_snapshot!(
"value_impl_block_height",
borsh_then_hex(&ValueImpl::BlockHeight(1.into()))
);
assert_snapshot!(
"value_impl_block_timestamp",
borsh_then_hex(&ValueImpl::BlockTimestamp(
tendermint::Time::unix_epoch().into()
))
);
assert_snapshot!(
"value_impl_storage_version",
borsh_then_hex(&ValueImpl::StorageVersion(1.into()))
);
}

#[test]
fn stored_value_app_variant_unchanged() {
use crate::storage::StoredValue;
assert_snapshot!(
"stored_value_app_variant",
borsh_then_hex(&StoredValue::App(Value(ValueImpl::BlockHeight(1.into()))))
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/app/storage/values/mod.rs
expression: "borsh_then_hex(&StoredValue::App(Value(ValueImpl::BlockHeight(1.into()))))"
---
08020100000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/app/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::BlockHeight(1.into()))"
---
020100000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/app/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::BlockTimestamp(tendermint::Time::unix_epoch().into()))"
---
0300000000000000000000000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/app/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::ChainId((&tendermint::chain::Id::try_from(\"test_prefix\".to_string()).unwrap()).into()))"
---
000b000000746573745f707265666978
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/app/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::RevisionNumber(1.into()))"
---
010100000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/app/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::StorageVersion(1.into()))"
---
040100000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/assets/storage/values.rs
expression: "borsh_then_hex(&StoredValue::Assets(Value(ValueImpl::TracePrefixedDenom((&\"test_denom\".to_string().parse::<DomainTracePrefixed>().unwrap()).into()))))"
---
0200000000000a000000746573745f64656e6f6d
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/assets/storage/values.rs
expression: "borsh_then_hex(&ValueImpl::TracePrefixedDenom((&\"test_denom\".to_string().parse::<DomainTracePrefixed>().unwrap()).into()))"
---
00000000000a000000746573745f64656e6f6d
39 changes: 39 additions & 0 deletions crates/astria-sequencer/src/assets/storage/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,42 @@ impl<'a> TryFrom<crate::storage::StoredValue<'a>> for TracePrefixedDenom<'a> {
Ok(denom)
}
}

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use super::*;
use crate::test_utils::borsh_then_hex;

#[test]
fn value_impl_existing_variants_unchanged() {
assert_snapshot!(
"value_impl_trace_prefixed_denom",
borsh_then_hex(&ValueImpl::TracePrefixedDenom(
(&"test_denom"
.to_string()
.parse::<DomainTracePrefixed>()
.unwrap())
.into()
))
);
}

// Note: This test must be here instead of in `crate::storage` since `ValueImpl` is not
// re-exported.
#[test]
fn stored_value_assets_variant_unchanged() {
use crate::storage::StoredValue;
assert_snapshot!(
"stored_value_assets_variant",
borsh_then_hex(&StoredValue::Assets(Value(ValueImpl::TracePrefixedDenom(
(&"test_denom"
.to_string()
.parse::<DomainTracePrefixed>()
.unwrap())
.into()
))))
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/authority/storage/values.rs
expression: "borsh_then_hex(&StoredValue::Authority(Value(ValueImpl::ValidatorSet(ValidatorSet(vec![])))))"
---
040100000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/authority/storage/values.rs
expression: "borsh_then_hex(&ValueImpl::AddressBytes((&[0; ADDRESS_LEN]).into()))"
---
000000000000000000000000000000000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/authority/storage/values.rs
expression: "borsh_then_hex(&ValueImpl::ValidatorSet(ValidatorSet(vec![])))"
---
0100000000
33 changes: 33 additions & 0 deletions crates/astria-sequencer/src/authority/storage/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,36 @@ impl<'a> TryFrom<crate::storage::StoredValue<'a>> for ValidatorSet<'a> {
Ok(validator_set)
}
}

#[cfg(test)]
mod tests {
use insta::assert_snapshot;

use super::*;
use crate::test_utils::borsh_then_hex;

#[test]
fn value_impl_existing_variants_unchanged() {
assert_snapshot!(
"value_impl_address_bytes",
borsh_then_hex(&ValueImpl::AddressBytes((&[0; ADDRESS_LEN]).into()))
);
assert_snapshot!(
"value_impl_validator_set",
borsh_then_hex(&ValueImpl::ValidatorSet(ValidatorSet(vec![])))
);
}

// Note: This test must be here instead of in `crate::storage` since `ValueImpl` is not
// re-exported.
#[test]
fn stored_value_authority_variant_unchanged() {
use crate::storage::StoredValue;
assert_snapshot!(
"stored_value_authority_variant",
borsh_then_hex(&StoredValue::Authority(Value(ValueImpl::ValidatorSet(
ValidatorSet(vec![])
))))
);
}
}
68 changes: 68 additions & 0 deletions crates/astria-sequencer/src/bridge/storage/values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,71 @@ enum ValueImpl<'a> {
Deposits(Deposits<'a>),
TransactionId(TransactionId<'a>),
}

#[cfg(test)]
mod tests {
use astria_core::{
crypto::ADDRESS_LENGTH,
primitive::v1::{
asset::IbcPrefixed as DomainIbcPrefixed,
RollupId as DomainRollupId,
TransactionId as DomainTransactionId,
ROLLUP_ID_LEN,
TRANSACTION_ID_LEN,
},
sequencerblock::v1::block::Deposit as DomainDeposit,
};
use insta::assert_snapshot;

use super::*;
use crate::test_utils::borsh_then_hex;

#[test]
fn value_impl_existing_variants_unchanged() {
assert_snapshot!(
"value_impl_rollup_id",
borsh_then_hex(&ValueImpl::RollupId(
(&DomainRollupId::new([0; ROLLUP_ID_LEN])).into()
))
);
assert_snapshot!(
"value_impl_ibc_prefixed_denom",
borsh_then_hex(&ValueImpl::IbcPrefixedDenom(
(&DomainIbcPrefixed::new([0; 32])).into()
))
);
assert_snapshot!(
"value_impl_address_bytes",
borsh_then_hex(&ValueImpl::AddressBytes((&[0; ADDRESS_LENGTH]).into()))
);
assert_snapshot!(
"value_impl_block_height",
borsh_then_hex(&ValueImpl::BlockHeight(1.into()))
);
assert_snapshot!(
"value_impl_deposits",
borsh_then_hex(&ValueImpl::Deposits(
Vec::<DomainDeposit>::new().iter().into()
))
);
assert_snapshot!(
"value_impl_transaction_id",
borsh_then_hex(&ValueImpl::TransactionId(
(&DomainTransactionId::new([0; TRANSACTION_ID_LEN])).into()
))
);
}

// Note: This test must be here instead of in `crate::storage` since `ValueImpl` is not
// re-exported.
#[test]
fn stored_value_bridge_variant_unchanged() {
use crate::storage::StoredValue;
assert_snapshot!(
"stored_value_bridge_variant",
borsh_then_hex(&StoredValue::Bridge(Value(ValueImpl::BlockHeight(
1.into()
))))
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/bridge/storage/values/mod.rs
expression: "borsh_then_hex(&StoredValue::Bridge(Value(ValueImpl::BlockHeight(1.into()))))"
---
06030100000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/bridge/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::AddressBytes((&[0; ADDRESS_LENGTH]).into()))"
---
020000000000000000000000000000000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/bridge/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::BlockHeight(1.into()))"
---
030100000000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/bridge/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::Deposits(Vec::<DomainDeposit>::new().iter().into()))"
---
0400000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/astria-sequencer/src/bridge/storage/values/mod.rs
expression: "borsh_then_hex(&ValueImpl::IbcPrefixedDenom((&DomainIbcPrefixed::new([0;\n32])).into()))"
---
010000000000000000000000000000000000000000000000000000000000000000
Loading

0 comments on commit dd99bf9

Please sign in to comment.