Skip to content

Commit

Permalink
Split AddressTrait (#720)
Browse files Browse the repository at this point in the history
* Removing extra bound on RollupAddress where it is not needed
* Update demo-simple-stf docs
* Public export
* Remove unused H160
  • Loading branch information
citizen-stig authored and preston-evans98 committed Sep 14, 2023
1 parent 7da0a98 commit d6e3bf5
Show file tree
Hide file tree
Showing 17 changed files with 83 additions and 203 deletions.
53 changes: 0 additions & 53 deletions adapters/celestia/src/celestia.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::fmt::{Display, Formatter};
use std::ops::Range;
use std::str::FromStr;
use std::sync::{Arc, Mutex};

use base64::engine::general_purpose::STANDARD as B64_ENGINE;
Expand All @@ -12,7 +10,6 @@ use prost::Message;
use serde::{Deserialize, Serialize};
use sov_rollup_interface::da::{BlockHeaderTrait as BlockHeader, CountedBufReader};
use sov_rollup_interface::services::da::SlotData;
use sov_rollup_interface::AddressTrait;
pub use tendermint::block::Header as TendermintHeader;
use tendermint::block::Height;
use tendermint::crypto::default::Sha256;
Expand Down Expand Up @@ -348,56 +345,6 @@ impl AsRef<[u8]> for Sha2Hash {
}
}

#[derive(Deserialize, Serialize, PartialEq, Debug, Clone, Eq, Hash)]
pub struct H160(#[serde(deserialize_with = "hex::deserialize")] pub [u8; 20]);

impl AsRef<[u8]> for H160 {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl<'a> TryFrom<&'a [u8]> for H160 {
type Error = anyhow::Error;

fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
if value.len() == 20 {
let mut addr = [0u8; 20];
addr.copy_from_slice(value);
return Ok(Self(addr));
}
anyhow::bail!("Adress is not exactly 20 bytes");
}
}

impl From<[u8; 32]> for H160 {
fn from(value: [u8; 32]) -> Self {
let mut addr = [0u8; 20];
addr.copy_from_slice(&value[12..]);
Self(addr)
}
}

impl FromStr for H160 {
type Err = hex::FromHexError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
// Remove the "0x" prefix, if it exists.
let s = s.strip_prefix("0x").unwrap_or(s);
let mut output = [0u8; 20];
hex::decode_to_slice(s, &mut output)?;
Ok(H160(output))
}
}

impl Display for H160 {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "0x{}", hex::encode(self.0))
}
}

impl AddressTrait for H160 {}

pub fn parse_pfb_namespace(
group: NamespaceGroup,
) -> Result<Vec<(MsgPayForBlobs, TxPosition)>, BoxError> {
Expand Down
21 changes: 1 addition & 20 deletions adapters/celestia/src/verifier/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::str::FromStr;
use bech32::WriteBase32;
use borsh::{BorshDeserialize, BorshSerialize};
use serde::{Deserialize, Serialize};
use sov_rollup_interface::AddressTrait;
use thiserror::Error;

/// Human Readable Part: "celestia" for Celestia network
Expand Down Expand Up @@ -52,17 +51,6 @@ impl<'a> TryFrom<&'a [u8]> for CelestiaAddress {
}
}

/// Panics if any element is not in range 0..32 (u5)
/// TODO: Will be removed after https://github.com/Sovereign-Labs/sovereign-sdk/issues/493
impl From<[u8; 32]> for CelestiaAddress {
fn from(value: [u8; 32]) -> Self {
for item in value {
bech32::u5::try_from_u8(item).unwrap();
}
Self(value)
}
}

impl Display for CelestiaAddress {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut w = bech32::Bech32Writer::new(HRP, VARIANT, f)?;
Expand Down Expand Up @@ -116,7 +104,7 @@ impl FromStr for CelestiaAddress {
}
}

impl AddressTrait for CelestiaAddress {}
impl sov_rollup_interface::BasicAddress for CelestiaAddress {}

#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -232,12 +220,5 @@ mod tests {
fn test_borsh(input in proptest::array::uniform20(0u8..=255)) {
check_borsh(input);
}

#[test]
fn test_try_from_array(arr in proptest::array::uniform32(0u8..32)) {
let address = CelestiaAddress::from(arr);
let output = format!("{}", address);
prop_assert!(output.starts_with("celestia"));
}
}
}
8 changes: 4 additions & 4 deletions examples/demo-rollup/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use demo_stf::runtime::GenesisConfig;
pub use rollup::{new_rollup_with_celestia_da, Rollup};
use sov_db::ledger_db::LedgerDB;
use sov_modules_api::default_context::DefaultContext;
use sov_rollup_interface::AddressTrait;
use sov_rollup_interface::BasicAddress;

/// The rollup stores its data in the namespace b"sov-test" on Celestia
/// You can change this constant to point your rollup at a different namespace
Expand All @@ -38,10 +38,10 @@ pub struct HexKey {
/// address, simply change the value of the SEQUENCER_DA_ADDRESS to your own address.
/// For example:
/// ```rust,no_run
/// const SEQUENCER_DA_ADDRESS: [u8;47] = *b"celestia1qp09ysygcx6npted5yc0au6k9lner05yvs9208";
/// const SEQUENCER_DA_ADDRESS: &str = "celestia1qp09ysygcx6npted5yc0au6k9lner05yvs9208";
/// ```
pub fn get_genesis_config<D: AddressTrait>(
sequencer_da_address: D,
pub fn get_genesis_config<A: BasicAddress>(
sequencer_da_address: A,
) -> GenesisConfig<DefaultContext> {
let hex_key: HexKey = serde_json::from_slice(include_bytes!(
"../../test-data/keys/token_deployer_private_key.json"
Expand Down
42 changes: 22 additions & 20 deletions examples/demo-simple-stf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,37 +154,39 @@ The first transaction that finds the correct hash would break the loop and retur
The `sov_rollup_interface::mocks` crate provides two utilities that are useful for testing:

1. The `MockZkvm` is an implementation of the `Zkvm` trait that can be used in tests.
1. The `TestBlob` is an implementation of the `BlobTransactionTrait` trait that can be used in tests. It accepts an `Address` as a generic parameter. For testing purposes, we implement our own `Address` type as follows:

```rust, ignore
#[derive(PartialEq, Debug, Clone, Eq, serde::Serialize, serde::Deserialize)]
pub struct DaAddress {
pub addr: [u8; 32],
}
impl AddressTrait for DaAddress {}
```
1. The `MockBlob` is an implementation of the `BlobTransactionTrait` trait that can be used in tests. It accepts an `A: BasicAddress` as a generic parameter. For testing purposes, we use `MockAddress` struct from the same `mocks` module

You can find more details in the `stf_test.rs` file.

The following test checks the rollup logic. In the test, we call `init_chain, begin_slot, and end_slot` for completeness, even though these methods do nothing.

```rust, ignore
```rust
use demo_simple_stf::{ApplySlotResult, CheckHashPreimageStf};
use sov_rollup_interface::mocks::{MockAddress, MockBlob, MockBlock, MockValidityCond, MockZkvm};
use sov_rollup_interface::stf::StateTransitionFunction;

#[test]
fn test_stf() {
let address = DaAddress { addr: [1; 32] };
let address = MockAddress { addr: [1; 32] };
let preimage = vec![0; 32];

let test_blob = TestBlob::<DaAddress>::new(preimage, address);
let stf = &mut CheckHashPreimageStf {};
let test_blob = MockBlob::<MockAddress>::new(preimage, address, [0; 32]);
let stf = &mut CheckHashPreimageStf::<MockValidityCond>::default();

let data = MockBlock::default();
let mut blobs = [test_blob];

StateTransitionFunction::<MockZkvm>::init_chain(stf, ());
StateTransitionFunction::<MockZkvm>::begin_slot(stf, ());
StateTransitionFunction::<MockZkvm, MockBlob<MockAddress>>::init_chain(stf, ());

let receipt = StateTransitionFunction::<MockZkvm>::apply_blob(stf, test_blob, None);
assert_eq!(receipt.inner, ApplyBlobResult::Success);
let result = StateTransitionFunction::<MockZkvm, MockBlob<MockAddress>>::apply_slot(
stf,
(),
&data,
&mut blobs,
);

StateTransitionFunction::<MockZkvm>::end_slot(stf);
assert_eq!(1, result.batch_receipts.len());
let receipt = result.batch_receipts[0].clone();
assert_eq!(receipt.inner, ApplySlotResult::Success);
}
```
64 changes: 5 additions & 59 deletions examples/demo-simple-stf/tests/stf_test.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,21 @@
use std::fmt::Display;
use std::str::FromStr;

use demo_simple_stf::{ApplySlotResult, CheckHashPreimageStf};
use sov_rollup_interface::mocks::{MockBlob, MockBlock, MockValidityCond, MockZkvm};
use sov_rollup_interface::mocks::{MockAddress, MockBlob, MockBlock, MockValidityCond, MockZkvm};
use sov_rollup_interface::stf::StateTransitionFunction;
use sov_rollup_interface::AddressTrait;

#[derive(PartialEq, Debug, Clone, Eq, serde::Serialize, serde::Deserialize, Hash)]
pub struct DaAddress {
pub addr: [u8; 32],
}

impl AddressTrait for DaAddress {}

impl AsRef<[u8]> for DaAddress {
fn as_ref(&self) -> &[u8] {
&self.addr
}
}

impl From<[u8; 32]> for DaAddress {
fn from(addr: [u8; 32]) -> Self {
DaAddress { addr }
}
}

impl FromStr for DaAddress {
type Err = hex::FromHexError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
// Remove the "0x" prefix, if it exists.
let s = s.strip_prefix("0x").unwrap_or(s);
let mut addr = [0u8; 32];
hex::decode_to_slice(s, &mut addr)?;
Ok(DaAddress { addr })
}
}

impl<'a> TryFrom<&'a [u8]> for DaAddress {
type Error = anyhow::Error;

fn try_from(addr: &'a [u8]) -> Result<Self, Self::Error> {
if addr.len() != 32 {
anyhow::bail!("Address must be 32 bytes long");
}
let mut addr_bytes = [0u8; 32];
addr_bytes.copy_from_slice(addr);
Ok(Self { addr: addr_bytes })
}
}

impl Display for DaAddress {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.addr)
}
}

#[test]
fn test_stf() {
let address = DaAddress { addr: [1; 32] };
let address = MockAddress { addr: [1; 32] };
let preimage = vec![0; 32];

let test_blob = MockBlob::<DaAddress>::new(preimage, address, [0; 32]);
let test_blob = MockBlob::<MockAddress>::new(preimage, address, [0; 32]);
let stf = &mut CheckHashPreimageStf::<MockValidityCond>::default();

let data = MockBlock::default();
let mut blobs = [test_blob];

StateTransitionFunction::<MockZkvm, MockBlob<DaAddress>>::init_chain(stf, ());
StateTransitionFunction::<MockZkvm, MockBlob<MockAddress>>::init_chain(stf, ());

let result = StateTransitionFunction::<MockZkvm, MockBlob<DaAddress>>::apply_slot(
let result = StateTransitionFunction::<MockZkvm, MockBlob<MockAddress>>::apply_slot(
stf,
(),
&data,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl<C: sov_modules_api::Context> BlobStorage<C> {
.collect()
}

// TODO: Migrate to AddressTrait generic: https://github.com/Sovereign-Labs/sovereign-sdk/issues/622
// TODO: Migrate to generic: https://github.com/Sovereign-Labs/sovereign-sdk/issues/622
pub(crate) fn get_preferred_sequencer(
&self,
working_set: &mut WorkingSet<C::Storage>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl<C: sov_modules_api::Context> SequencerRegistry<C> {
}

/// Checks whether `sender` is a registered sequencer.
pub fn is_sender_allowed<T: sov_modules_api::AddressTrait>(
pub fn is_sender_allowed<T: sov_rollup_interface::BasicAddress>(
&self,
sender: &T,
working_set: &mut WorkingSet<C::Storage>,
Expand Down
4 changes: 2 additions & 2 deletions module-system/sov-modules-api/src/default_context.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[cfg(feature = "native")]
use serde::{Deserialize, Serialize};
use sha2::Digest;
use sov_rollup_interface::AddressTrait;
use sov_rollup_interface::RollupAddress;
#[cfg(feature = "native")]
use sov_state::ProverStorage;
use sov_state::{ArrayWitness, DefaultStorageSpec, ZkStorage};
Expand Down Expand Up @@ -67,7 +67,7 @@ impl Context for ZkDefaultContext {
}

impl PublicKey for DefaultPublicKey {
fn to_address<A: AddressTrait>(&self) -> A {
fn to_address<A: RollupAddress>(&self) -> A {
let pub_key_hash = {
let mut hasher = <ZkDefaultContext as Spec>::Hasher::new();
hasher.update(self.pub_key);
Expand Down
13 changes: 7 additions & 6 deletions module-system/sov-modules-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub use error::Error;
pub use prefix::Prefix;
pub use response::CallResponse;
use serde::{Deserialize, Serialize};
pub use sov_rollup_interface::{digest, AddressTrait};
pub use sov_rollup_interface::{digest, BasicAddress, RollupAddress};
use sov_state::{Storage, Witness, WorkingSet};
use thiserror::Error;

Expand All @@ -66,7 +66,8 @@ impl AsRef<[u8]> for Address {
}
}

impl AddressTrait for Address {}
impl BasicAddress for Address {}
impl RollupAddress for Address {}

#[cfg_attr(feature = "native", derive(schemars::JsonSchema))]
#[derive(PartialEq, Clone, Copy, Eq, borsh::BorshDeserialize, borsh::BorshSerialize, Hash)]
Expand Down Expand Up @@ -143,7 +144,7 @@ pub enum NonInstantiable {}

/// PublicKey used in the Module System.
pub trait PublicKey {
fn to_address<A: AddressTrait>(&self) -> A;
fn to_address<A: RollupAddress>(&self) -> A;
}

/// A PrivateKey used in the Module System.
Expand All @@ -154,7 +155,7 @@ pub trait PrivateKey {
fn generate() -> Self;
fn pub_key(&self) -> Self::PublicKey;
fn sign(&self, msg: &[u8]) -> Self::Signature;
fn to_address<A: AddressTrait>(&self) -> A {
fn to_address<A: RollupAddress>(&self) -> A {
self.pub_key().to_address::<A>()
}
}
Expand All @@ -171,7 +172,7 @@ pub trait PrivateKey {
pub trait Spec {
/// The Address type used on the rollup. Typically calculated as the hash of a public key.
#[cfg(feature = "native")]
type Address: AddressTrait
type Address: RollupAddress
+ BorshSerialize
+ BorshDeserialize
+ Sync
Expand All @@ -184,7 +185,7 @@ pub trait Spec {

/// The Address type used on the rollup. Typically calculated as the hash of a public key.
#[cfg(not(feature = "native"))]
type Address: AddressTrait + BorshSerialize + BorshDeserialize;
type Address: RollupAddress + BorshSerialize + BorshDeserialize;

/// Authenticated state storage used by the rollup. Typically some variant of a merkle-patricia trie.
type Storage: Storage + Clone + Send + Sync;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![allow(unused_imports)]

use sov_modules_api::{AddressTrait, Context, ModuleInfo};
use sov_modules_api::{Context, ModuleInfo, RollupAddress};

#[derive(ModuleInfo)]
struct TestModule<C: Context> {
Expand Down
Loading

0 comments on commit d6e3bf5

Please sign in to comment.