Skip to content

Commit 7b547c5

Browse files
refactor(worker): remove alpen storage deps from workspace (#56)
Moves AsmState into strata-asm-worker. Removes BlockSubmitter trait entirely — the handle's submit_block/submit_block_async methods are the direct API, no indirection needed. strata-state, strata-storage, and strata-db-store-sled are now direct git deps of bin/asm-runner only (binary-level, no cycle). The workspace root Cargo.toml no longer references any alpen storage crates.
1 parent b04c836 commit 7b547c5

File tree

17 files changed

+97
-73
lines changed

17 files changed

+97
-73
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,8 @@ strata-test-utils-checkpoint = { path = "crates/test-utils/checkpoint" }
8989
strata-btc-types = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
9090
strata-codec-utils = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
9191
strata-crypto = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
92-
strata-db-store-sled = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
9392
strata-identifiers = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
9493
strata-primitives = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
95-
strata-state = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
96-
strata-storage = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
9794
strata-test-utils-ssz = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
9895

9996
# Dependencies from alpenlabs/strata-bridge pinned to commit fc966d5 (STR-2598-asm-stf-proof-statements @ 2026-03-17)

bin/asm-runner/Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ strata-asm-proto-bridge-v1.workspace = true
2424
strata-asm-txs-bridge-v1.workspace = true
2525
strata-asm-worker.workspace = true
2626
strata-btc-types.workspace = true
27-
strata-db-store-sled.workspace = true
27+
28+
# Storage deps — now only needed by the runner binary, not ASM library crates
29+
# TODO(STR-2544): eliminate it completely
30+
strata-db-store-sled = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
31+
strata-state = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
32+
strata-storage = { git = "https://github.com/alpenlabs/alpen.git", rev = "02fe60d1b74470da3db67352b2f74625eb2e0ed1" }
33+
2834
strata-identifiers.workspace = true
2935
strata-merkle.workspace = true
3036
strata-predicate.workspace = true
31-
strata-state.workspace = true
32-
strata-storage.workspace = true
3337
strata-tasks.workspace = true
3438

3539
anyhow.workspace = true

bin/asm-runner/src/block_driver.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use strata_asm_proof_types::{L1Range, ProofId};
1414
use strata_asm_worker::AsmWorkerHandle;
1515
use strata_btc_types::BlockHashExt;
1616
use strata_identifiers::L1BlockCommitment;
17-
use strata_state::BlockSubmitter;
1817
use strata_tasks::ShutdownGuard;
1918
use tokio::sync::mpsc;
2019
use tracing::{debug, error, info, warn};

bin/asm-runner/src/worker_context.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
1-
//! WorkerContext implementation for ASM worker
1+
//! WorkerContext implementation for ASM worker.
2+
//!
3+
//! This is the glue between the worker (which uses `strata_asm_worker::AsmState`)
4+
//! and the storage layer (which uses `strata_state::asm_state::AsmState`).
5+
//! The two types are structurally identical — we convert between them at the
6+
//! persistence boundary.
27
38
use std::sync::Arc;
49

510
use bitcoin::{Block, BlockHash, Network};
611
use bitcoind_async_client::{Client, traits::Reader};
712
use strata_asm_common::{AsmManifest, AuxData};
8-
use strata_asm_worker::{WorkerContext, WorkerError, WorkerResult};
13+
use strata_asm_worker::{AsmState, WorkerContext, WorkerError, WorkerResult};
914
use strata_btc_types::{BitcoinTxid, L1BlockIdBitcoinExt, RawBitcoinTx};
1015
use strata_identifiers::{Hash, L1BlockCommitment, L1BlockId};
11-
use strata_state::asm_state::AsmState;
16+
use strata_state::asm_state::AsmState as StorageAsmState;
1217
use strata_storage::{AsmStateManager, MmrIndexHandle};
1318
use tokio::runtime::Handle;
1419

15-
/// ASM [`WorkerContext`] implementation
20+
/// Convert storage-layer AsmState to worker AsmState.
21+
fn from_storage(s: StorageAsmState) -> AsmState {
22+
AsmState::new(s.state().clone(), s.logs().clone())
23+
}
24+
25+
/// Convert worker AsmState to storage-layer AsmState.
26+
fn to_storage(s: &AsmState) -> StorageAsmState {
27+
StorageAsmState::new(s.state().clone(), s.logs().clone())
28+
}
29+
30+
/// ASM [`WorkerContext`] implementation.
1631
///
17-
/// This implementation fetches L1 blocks directly from a Bitcoin node
18-
/// and uses SledDB for state storage.
32+
/// Fetches L1 blocks from a Bitcoin node and persists state via SledDB.
1933
pub(crate) struct AsmWorkerContext {
2034
runtime_handle: Handle,
2135
bitcoin_client: Arc<Client>,
@@ -24,7 +38,6 @@ pub(crate) struct AsmWorkerContext {
2438
}
2539

2640
impl AsmWorkerContext {
27-
/// Create a new BridgeWorkerContext
2841
pub(crate) const fn new(
2942
runtime_handle: Handle,
3043
bitcoin_client: Arc<Client>,
@@ -42,7 +55,6 @@ impl AsmWorkerContext {
4255

4356
impl WorkerContext for AsmWorkerContext {
4457
fn get_l1_block(&self, blockid: &L1BlockId) -> WorkerResult<Block> {
45-
// Fetch block directly from Bitcoin node by hash
4658
let block_hash: BlockHash = blockid.to_block_hash();
4759
self.runtime_handle
4860
.block_on(self.bitcoin_client.get_block(&block_hash))
@@ -52,12 +64,14 @@ impl WorkerContext for AsmWorkerContext {
5264
fn get_latest_asm_state(&self) -> WorkerResult<Option<(L1BlockCommitment, AsmState)>> {
5365
self.asm_manager
5466
.fetch_most_recent_state()
67+
.map(|opt| opt.map(|(id, s)| (id, from_storage(s))))
5568
.map_err(|_| WorkerError::DbError)
5669
}
5770

5871
fn get_anchor_state(&self, blockid: &L1BlockCommitment) -> WorkerResult<AsmState> {
5972
self.asm_manager
6073
.get_state(*blockid)
74+
.map(|opt| opt.map(from_storage))
6175
.map_err(|_| WorkerError::DbError)?
6276
.ok_or(WorkerError::MissingAsmState(*blockid.blkid()))
6377
}
@@ -68,13 +82,11 @@ impl WorkerContext for AsmWorkerContext {
6882
state: &AsmState,
6983
) -> WorkerResult<()> {
7084
self.asm_manager
71-
.put_state(*blockid, state.clone())
85+
.put_state(*blockid, to_storage(state))
7286
.map_err(|_| WorkerError::DbError)
7387
}
7488

7589
fn store_l1_manifest(&self, _manifest: AsmManifest) -> WorkerResult<()> {
76-
// Manifests are already stored with AsmState in AsmStateManager
77-
// No separate storage needed for now
7890
Ok(())
7991
}
8092

@@ -130,7 +142,6 @@ impl WorkerContext for AsmWorkerContext {
130142
}
131143

132144
fn has_l1_manifest(&self, _blockid: &L1BlockId) -> WorkerResult<bool> {
133-
// Each block generates a valid manifest
134145
Ok(true)
135146
}
136147
}

crates/worker/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ strata-btc-verification.workspace = true
1717
strata-identifiers.workspace = true
1818
strata-merkle = { workspace = true, features = ["ssz"] }
1919
strata-service.workspace = true
20-
strata-state.workspace = true
2120
strata-tasks.workspace = true
2221

2322
anyhow.workspace = true
24-
async-trait.workspace = true
2523
bitcoin.workspace = true
24+
borsh.workspace = true
2625
serde.workspace = true
2726
thiserror.workspace = true
2827
tracing.workspace = true

crates/worker/src/asm_state.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//! ASM bookkeeping state.
2+
//!
3+
//! Previously lived in `strata-state` (alpen). Moved here to eliminate the
4+
//! circular dependency between the ASM repo and alpen.
5+
6+
use borsh::{BorshDeserialize, BorshSerialize};
7+
use serde::{Deserialize, Serialize};
8+
use strata_asm_common::{AnchorState, AsmLogEntry};
9+
use strata_asm_stf::AsmStfOutput;
10+
11+
/// ASM bookkeeping "umbrella" state.
12+
///
13+
/// Wraps an [`AnchorState`] (the raw STF output) with log entries.
14+
/// This is the unit stored in the database per L1 block.
15+
#[derive(Debug, Clone, PartialEq, BorshSerialize, BorshDeserialize, Serialize, Deserialize)]
16+
pub struct AsmState {
17+
state: AnchorState,
18+
logs: Vec<AsmLogEntry>,
19+
}
20+
21+
impl AsmState {
22+
pub fn new(state: AnchorState, logs: Vec<AsmLogEntry>) -> Self {
23+
Self { state, logs }
24+
}
25+
26+
pub fn from_output(output: AsmStfOutput) -> Self {
27+
Self {
28+
state: output.state,
29+
logs: output.manifest.logs.to_vec(),
30+
}
31+
}
32+
33+
pub fn logs(&self) -> &Vec<AsmLogEntry> {
34+
&self.logs
35+
}
36+
37+
pub fn state(&self) -> &AnchorState {
38+
&self.state
39+
}
40+
}

crates/worker/src/handle.rs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use async_trait::async_trait;
1+
//! Handle for interacting with the ASM worker service.
2+
23
use strata_identifiers::L1BlockCommitment;
34
use strata_service::{CommandHandle, ServiceError, ServiceMonitor};
4-
use strata_state::BlockSubmitter;
55

66
use crate::{AsmWorkerStatus, WorkerError, message::AsmWorkerMessage};
77

@@ -24,37 +24,32 @@ impl AsmWorkerHandle {
2424
}
2525
}
2626

27-
/// Allows other services to listen to status updates.
28-
///
29-
/// Can be useful for logic that want to listen to logs/updates of ASM state.
30-
pub fn monitor(&self) -> &ServiceMonitor<AsmWorkerStatus> {
31-
&self.monitor
32-
}
33-
34-
/// Returns the number of pending inputs that have not been processed yet.
35-
pub fn pending(&self) -> usize {
36-
self.command_handle.pending()
37-
}
38-
}
39-
40-
#[async_trait]
41-
impl BlockSubmitter for AsmWorkerHandle {
4227
/// Sends an L1 block to the ASM service and waits for processing to complete.
43-
fn submit_block(&self, block: L1BlockCommitment) -> anyhow::Result<()> {
28+
pub fn submit_block(&self, block: L1BlockCommitment) -> anyhow::Result<()> {
4429
self.command_handle
4530
.send_and_wait_blocking(|completion| AsmWorkerMessage::SubmitBlock(block, completion))
4631
.map_err(convert_service_error)?
4732
.map_err(Into::into)
4833
}
4934

50-
/// Sends an L1 block to the ASM service and waits for processing to complete.
51-
async fn submit_block_async(&self, block: L1BlockCommitment) -> anyhow::Result<()> {
35+
/// Sends an L1 block to the ASM service and waits for processing to complete (async).
36+
pub async fn submit_block_async(&self, block: L1BlockCommitment) -> anyhow::Result<()> {
5237
self.command_handle
5338
.send_and_wait(|completion| AsmWorkerMessage::SubmitBlock(block, completion))
5439
.await
5540
.map_err(convert_service_error)?
5641
.map_err(Into::into)
5742
}
43+
44+
/// Allows other services to listen to status updates.
45+
pub fn monitor(&self) -> &ServiceMonitor<AsmWorkerStatus> {
46+
&self.monitor
47+
}
48+
49+
/// Returns the number of pending inputs that have not been processed yet.
50+
pub fn pending(&self) -> usize {
51+
self.command_handle.pending()
52+
}
5853
}
5954

6055
/// Convert service framework errors to worker errors.

crates/worker/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! The `strata-asm-worker` crate provides a dedicated asynchronous worker
44
//! for managing Strata's Anchor state (ASM).
55
6+
mod asm_state;
67
mod aux_resolver;
78
mod builder;
89
mod constants;
@@ -13,6 +14,7 @@ mod service;
1314
mod state;
1415
mod traits;
1516

17+
pub use asm_state::AsmState;
1618
pub use aux_resolver::AuxDataResolver;
1719
pub use builder::AsmWorkerBuilder;
1820
pub use errors::{WorkerError, WorkerResult};

crates/worker/src/message.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
33
use strata_identifiers::L1BlockCommitment;
44
use strata_service::CommandCompletionSender;
5-
use strata_state::asm_state::AsmState;
65

7-
use crate::WorkerResult;
6+
use crate::{AsmState, WorkerResult};
87

98
/// Messages from the ASM Handle to the subprotocol to give it work to do.
109
#[derive(Debug)]

0 commit comments

Comments
 (0)