github: https://github.com/soonlabs/igloo.git
igloo\example\src\main.rs
async fn main() -> Result<()> {
env_logger::init();
let (instant_sender, instant_receiver) = channel(1024);
let instanct_driver = InstantDeriveImpl::new(instant_receiver);
let (da_sender, da_receiver) = channel(1);
let da_driver = DaDeriveImpl::default();
let (attribute_sender, attribute_receiver) = channel(1024);
let mut runner = SimpleRunner::new(Path::new("/tmp/igloo-example"), attribute_sender)?; // blockstore和accountsdb 存储路径
runner.register_instant(instanct_driver); // 从instant_sender获取非安全区块数据
runner.register_da(da_driver.clone()); // 从DA获取安全区块数据
MockLayer1::new(1000, instant_sender).run(); // 从起始高度 1000,每隔12s 产生一个mock区块,喂到 instant_sender
TxServer::new(runner.get_engine().stream().clone()).run();// 每秒随机0-4个L2交易,喂到stream
Batcher::new(da_sender).run(attribute_receiver); // 将da_sender接收到的交易通过receive_tx_loop放到cache,每隔20s将catche中的交易通过da_sender发送给da_receiver
da_driver.run(da_receiver); // 将da_receiver接收到的数据,写入到cached,模拟DA
loop {
if let Err(e) = runner.advance().await {
// We should match the error type and panic accordingly in production code
error!("Error: {}", e);
}
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
}
}
igloo\example\src\runner.rs
impl SimpleRunner {
pub fn new(
base_path: &Path,
attribute_sender: Sender<PayloadAttributeImpl>,
) -> anyhow::Result<Self> {
Ok(Self {
engine: SvmEngine::new(base_path, attribute_sender)?,
instant_derive: None,
da_derive: None,
current_head: None,
sequence_number: 0,
})
}
async fn advance_unsafe(&mut self) -> Result<()> {
let info = self.instant_derive()?.get_new_block().await?; // 从L1获取L2提交的交易
async fn advance_safe(&mut self) -> Result<()> { // 从DA中检查并获取未执行的区块数据,DA中的数据认为是已经经过检查,所以作为安全数据
trace!("begin of da derive");
while let Some(attribute) = self.da_derive()?.next().await {
if self.has_executed(&attribute) { // 检查是否已经执行过
debug!(
"skip executed attribute at L1 height {} sequence number {}",
attribute.epoch.block_height(),
attribute.sequence_number
);
continue;
}
let block = self.engine.produce_block(attribute).await?;
self.new_block(block).await?;
}
trace!("end of da derive");
Ok(())
}
igloo\example\src\l2\engine.rs
pub async fn produce_block(
&mut self,
attribute: PayloadAttributeImpl,
) -> anyhow::Result<BlockPayloadImpl> {
let mut transactions = (*attribute.transactions).clone();
let extra_txs = {
self.stream
.write()
.await
.next_batch(Default::default())
.await
};
trace!(
"produce block with {} deposit txs, {} normal txs",
transactions.len(),
extra_txs.len()
);
transactions.extend(extra_txs);
let new_attribute = PayloadAttributeImpl { // 组装区块所需数据
transactions: Arc::new(transactions),
epoch: attribute.epoch,
sequence_number: attribute.sequence_number,
};
let block = self.producer.produce(new_attribute.clone()).await?;
if let Err(e) = self.attribute_sender.send(new_attribute).await {
error!("Failed to send attribute: {}", e);
}
Ok(block)
}
}
总结
该Demo只演示了基础的模拟区块组装,数据与DA层Mock流转,核心层代码逻辑并未开源,关注后期更新
版权属于:区块链中文技术社区 / 转载原创者
本文链接:https://bcskill.com/index.php/archives/2189.html
相关技术文章仅限于相关区块链底层技术研究,禁止用于非法用途,后果自负!本站严格遵守一切相关法律政策!