Skip to content

Commit 710b0f9

Browse files
committed
sugondat-da-adapter: use shim
this removes all the subxt and substrate cruft from the sovereign adapter.
1 parent a0f6976 commit 710b0f9

File tree

5 files changed

+59
-155
lines changed

5 files changed

+59
-155
lines changed

Cargo.lock

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

sugondat-da-adapter/Cargo.toml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,8 @@ edition = "2021"
88
[dependencies]
99
parity-scale-codec = "3.6.3"
1010
# The only required dependency for a DA adapter is the Sovereign SDK...
11-
sov-rollup-interface = { git = "https://github.com/Sovereign-Labs/sovereign-sdk", rev = "6058b31" }
11+
sov-rollup-interface = { git = "https://github.com/Sovereign-Labs/sovereign-sdk", rev = "6058b31" }
1212

13-
sugondat-subxt = { path = "../sugondat-subxt", optional = true }
14-
subxt = {version = "0.32.1", optional = true }
15-
subxt-signer = {version = "0.32.1", optional = true, features = ["subxt"] }
16-
sp-keyring = { git = "https://github.com/paritytech/polkadot-sdk", optional = true, default-features = false, branch = "release-polkadot-v1.2.0" }
1713
tracing = "0.1.37"
1814
serde = { version = "1", features = ["derive"] }
1915
hex = { version = "0.4.3", features = ["serde"] }
@@ -25,13 +21,23 @@ bytes = { version = "1", features = ["serde"] }
2521

2622
sha2 = { version = "0.10.6", default-features = false }
2723
sugondat-nmt = { path = "../sugondat-nmt", default-features = false }
28-
24+
jsonrpsee = { version = "0.20.3", optional = true, features = ["ws-client"] }
25+
tokio = { version = "1", optional = true }
26+
sugondat-shim-common-sovereign = { path = "../sugondat-shim/common/sovereign", optional = true, default-features = false, features = [
27+
"client",
28+
] }
2929
anyhow = "1.0.68"
3030
async-trait = "0.1.71"
31-
tokio = { version = "1", optional = true }
3231
digest = "0.10.7"
3332

3433
[features]
3534
default = ["native"]
36-
native = ["sov-rollup-interface/native", "sugondat-nmt/serde", "sugondat-nmt/native", "dep:sugondat-subxt", "dep:subxt", "dep:subxt-signer", "dep:sp-keyring", "dep:tokio"]
35+
native = [
36+
"sov-rollup-interface/native",
37+
"sugondat-nmt/serde",
38+
"sugondat-nmt/native",
39+
"dep:tokio",
40+
"dep:jsonrpsee",
41+
"dep:sugondat-shim-common-sovereign",
42+
]
3743
verifier = ["sugondat-nmt/serde"]

sugondat-da-adapter/src/service.rs

Lines changed: 17 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
use crate::{
22
spec::{ChainParams, DaLayerSpec},
3-
types,
3+
types::{self, Hash},
44
verifier::SugondatVerifier,
55
};
66
use async_trait::async_trait;
77
use sov_rollup_interface::da::DaSpec;
8-
9-
use subxt::backend::rpc::{rpc_params, RpcClient};
10-
use sugondat_subxt::sugondat::{
11-
runtime_types::bounded_collections::bounded_vec::BoundedVec, storage,
12-
};
8+
use sugondat_shim_common_sovereign::SovereignRPCClient;
139

1410
mod client;
1511

1612
use client::Client;
1713

1814
fn default_rpc_addr() -> String {
19-
"ws://localhost:9988/".into()
15+
"ws://localhost:10995/".into()
2016
}
2117

2218
/// Runtime configuration for the DA service
@@ -54,119 +50,25 @@ impl sov_rollup_interface::services::da::DaService for DaProvider {
5450
// Make an RPC call to the node to get the finalized block at the given height, if one exists.
5551
// If no such block exists, block until one does.
5652
async fn get_finalized_at(&self, height: u64) -> Result<Self::FilteredBlock, Self::Error> {
57-
let client = self.client.clone();
58-
let namespace = self.namespace;
59-
let client_url = client.url().await;
60-
let client = client.client().await?;
61-
62-
loop {
63-
let finalized_head = client.backend().latest_finalized_block_ref().await?;
64-
let header = client
65-
.backend()
66-
.block_header(finalized_head.hash())
67-
.await?
68-
.unwrap();
69-
if header.number as u64 >= height {
70-
break;
71-
}
72-
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
73-
}
74-
75-
// between version 0.29 and 0.32 they remove subxt::rpc::Rpc
76-
// so this 'raw' rpc call is required to extract the hash of the block with a certain height
77-
let rpc_client = RpcClient::from_url(client_url).await?;
78-
let hash: subxt::utils::H256 = rpc_client
79-
.request("chain_getBlockHash", rpc_params![height])
80-
.await?;
81-
82-
let block = client.blocks().at(hash).await?;
83-
84-
let header = block.header().clone();
85-
86-
let mut nmt_root = None;
87-
for log in &header.digest.logs {
88-
match log {
89-
subxt::config::substrate::DigestItem::Other(ref bytes) => {
90-
if bytes.starts_with(b"snmt") {
91-
nmt_root = Some(sugondat_nmt::TreeRoot::from_raw_bytes(
92-
bytes[4..].try_into().unwrap(),
93-
));
94-
break;
95-
}
96-
}
97-
_ => {}
98-
}
99-
}
100-
101-
// fetch timestamp from block
102-
let timestamp = block
103-
.storage()
104-
.fetch(&storage().timestamp().now())
105-
.await?
106-
.ok_or(anyhow::anyhow!("no timestamp found"))?;
107-
53+
let client = self.client.ensure_connected().await?;
54+
let block: sugondat_shim_common_sovereign::Block =
55+
client.get_block(height, self.namespace).await?;
10856
let header = types::Header::new(
109-
types::Hash(hash.0),
110-
types::Hash(header.parent_hash.0),
111-
nmt_root.unwrap(),
112-
header.number as u64,
113-
timestamp,
57+
Hash(block.block_hash),
58+
Hash(block.prev_hash),
59+
block.nmt_root,
60+
height,
61+
block.timestamp,
11462
);
115-
116-
let mut transactions = vec![];
117-
for ext in block.extrinsics().await?.iter() {
118-
let ext = ext?;
119-
let Some(address) = ext.address_bytes().map(|a| {
120-
tracing::info!("Address: {:?}", hex::encode(&a));
121-
types::Address::try_from(&a[1..]).unwrap()
122-
}) else {
123-
continue
124-
};
125-
let Ok(Some(submit_blob_extrinsic)) =
126-
ext.as_extrinsic::<sugondat_subxt::sugondat::blobs::calls::types::SubmitBlob>()
127-
else {
128-
// Not a submit blob extrinsic, skip.
129-
continue
130-
};
131-
132-
if submit_blob_extrinsic.namespace_id != namespace.namespace_id() {
133-
// Not for our app.
134-
continue;
135-
}
136-
137-
let blob_data = submit_blob_extrinsic.blob.0;
138-
tracing::info!("received a blob: {}", hex::encode(&blob_data));
139-
transactions.push(types::BlobTransaction::new(address, blob_data));
140-
}
141-
142-
let address = sugondat_subxt::sugondat::blobs::storage::StorageApi.blob_list();
143-
let blobs = client
144-
.storage()
145-
.at(hash)
146-
.fetch(&address)
147-
.await
148-
.unwrap()
149-
.map(|x| x.0)
150-
.unwrap_or_default();
151-
152-
let blobs = blobs
63+
let transactions = block
64+
.blobs
15365
.into_iter()
154-
.map(|blob| sugondat_nmt::BlobMetadata {
155-
namespace: sugondat_nmt::Namespace::with_namespace_id(blob.namespace_id),
156-
leaf: sugondat_nmt::NmtLeaf {
157-
extrinsic_index: blob.extrinsic_index,
158-
who: blob.who.0,
159-
blob_hash: blob.blob_hash,
160-
},
161-
})
66+
.map(|blob| types::BlobTransaction::new(types::Address(blob.sender), blob.data))
16267
.collect();
163-
let mut tree = sugondat_nmt::tree_from_blobs(blobs);
164-
let blob_proof = tree.proof(namespace);
165-
16668
Ok(types::Block {
16769
header,
16870
transactions,
169-
blob_proof,
71+
blob_proof: block.proof,
17072
})
17173
}
17274

@@ -200,25 +102,8 @@ impl sov_rollup_interface::services::da::DaService for DaProvider {
200102

201103
// Send the blob to the DA layer, using the submit_blob extrinsic
202104
async fn send_transaction(&self, blob: &[u8]) -> Result<(), Self::Error> {
203-
let client = self.client.clone();
204-
let blob = blob.to_vec();
205-
let namespace_id = self.namespace.namespace_id();
206-
use subxt_signer::sr25519::dev;
207-
208-
let client = client.client().await?;
209-
210-
let extrinsic = sugondat_subxt::sugondat::tx()
211-
.blobs()
212-
.submit_blob(namespace_id, BoundedVec(blob));
213-
214-
let from = dev::alice();
215-
let _events = client
216-
.tx()
217-
.sign_and_submit_then_watch_default(&extrinsic, &from)
218-
.await?
219-
.wait_for_finalized_success()
220-
.await?;
221-
105+
let client = self.client.ensure_connected().await?;
106+
client.submit_blob(blob.to_vec(), self.namespace).await?;
222107
Ok(())
223108
}
224109
}

sugondat-da-adapter/src/service/client.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,20 @@ pub struct Client {
1010

1111
struct Inner {
1212
url: String,
13-
client: Option<sugondat_subxt::Client>,
13+
client: Option<ClientRef>,
14+
}
15+
16+
#[derive(Clone)]
17+
pub struct ClientRef {
18+
client: Arc<jsonrpsee::ws_client::WsClient>,
19+
}
20+
21+
impl std::ops::Deref for ClientRef {
22+
type Target = jsonrpsee::ws_client::WsClient;
23+
24+
fn deref(&self) -> &Self::Target {
25+
&self.client
26+
}
1427
}
1528

1629
impl Client {
@@ -20,18 +33,18 @@ impl Client {
2033
}
2134
}
2235

23-
pub async fn url(&self) -> String {
24-
let inner = self.inner.lock().await;
25-
inner.url.clone()
26-
}
27-
28-
pub async fn client(&self) -> anyhow::Result<sugondat_subxt::Client> {
36+
pub async fn ensure_connected(&self) -> anyhow::Result<ClientRef> {
2937
let mut inner = self.inner.lock().await;
3038
if let Some(client) = &inner.client {
3139
return Ok(client.clone());
3240
}
3341

34-
let client = sugondat_subxt::Client::from_url(&inner.url).await?;
42+
let client = jsonrpsee::ws_client::WsClientBuilder::new()
43+
.build(inner.url.clone())
44+
.await?;
45+
let client = ClientRef {
46+
client: Arc::new(client),
47+
};
3548
inner.client = Some(client.clone());
3649
Ok(client)
3750
}

sugondat-shim/common/sovereign/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
use jsonrpsee::{proc_macros::rpc, types::ErrorObjectOwned};
1+
use jsonrpsee::proc_macros::rpc;
22

33
#[cfg(not(any(feature = "server", feature = "client")))]
44
compile_error!("either feature \"server\" or \"client\" must be enabled");
55

6+
pub type JsonRPCError = jsonrpsee::types::ErrorObjectOwned;
7+
68
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
79
pub struct Block {
810
// TODO: Hash should be a newtype that serializes to hex.
@@ -31,12 +33,12 @@ pub trait SovereignRPC {
3133
&self,
3234
height: u64,
3335
namespace: sugondat_nmt::Namespace,
34-
) -> Result<Block, ErrorObjectOwned>;
36+
) -> Result<Block, JsonRPCError>;
3537

3638
#[method(name = "sovereign_submitBlob")]
3739
async fn submit_blob(
3840
&self,
3941
blob: Vec<u8>,
4042
namespace: sugondat_nmt::Namespace,
41-
) -> Result<(), ErrorObjectOwned>;
43+
) -> Result<(), JsonRPCError>;
4244
}

0 commit comments

Comments
 (0)