Skip to content

Commit 2f529da

Browse files
gabriele-0201pepyakin
authored andcommitted
use async_trait macro
1 parent e69ff4c commit 2f529da

File tree

5 files changed

+133
-168
lines changed

5 files changed

+133
-168
lines changed

demo/Cargo.lock

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

demo/demo-rollup/provers/risc0/guest-sugondat/Cargo.lock

Lines changed: 1 addition & 0 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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ sha2 = { version = "0.10.6", default-features = false }
2727
sugondat-nmt = { path = "../sugondat-nmt", default-features = false }
2828

2929
anyhow = "1.0.68"
30+
async-trait = "0.1.71"
3031
tokio = { version = "1", optional = true }
3132
digest = "0.10.7"
3233

sugondat-da-adapter/src/service.rs

Lines changed: 129 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
types,
44
verifier::SugondatVerifier,
55
};
6+
use async_trait::async_trait;
67
use sov_rollup_interface::{da::DaSpec, services::da::DaService};
78
use std::{future::Future, pin::Pin};
89
use subxt::backend::rpc::{rpc_params, RpcClient};
@@ -43,6 +44,7 @@ impl DaProvider {
4344
}
4445
}
4546

47+
#[async_trait]
4648
impl sov_rollup_interface::services::da::DaService for DaProvider {
4749
type Spec = DaLayerSpec;
4850
type FilteredBlock = crate::types::Block;
@@ -51,143 +53,127 @@ impl sov_rollup_interface::services::da::DaService for DaProvider {
5153

5254
// Make an RPC call to the node to get the finalized block at the given height, if one exists.
5355
// If no such block exists, block until one does.
54-
fn get_finalized_at<'life0, 'async_trait>(
55-
&'life0 self,
56-
height: u64,
57-
) -> Pin<Box<dyn Future<Output = Result<Self::FilteredBlock, Self::Error>> + Send + 'async_trait>>
58-
where
59-
Self: 'async_trait,
60-
'life0: 'async_trait,
61-
{
56+
async fn get_finalized_at(&self, height: u64) -> Result<Self::FilteredBlock, Self::Error> {
6257
let client = self.client.clone();
6358
let namespace = self.namespace;
64-
Box::pin(async move {
65-
let client_url = client.url().await;
66-
let client = client.client().await?;
67-
68-
loop {
69-
let finalized_head = client.backend().latest_finalized_block_ref().await?;
70-
let header = client
71-
.backend()
72-
.block_header(finalized_head.hash())
73-
.await?
74-
.unwrap();
75-
if header.number as u64 >= height {
76-
break;
77-
}
78-
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
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;
7971
}
72+
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
73+
}
8074

81-
// between version 0.29 and 0.32 they remove subxt::rpc::Rpc
82-
// so this 'raw' rpc call is required to extract the hash of the block with a certain height
83-
let rpc_client = RpcClient::from_url(client_url).await?;
84-
let hash: subxt::utils::H256 = rpc_client
85-
.request("chain_getBlockHash", rpc_params![height])
86-
.await?;
87-
88-
let block = client.blocks().at(hash).await?;
89-
90-
let header = block.header().clone();
91-
92-
let mut nmt_root = None;
93-
for log in &header.digest.logs {
94-
match log {
95-
subxt::config::substrate::DigestItem::Other(ref bytes) => {
96-
if bytes.starts_with(b"snmt") {
97-
nmt_root = Some(sugondat_nmt::TreeRoot::from_raw_bytes(
98-
bytes[4..].try_into().unwrap(),
99-
));
100-
break;
101-
}
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;
10295
}
103-
_ => {}
10496
}
97+
_ => {}
10598
}
99+
}
106100

107-
// fetch timestamp from block
108-
let timestamp = block
109-
.storage()
110-
.fetch(&storage().timestamp().now())
111-
.await?
112-
.ok_or(anyhow::anyhow!("no timestamp found"))?;
113-
114-
let header = types::Header::new(
115-
types::Hash(hash.0),
116-
types::Hash(header.parent_hash.0),
117-
nmt_root.unwrap(),
118-
header.number as u64,
119-
timestamp,
120-
);
121-
122-
let mut transactions = vec![];
123-
for ext in block.extrinsics().await?.iter() {
124-
let ext = ext?;
125-
let Some(address) = ext.address_bytes().map(|a| {
126-
tracing::info!("Address: {:?}", hex::encode(&a));
127-
types::Address::try_from(&a[1..]).unwrap()
128-
}) else {
129-
continue;
130-
};
131-
let Ok(Some(submit_blob_extrinsic)) =
132-
ext.as_extrinsic::<sugondat_subxt::sugondat::blob::calls::types::SubmitBlob>()
133-
else {
134-
// Not a submit blob extrinsic, skip.
135-
continue;
136-
};
137-
138-
if submit_blob_extrinsic.namespace_id != namespace.namespace_id() {
139-
// Not for our app.
140-
continue;
141-
}
142-
143-
let blob_data = submit_blob_extrinsic.blob.0;
144-
tracing::info!("received a blob: {}", hex::encode(&blob_data));
145-
transactions.push(types::BlobTransaction::new(address, blob_data));
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+
108+
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,
114+
);
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::blob::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;
146135
}
147136

148-
let address = sugondat_subxt::sugondat::blob::storage::StorageApi.blob_list();
149-
let blobs = client
150-
.storage()
151-
.at(hash)
152-
.fetch(&address)
153-
.await
154-
.unwrap()
155-
.map(|x| x.0)
156-
.unwrap_or_default();
157-
158-
let blobs = blobs
159-
.into_iter()
160-
.map(|blob| sugondat_nmt::BlobMetadata {
161-
namespace: sugondat_nmt::Namespace::with_namespace_id(blob.namespace_id),
162-
leaf: sugondat_nmt::NmtLeaf {
163-
extrinsic_index: blob.extrinsic_index,
164-
who: blob.who.0,
165-
blob_hash: blob.blob_hash,
166-
},
167-
})
168-
.collect();
169-
let mut tree = sugondat_nmt::tree_from_blobs(blobs);
170-
let blob_proof = tree.proof(namespace);
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+
}
171141

172-
Ok(types::Block {
173-
header,
174-
transactions,
175-
blob_proof,
142+
let address = sugondat_subxt::sugondat::blob::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
153+
.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+
},
176161
})
162+
.collect();
163+
let mut tree = sugondat_nmt::tree_from_blobs(blobs);
164+
let blob_proof = tree.proof(namespace);
165+
166+
Ok(types::Block {
167+
header,
168+
transactions,
169+
blob_proof,
177170
})
178171
}
179172

180173
// Make an RPC call to the node to get the block at the given height
181174
// If no such block exists, block until one does.
182-
fn get_block_at<'life0, 'async_trait>(
183-
&'life0 self,
184-
height: u64,
185-
) -> Pin<Box<dyn Future<Output = Result<Self::FilteredBlock, Self::Error>> + Send + 'async_trait>>
186-
where
187-
Self: 'async_trait,
188-
'life0: 'async_trait,
189-
{
190-
self.get_finalized_at(height)
175+
async fn get_block_at(&self, height: u64) -> Result<Self::FilteredBlock, Self::Error> {
176+
self.get_finalized_at(height).await
191177
}
192178

193179
// Extract the blob transactions relevant to a particular rollup from a block.
@@ -201,63 +187,38 @@ impl sov_rollup_interface::services::da::DaService for DaProvider {
201187
block.transactions.clone()
202188
}
203189

204-
fn get_extraction_proof<'life0, 'life1, 'life2, 'async_trait>(
205-
&'life0 self,
206-
block: &'life1 Self::FilteredBlock,
207-
blobs: &'life2 [<Self::Spec as DaSpec>::BlobTransaction],
208-
) -> Pin<
209-
Box<
210-
dyn Future<
211-
Output = (
212-
<Self::Spec as DaSpec>::InclusionMultiProof,
213-
<Self::Spec as DaSpec>::CompletenessProof,
214-
),
215-
> + Send
216-
+ 'async_trait,
217-
>,
218-
>
219-
where
220-
Self: 'async_trait,
221-
'life0: 'async_trait,
222-
'life1: 'async_trait,
223-
'life2: 'async_trait,
224-
{
225-
Box::pin(async { (block.blob_proof.clone(), ()) })
190+
async fn get_extraction_proof(
191+
&self,
192+
block: &Self::FilteredBlock,
193+
blobs: &[<Self::Spec as DaSpec>::BlobTransaction],
194+
) -> (
195+
<Self::Spec as DaSpec>::InclusionMultiProof,
196+
<Self::Spec as DaSpec>::CompletenessProof,
197+
) {
198+
(block.blob_proof.clone(), ())
226199
}
227200

228201
// Send the blob to the DA layer, using the submit_blob extrinsic
229-
fn send_transaction<'life0, 'life1, 'async_trait>(
230-
&'life0 self,
231-
blob: &'life1 [u8],
232-
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
233-
where
234-
Self: 'async_trait,
235-
'life0: 'async_trait,
236-
'life1: 'async_trait,
237-
{
202+
async fn send_transaction(&self, blob: &[u8]) -> Result<(), Self::Error> {
238203
let client = self.client.clone();
239204
let blob = blob.to_vec();
240205
let namespace_id = self.namespace.namespace_id();
241-
Box::pin(async move {
242-
use sp_keyring::AccountKeyring;
243-
use subxt::tx::Signer;
244-
use subxt_signer::sr25519::dev;
206+
use subxt_signer::sr25519::dev;
245207

246-
let client = client.client().await?;
208+
let client = client.client().await?;
247209

248-
let extrinsic = sugondat_subxt::sugondat::tx()
249-
.blob()
250-
.submit_blob(namespace_id, BoundedVec(blob));
210+
let extrinsic = sugondat_subxt::sugondat::tx()
211+
.blob()
212+
.submit_blob(namespace_id, BoundedVec(blob));
251213

252-
let from = dev::alice();
253-
let _events = client
254-
.tx()
255-
.sign_and_submit_then_watch_default(&extrinsic, &from)
256-
.await?
257-
.wait_for_finalized_success()
258-
.await?;
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?;
259221

260-
Ok(())
261-
})
222+
Ok(())
262223
}
263224
}

sugondat-submit-blob/Cargo.lock

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

0 commit comments

Comments
 (0)