Skip to content

Commit

Permalink
Make Sequencer Outcome generic over address (#652)
Browse files Browse the repository at this point in the history
  • Loading branch information
citizen-stig authored Aug 15, 2023
1 parent b4c54b1 commit c0ef212
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 68 deletions.
2 changes: 1 addition & 1 deletion examples/demo-rollup/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ fn register_ledger(
ledger_db: LedgerDB,
methods: &mut jsonrpsee::RpcModule<()>,
) -> Result<(), anyhow::Error> {
let ledger_rpc = get_ledger_rpc::<SequencerOutcome, TxEffect>(ledger_db);
let ledger_rpc = get_ledger_rpc::<SequencerOutcome<CelestiaAddress>, TxEffect>(ledger_db);
methods
.merge(ledger_rpc)
.context("Failed to merge ledger RPC modules")
Expand Down
17 changes: 10 additions & 7 deletions examples/demo-stf/src/hooks_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use sov_modules_api::transaction::Transaction;
use sov_modules_api::{Context, Spec};
use sov_modules_stf_template::SequencerOutcome;
use sov_rollup_interface::da::BlobReaderTrait;
use sov_sequencer_registry::SequencerRegistry;
use sov_state::WorkingSet;
use tracing::info;

Expand All @@ -28,13 +29,13 @@ impl<C: Context> TxHooks for Runtime<C> {
}
}

impl<C: Context> ApplyBlobHooks for Runtime<C> {
impl<C: Context, B: BlobReaderTrait> ApplyBlobHooks<B> for Runtime<C> {
type Context = C;
type BlobResult = SequencerOutcome;
type BlobResult = SequencerOutcome<B::Address>;

fn begin_blob_hook(
&self,
blob: &mut impl BlobReaderTrait,
blob: &mut B,
working_set: &mut WorkingSet<<Self::Context as Spec>::Storage>,
) -> anyhow::Result<()> {
self.sequencer_registry.begin_blob_hook(blob, working_set)
Expand All @@ -48,7 +49,8 @@ impl<C: Context> ApplyBlobHooks for Runtime<C> {
match result {
SequencerOutcome::Rewarded(_reward) => {
// TODO: Process reward here or above.
self.sequencer_registry.end_blob_hook(
<SequencerRegistry<C> as ApplyBlobHooks<B>>::end_blob_hook(
&self.sequencer_registry,
sov_sequencer_registry::SequencerOutcome::Completed,
working_set,
)
Expand All @@ -58,10 +60,11 @@ impl<C: Context> ApplyBlobHooks for Runtime<C> {
reason,
sequencer_da_address,
} => {
info!("Sequencer slashed: {:?}", reason);
self.sequencer_registry.end_blob_hook(
info!("Sequencer {} slashed: {:?}", sequencer_da_address, reason);
<SequencerRegistry<C> as ApplyBlobHooks<B>>::end_blob_hook(
&self.sequencer_registry,
sov_sequencer_registry::SequencerOutcome::Slashed {
sequencer: sequencer_da_address,
sequencer: sequencer_da_address.as_ref().to_vec(),
},
working_set,
)
Expand Down
7 changes: 5 additions & 2 deletions examples/demo-stf/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,11 @@ impl<C: Context, Cond: ValidityCondition> SlotHooks<Cond> for Runtime<C> {
}
}

impl<C: Context, Cond: ValidityCondition> sov_modules_stf_template::Runtime<C, Cond>
for Runtime<C>
impl<C, Cond, B> sov_modules_stf_template::Runtime<C, Cond, B> for Runtime<C>
where
C: Context,
Cond: ValidityCondition,
B: BlobReaderTrait,
{
}

Expand Down
7 changes: 5 additions & 2 deletions examples/demo-stf/src/tests/tx_revert_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use sov_modules_api::default_signature::private_key::DefaultPrivateKey;
use sov_modules_api::transaction::Transaction;
use sov_modules_api::{EncodeCall, PrivateKey, PublicKey};
use sov_modules_stf_template::{Batch, RawTx, SequencerOutcome, SlashingReason};
use sov_rollup_interface::da::BlobReaderTrait;
use sov_rollup_interface::mocks::{MockZkvm, TestBlock};
use sov_rollup_interface::stf::StateTransitionFunction;
use sov_state::{ProverStorage, WorkingSet};
Expand Down Expand Up @@ -231,6 +232,7 @@ fn test_tx_bad_sig() {
let txs = simulate_da_with_bad_sig(election_admin_private_key);

let blob = new_test_blob_from_batch(Batch { txs }, &DEMO_SEQUENCER_DA_ADDRESS, [0; 32]);
let blob_sender = blob.sender();
let mut blobs = [blob];

let data = TestBlock::default();
Expand All @@ -247,7 +249,7 @@ fn test_tx_bad_sig() {
assert_eq!(
SequencerOutcome::Slashed{
reason:SlashingReason::StatelessVerificationFailed,
sequencer_da_address: DEMO_SEQUENCER_DA_ADDRESS.to_vec(),
sequencer_da_address: blob_sender,
},
apply_blob_outcome.inner,
"Unexpected outcome: Stateless verification should have failed due to invalid signature"
Expand Down Expand Up @@ -315,6 +317,7 @@ fn test_tx_bad_serialization() {

let txs = simulate_da_with_bad_serialization(election_admin_private_key);
let blob = new_test_blob_from_batch(Batch { txs }, &DEMO_SEQUENCER_DA_ADDRESS, [0; 32]);
let blob_sender = blob.sender();
let mut blobs = [blob];

let data = TestBlock::default();
Expand All @@ -331,7 +334,7 @@ fn test_tx_bad_serialization() {
assert_eq!(
SequencerOutcome::Slashed {
reason: SlashingReason::InvalidTransactionEncoding ,
sequencer_da_address: DEMO_SEQUENCER_DA_ADDRESS.to_vec(),
sequencer_da_address: blob_sender,
},
apply_blob_outcome.inner,
"Unexpected outcome: Stateless verification should have failed due to invalid signature"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ impl<C: Context, Cond: ValidityCondition> TxHooks for TestRuntime<C, Cond> {
}
}

impl<C: Context, Cond: ValidityCondition> ApplyBlobHooks for TestRuntime<C, Cond> {
impl<C: Context, Cond: ValidityCondition, B: BlobReaderTrait> ApplyBlobHooks<B>
for TestRuntime<C, Cond>
{
type Context = C;
type BlobResult = SequencerOutcome;
type BlobResult = SequencerOutcome<B::Address>;

fn begin_blob_hook(
&self,
_blob: &mut impl BlobReaderTrait,
_blob: &mut B,
_working_set: &mut WorkingSet<<Self::Context as Spec>::Storage>,
) -> anyhow::Result<()> {
Ok(())
Expand Down Expand Up @@ -90,7 +92,10 @@ impl<C: Context, Cond: ValidityCondition> BlobSelector for TestRuntime<C, Cond>
}
}

impl<C: Context, Cond: ValidityCondition> Runtime<C, Cond> for TestRuntime<C, Cond> {}
impl<C: Context, Cond: ValidityCondition, B: BlobReaderTrait> Runtime<C, Cond, B>
for TestRuntime<C, Cond>
{
}

pub(crate) fn create_demo_genesis_config<C: Context, Cond: ValidityCondition>(
admin: <C as Spec>::Address,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ use sov_state::WorkingSet;

use crate::{SequencerOutcome, SequencerRegistry};

impl<C: Context> ApplyBlobHooks for SequencerRegistry<C> {
impl<C: Context, B: BlobReaderTrait> ApplyBlobHooks<B> for SequencerRegistry<C> {
type Context = C;
type BlobResult = SequencerOutcome;

fn begin_blob_hook(
&self,
blob: &mut impl BlobReaderTrait,
blob: &mut B,
working_set: &mut WorkingSet<<Self::Context as sov_modules_api::Spec>::Storage>,
) -> anyhow::Result<()> {
if !self.is_sender_allowed(&blob.sender(), working_set) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@ fn end_blob_hook_success() {
.begin_blob_hook(&mut test_blob, working_set)
.unwrap();

test_sequencer
.registry
.end_blob_hook(SequencerOutcome::Completed, working_set)
.unwrap();
<SequencerRegistry<C> as ApplyBlobHooks<TestBlob<Address>>>::end_blob_hook(
&test_sequencer.registry,
SequencerOutcome::Completed,
working_set,
)
.unwrap();
let resp = test_sequencer.query_balance_via_bank(working_set).unwrap();
assert_eq!(balance_after_genesis, resp.amount.unwrap());
let resp = test_sequencer
Expand Down Expand Up @@ -128,10 +130,12 @@ fn end_blob_hook_slash() {
let result = SequencerOutcome::Slashed {
sequencer: GENESIS_SEQUENCER_DA_ADDRESS.to_vec(),
};
test_sequencer
.registry
.end_blob_hook(result, working_set)
.unwrap();
<SequencerRegistry<C> as ApplyBlobHooks<TestBlob<Address>>>::end_blob_hook(
&test_sequencer.registry,
result,
working_set,
)
.unwrap();

let resp = test_sequencer.query_balance_via_bank(working_set).unwrap();
assert_eq!(balance_after_genesis, resp.amount.unwrap());
Expand Down Expand Up @@ -187,10 +191,12 @@ fn end_blob_hook_slash_preferred_sequencer() {
let result = SequencerOutcome::Slashed {
sequencer: GENESIS_SEQUENCER_DA_ADDRESS.to_vec(),
};
test_sequencer
.registry
.end_blob_hook(result, working_set)
.unwrap();
<SequencerRegistry<C> as ApplyBlobHooks<TestBlob<Address>>>::end_blob_hook(
&test_sequencer.registry,
result,
working_set,
)
.unwrap();

let resp = test_sequencer.query_balance_via_bank(working_set).unwrap();
assert_eq!(balance_after_genesis, resp.amount.unwrap());
Expand Down Expand Up @@ -233,10 +239,12 @@ fn end_blob_hook_slash_unknown_sequencer() {
let result = SequencerOutcome::Slashed {
sequencer: UNKNOWN_SEQUENCER_DA_ADDRESS.to_vec(),
};
test_sequencer
.registry
.end_blob_hook(result, working_set)
.unwrap();
<SequencerRegistry<C> as ApplyBlobHooks<TestBlob<Address>>>::end_blob_hook(
&test_sequencer.registry,
result,
working_set,
)
.unwrap();

let resp = test_sequencer
.registry
Expand Down
4 changes: 2 additions & 2 deletions module-system/sov-modules-api/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ pub trait TxHooks {
/// Hooks related to the Sequencer functionality.
/// In essence, the sequencer locks a bond at the beginning of the `StateTransitionFunction::apply_blob`,
/// and is rewarded once a blob of transactions is processed.
pub trait ApplyBlobHooks {
pub trait ApplyBlobHooks<B: BlobReaderTrait> {
type Context: Context;
type BlobResult;

/// Runs at the beginning of apply_blob, locks the sequencer bond.
/// If this hook returns Err, batch is not applied
fn begin_blob_hook(
&self,
blob: &mut impl BlobReaderTrait,
blob: &mut B,
working_set: &mut WorkingSet<<Self::Context as Spec>::Storage>,
) -> anyhow::Result<()>;

Expand Down
32 changes: 20 additions & 12 deletions module-system/sov-modules-stf-template/src/app_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@ use sov_modules_api::{Context, DispatchCall};
use sov_rollup_interface::da::{BlobReaderTrait, CountedBufReader};
use sov_rollup_interface::stf::{BatchReceipt, TransactionReceipt};
use sov_rollup_interface::zk::ValidityCondition;
use sov_rollup_interface::Buf;
use sov_rollup_interface::{AddressTrait, Buf};
use sov_state::StateCheckpoint;
use tracing::{debug, error};

use crate::tx_verifier::{verify_txs_stateless, TransactionAndRawHash};
use crate::{Batch, Runtime, SequencerOutcome, SlashingReason, TxEffect};

type ApplyBatchResult<T> = Result<T, ApplyBatchError>;
type ApplyBatchResult<T, A> = Result<T, ApplyBatchError<A>>;

/// An implementation of the
/// [`StateTransitionFunction`](sov_rollup_interface::stf::StateTransitionFunction)
/// that is specifically designed to work with the module-system.
pub struct AppTemplate<C: Context, Cond: ValidityCondition, Vm, RT: Runtime<C, Cond>, B> {
pub struct AppTemplate<
C: Context,
Cond: ValidityCondition,
Vm,
RT: Runtime<C, Cond, B>,
B: BlobReaderTrait,
> {
/// State storage used by the rollup.
pub current_storage: C::Storage,
/// The runtime includes all the modules that the rollup supports.
Expand All @@ -28,19 +34,19 @@ pub struct AppTemplate<C: Context, Cond: ValidityCondition, Vm, RT: Runtime<C, C
phantom_blob: PhantomData<B>,
}

pub(crate) enum ApplyBatchError {
pub(crate) enum ApplyBatchError<A: AddressTrait> {
// Contains batch hash
Ignored([u8; 32]),
Slashed {
// Contains batch hash
hash: [u8; 32],
reason: SlashingReason,
sequencer_da_address: Vec<u8>,
sequencer_da_address: A,
},
}

impl From<ApplyBatchError> for BatchReceipt<SequencerOutcome, TxEffect> {
fn from(value: ApplyBatchError) -> Self {
impl<A: AddressTrait> From<ApplyBatchError<A>> for BatchReceipt<SequencerOutcome<A>, TxEffect> {
fn from(value: ApplyBatchError<A>) -> Self {
match value {
ApplyBatchError::Ignored(hash) => BatchReceipt {
batch_hash: hash,
Expand All @@ -63,10 +69,12 @@ impl From<ApplyBatchError> for BatchReceipt<SequencerOutcome, TxEffect> {
}
}

impl<C: Context, Vm, Cond: ValidityCondition, RT: Runtime<C, Cond>, B: BlobReaderTrait>
AppTemplate<C, Cond, Vm, RT, B>
impl<C, Vm, Cond, RT, B> AppTemplate<C, Cond, Vm, RT, B>
where
RT: Runtime<C, Cond>,
C: Context,
Cond: ValidityCondition,
B: BlobReaderTrait,
RT: Runtime<C, Cond, B>,
{
/// [`AppTemplate`] constructor.
pub fn new(storage: C::Storage, runtime: RT) -> Self {
Expand All @@ -83,7 +91,7 @@ where
pub(crate) fn apply_blob(
&mut self,
blob: &mut B,
) -> ApplyBatchResult<BatchReceipt<SequencerOutcome, TxEffect>> {
) -> ApplyBatchResult<BatchReceipt<SequencerOutcome<B::Address>, TxEffect>, B::Address> {
debug!(
"Applying batch from sequencer: 0x{}",
hex::encode(blob.sender())
Expand Down Expand Up @@ -116,7 +124,7 @@ where
Err(reason) => {
// Explicitly revert on slashing, even though nothing has changed in pre_process.
let mut batch_workspace = batch_workspace.revert().to_revertable();
let sequencer_da_address = blob.sender().as_ref().to_vec();
let sequencer_da_address = blob.sender();
let sequencer_outcome = SequencerOutcome::Slashed {
reason,
sequencer_da_address: sequencer_da_address.clone(),
Expand Down
Loading

0 comments on commit c0ef212

Please sign in to comment.