Skip to content

Commit 518b627

Browse files
authored
add recover rollup command (#594)
* add recover rollup command * combine ut to increase test stability
1 parent dddbf4c commit 518b627

File tree

4 files changed

+242
-57
lines changed

4 files changed

+242
-57
lines changed

src/node/src/command.rs

Lines changed: 96 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
//
1717

1818
use crate::indexer_impl::IndexerNodeImpl;
19-
use crate::recover::{Recover, RecoverConfig};
19+
use crate::recover::{Recover, RecoverConfig, RecoverType};
2020
use crate::rollup_executor::RollupExecutorConfig;
2121
use crate::storage_node_light_impl::{StorageNodeV2Config, StorageNodeV2Impl};
2222
use crate::system_impl::SystemImpl;
@@ -35,7 +35,7 @@ use db3_storage::db_store_v2::{DBStoreV2, DBStoreV2Config};
3535
use db3_storage::doc_store::DocStoreConfig;
3636
use db3_storage::key_store::KeyStore;
3737
use db3_storage::key_store::KeyStoreConfig;
38-
use db3_storage::mutation_store::MutationStoreConfig;
38+
use db3_storage::mutation_store::{MutationStore, MutationStoreConfig};
3939
use db3_storage::state_store::{StateStore, StateStoreConfig};
4040
use db3_storage::system_store::{SystemRole, SystemStore, SystemStoreConfig};
4141
use ethers::prelude::LocalWallet;
@@ -183,6 +183,35 @@ pub enum RecoverCommand {
183183
verbose: bool,
184184
},
185185
// TODO: support recover rollup
186+
#[clap(name = "rollup")]
187+
Rollup {
188+
/// The database path for mutation
189+
#[clap(long, default_value = "./mutation_db")]
190+
mutation_db_path: String,
191+
/// The database path for state
192+
#[clap(long, default_value = "./state_db")]
193+
state_db_path: String,
194+
/// The database path for doc db
195+
#[clap(long, default_value = "./doc_db")]
196+
doc_db_path: String,
197+
#[clap(short, long, default_value = "./rollup_meta_db")]
198+
meta_db_path: String,
199+
#[clap(short, long, default_value = "./keys")]
200+
key_root_path: String,
201+
#[clap(short, long, default_value = "./recover_rollup_temp")]
202+
recover_temp_path: String,
203+
#[clap(
204+
short,
205+
long,
206+
default_value = "0x0000000000000000000000000000000000000000"
207+
)]
208+
admin_addr: String,
209+
/// this is just for upgrade the node
210+
#[clap(long, default_value = "100000")]
211+
doc_id_start: i64,
212+
#[clap(short, long)]
213+
verbose: bool,
214+
},
186215
}
187216
impl DB3Command {
188217
fn build_wallet(key_root_path: &str) -> std::result::Result<LocalWallet, DB3Error> {
@@ -382,6 +411,41 @@ impl DB3Command {
382411
info!("exit standalone indexer")
383412
}
384413
DB3Command::Recover { cmd } => match cmd {
414+
RecoverCommand::Rollup {
415+
mutation_db_path,
416+
state_db_path,
417+
doc_db_path,
418+
meta_db_path,
419+
key_root_path,
420+
recover_temp_path,
421+
admin_addr,
422+
doc_id_start,
423+
verbose,
424+
} => {
425+
let log_level = if verbose {
426+
LevelFilter::DEBUG
427+
} else {
428+
LevelFilter::INFO
429+
};
430+
431+
tracing_subscriber::fmt().with_max_level(log_level).init();
432+
info!("{ABOUT}");
433+
let recover = Self::create_recover(
434+
mutation_db_path,
435+
meta_db_path,
436+
state_db_path,
437+
doc_db_path,
438+
key_root_path,
439+
recover_temp_path,
440+
admin_addr,
441+
doc_id_start,
442+
RecoverType::Rollup,
443+
)
444+
.await;
445+
info!("start recovering index node");
446+
recover.recover_stat().unwrap();
447+
recover.recover_from_ar().await.unwrap();
448+
}
385449
RecoverCommand::Index {
386450
meta_db_path,
387451
state_db_path,
@@ -401,14 +465,15 @@ impl DB3Command {
401465
tracing_subscriber::fmt().with_max_level(log_level).init();
402466
info!("{ABOUT}");
403467
let recover = Self::create_recover(
468+
"".to_string(),
404469
meta_db_path,
405470
state_db_path,
406471
doc_db_path,
407472
key_root_path,
408473
recover_temp_path,
409474
admin_addr,
410475
doc_id_start,
411-
SystemRole::DataIndexNode,
476+
RecoverType::Index,
412477
)
413478
.await;
414479
info!("start recovering index node");
@@ -418,14 +483,15 @@ impl DB3Command {
418483
}
419484
}
420485
async fn create_recover(
486+
mutation_db_path: String,
421487
meta_db_path: String,
422488
state_db_path: String,
423489
doc_db_path: String,
424490
key_root_path: String,
425491
recover_temp_path: String,
426492
_admin_addr: String,
427493
doc_id_start: i64,
428-
role: SystemRole,
494+
recover_type: RecoverType,
429495
) -> Recover {
430496
let system_store_config = SystemStoreConfig {
431497
key_root_path: key_root_path.to_string(),
@@ -445,6 +511,10 @@ impl DB3Command {
445511
in_memory_db_handle_limit: 16,
446512
};
447513

514+
let enable_doc_store = match recover_type {
515+
RecoverType::Index => true,
516+
RecoverType::Rollup => false,
517+
};
448518
let db_store_config = DBStoreV2Config {
449519
db_path: meta_db_path.to_string(),
450520
db_store_cf_name: "db_store_cf".to_string(),
@@ -454,20 +524,38 @@ impl DB3Command {
454524
doc_owner_store_cf_name: "doc_owner_store_cf".to_string(),
455525
db_owner_store_cf_name: "db_owner_cf".to_string(),
456526
scan_max_limit: 1000,
457-
enable_doc_store: true,
527+
enable_doc_store,
458528
doc_store_conf,
459529
doc_start_id: doc_id_start,
460530
};
461531

462532
let db_store = DBStoreV2::new(db_store_config.clone()).unwrap();
533+
534+
let storage = match recover_type {
535+
RecoverType::Rollup => {
536+
let mutation_store_config = MutationStoreConfig {
537+
db_path: mutation_db_path.to_string(),
538+
block_store_cf_name: "block_store_cf".to_string(),
539+
tx_store_cf_name: "tx_store_cf".to_string(),
540+
rollup_store_cf_name: "rollup_store_cf".to_string(),
541+
gc_cf_name: "gc_store_cf".to_string(),
542+
message_max_buffer: 4 * 1024,
543+
scan_max_limit: 50,
544+
block_state_cf_name: "block_state_cf".to_string(),
545+
};
546+
let store = MutationStore::new(mutation_store_config).unwrap();
547+
Some(Arc::new(store))
548+
}
549+
RecoverType::Index => None,
550+
};
551+
463552
std::fs::create_dir_all(recover_temp_path.as_str()).unwrap();
464553
let recover_config = RecoverConfig {
465554
key_root_path: key_root_path.to_string(),
466555
temp_data_path: recover_temp_path.to_string(),
467-
enable_mutation_recover: false,
468-
role,
556+
recover_type,
469557
};
470-
Recover::new(recover_config, db_store, system_store)
558+
Recover::new(recover_config, db_store, system_store, storage)
471559
.await
472560
.unwrap()
473561
}

src/node/src/node_test_base.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
#[cfg(test)]
1919
pub mod tests {
20-
use crate::recover::{Recover, RecoverConfig};
20+
use crate::recover::{Recover, RecoverConfig, RecoverType};
2121
use crate::rollup_executor::{RollupExecutor, RollupExecutorConfig};
2222
use db3_crypto::db3_address::DB3Address;
2323
use db3_error::Result;
@@ -106,16 +106,14 @@ pub mod tests {
106106
let recover_index_config = RecoverConfig {
107107
key_root_path: key_root_path.to_string(),
108108
temp_data_path: format!("{real_path}/recover_index_temp_data"),
109-
enable_mutation_recover: true,
110-
role: SystemRole::DataIndexNode,
109+
recover_type: RecoverType::Index,
111110
};
112111
if let Err(_e) = std::fs::create_dir_all(recover_index_config.temp_data_path.as_str()) {
113112
}
114113
let recover_rollup_config = RecoverConfig {
115114
key_root_path: key_root_path.to_string(),
116115
temp_data_path: format!("{real_path}/recover_rollup_temp_data"),
117-
enable_mutation_recover: true,
118-
role: SystemRole::DataRollupNode,
116+
recover_type: RecoverType::Rollup,
119117
};
120118
if let Err(_e) = std::fs::create_dir_all(recover_rollup_config.temp_data_path.as_str())
121119
{
@@ -193,6 +191,7 @@ pub mod tests {
193191
recover_rollup_config,
194192
db_store.clone(),
195193
system_store.clone(),
194+
None,
196195
)
197196
.await?;
198197
Ok((rollup_executor, rollup_recover))

src/node/src/recover.rs

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,38 @@
1717

1818
use crate::ar_toolbox::ArToolBox;
1919
use crate::mutation_utils::MutationUtil;
20+
use bytes::BytesMut;
21+
use db3_crypto::id::TxId;
2022
use db3_error::{DB3Error, Result};
21-
use db3_proto::db3_mutation_v2_proto::MutationAction;
23+
use db3_proto::db3_mutation_v2_proto::{MutationAction, MutationBody, MutationHeader};
2224
use db3_storage::ar_fs::{ArFileSystem, ArFileSystemConfig};
2325
use db3_storage::db_store_v2::DBStoreV2;
2426
use db3_storage::meta_store_client::MetaStoreClient;
27+
use db3_storage::mutation_store::MutationStore;
2528
use db3_storage::system_store::{SystemRole, SystemStore};
2629
use ethers::prelude::Signer;
30+
use prost::Message;
2731
use std::sync::atomic::{AtomicU64, Ordering};
2832
use std::sync::Arc;
2933
use tracing::{debug, info};
3034

35+
#[derive(Clone)]
36+
pub enum RecoverType {
37+
Index,
38+
Rollup,
39+
}
3140
#[derive(Clone)]
3241
pub struct RecoverConfig {
3342
pub key_root_path: String,
3443
pub temp_data_path: String,
35-
pub enable_mutation_recover: bool,
36-
pub role: SystemRole,
44+
pub recover_type: RecoverType,
3745
}
3846
pub struct Recover {
3947
pub config: RecoverConfig,
4048
pub ar_toolbox: Arc<ArToolBox>,
4149
pub meta_store: Arc<MetaStoreClient>,
4250
pub db_store: Arc<DBStoreV2>,
51+
pub storage: Option<Arc<MutationStore>>,
4352
network_id: Arc<AtomicU64>,
4453
}
4554

@@ -48,8 +57,13 @@ impl Recover {
4857
config: RecoverConfig,
4958
db_store: DBStoreV2,
5059
system_store: Arc<SystemStore>,
60+
storage: Option<Arc<MutationStore>>,
5161
) -> Result<Self> {
52-
let system_config = match system_store.get_config(&config.role) {
62+
let role = match config.recover_type {
63+
RecoverType::Index => SystemRole::DataIndexNode,
64+
RecoverType::Rollup => SystemRole::DataRollupNode,
65+
};
66+
let system_config = match system_store.get_config(&role) {
5367
Ok(Some(system_config)) => system_config,
5468
Ok(None) => {
5569
return Err(DB3Error::StoreEventError(
@@ -87,6 +101,7 @@ impl Recover {
87101
ar_toolbox,
88102
meta_store,
89103
db_store: Arc::new(db_store),
104+
storage,
90105
network_id,
91106
})
92107
}
@@ -95,6 +110,14 @@ impl Recover {
95110
Ok(())
96111
}
97112

113+
pub fn recover_stat(&self) -> Result<()> {
114+
self.db_store.recover_db_state()?;
115+
if let Some(s) = &self.storage {
116+
s.recover()?;
117+
}
118+
Ok(())
119+
}
120+
98121
pub async fn recover_from_ar(&self) -> Result<()> {
99122
info!("start recover from arweave");
100123
let last_block = self.db_store.recover_block_state()?;
@@ -134,6 +157,13 @@ impl Recover {
134157
Ok(from_block)
135158
}
136159

160+
pub fn is_recover_rollup(&self) -> bool {
161+
match self.config.recover_type {
162+
RecoverType::Rollup => true,
163+
_ => false,
164+
}
165+
}
166+
137167
/// recover from arweave tx
138168
async fn recover_from_arweave_tx(&self, tx: &str, version: Option<String>) -> Result<()> {
139169
debug!("recover_from_arweave_tx: {}, version {:?}", tx, version);
@@ -160,6 +190,22 @@ impl Recover {
160190
order.clone(),
161191
&doc_ids_map,
162192
)?;
193+
194+
if self.is_recover_rollup() {
195+
if let Some(s) = &self.storage {
196+
s.update_mutation_stat(
197+
&body.payload,
198+
body.signature.as_str(),
199+
doc_ids.as_str(),
200+
&address,
201+
nonce,
202+
*block,
203+
*order,
204+
self.network_id.load(Ordering::Relaxed),
205+
action,
206+
)?;
207+
}
208+
}
163209
}
164210
}
165211

@@ -206,25 +252,6 @@ mod tests {
206252
use std::thread::sleep;
207253
use tempdir::TempDir;
208254

209-
#[tokio::test]
210-
async fn test_get_latest_arweave_tx() {
211-
sleep(std::time::Duration::from_secs(1));
212-
let tmp_dir_path = TempDir::new("test_get_latest_arweave_tx").expect("create temp dir");
213-
match NodeTestBase::setup_for_smoke_test(&tmp_dir_path).await {
214-
Ok((rollup_executor, recover)) => {
215-
let result = rollup_executor.process().await;
216-
assert_eq!(true, result.is_ok(), "{:?}", result);
217-
let result = recover.get_latest_arweave_tx().await;
218-
assert_eq!(true, result.is_ok(), "{:?}", result);
219-
let tx = result.unwrap();
220-
assert!(!tx.is_empty());
221-
}
222-
Err(e) => {
223-
assert!(false, "{e}");
224-
}
225-
}
226-
}
227-
228255
#[tokio::test]
229256
async fn test_fetch_arware_tx_from_block() {
230257
sleep(std::time::Duration::from_secs(3));

0 commit comments

Comments
 (0)