Skip to content

Commit

Permalink
[Bitcoin] UTXO genesis import tool (#1632)
Browse files Browse the repository at this point in the history
* implements utxo genesis import cli

* fixup child object store as parent object field

* finish statedb genesis-utxo tool

* remove unused code
  • Loading branch information
baichuan3 authored Apr 28, 2024
1 parent e7d770a commit 592f471
Show file tree
Hide file tree
Showing 23 changed files with 965 additions and 34 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions crates/rooch-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ impl RoochOpt {
}
}

pub fn new_with_default(
base_data_dir: Option<PathBuf>,
chain_id: Option<RoochChainID>,
) -> Self {
RoochOpt {
base_data_dir,
chain_id,
..Default::default()
}
}

pub fn ethereum_relayer_config(&self) -> Option<EthereumRelayerConfig> {
self.eth_rpc_url
.as_ref()
Expand Down
4 changes: 2 additions & 2 deletions crates/rooch-executor/src/actor/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use rooch_genesis::FrameworksGasParameters;
use rooch_store::RoochStore;
use rooch_types::address::MultiChainAddress;
use rooch_types::bitcoin::light_client::BitcoinLightClientModule;
use rooch_types::framework::address_mapping::AddressMapping;
use rooch_types::framework::address_mapping::AddressMappingModule;
use rooch_types::framework::auth_validator::{AuthValidatorCaller, TxValidateResult};
use rooch_types::framework::ethereum_light_client::EthereumLightClientModule;
use rooch_types::framework::transaction_validator::TransactionValidator;
Expand Down Expand Up @@ -91,7 +91,7 @@ impl ExecutorActor {
multi_chain_address_sender: MultiChainAddress,
) -> Result<AccountAddress> {
let resolved_sender = {
let address_mapping = self.as_module_binding::<AddressMapping>();
let address_mapping = self.as_module_binding::<AddressMappingModule>();
address_mapping.resolve_or_generate(multi_chain_address_sender)?
};

Expand Down
6 changes: 3 additions & 3 deletions crates/rooch-rpc-server/src/service/aggregate_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rooch_types::address::{BitcoinAddress, MultiChainAddress};
use rooch_types::bitcoin::ord::{Inscription, InscriptionState};
use rooch_types::bitcoin::utxo::{UTXOState, UTXO};
use rooch_types::framework::account_coin_store::AccountCoinStoreModule;
use rooch_types::framework::address_mapping::AddressMapping;
use rooch_types::framework::address_mapping::AddressMappingModule;
use rooch_types::framework::coin::{CoinInfo, CoinModule};
use rooch_types::framework::coin_store::CoinStore;
use rooch_types::indexer::state::IndexerObjectState;
Expand Down Expand Up @@ -269,7 +269,7 @@ impl AggregateService {
let address_mapping_module = self
.rpc_service
.executor
.as_module_binding::<AddressMapping>();
.as_module_binding::<AddressMappingModule>();
let (_address_mapping_handle, _mapping_handle, reverse_mapping_handle) =
address_mapping_module.address_mapping_handle()?;

Expand Down Expand Up @@ -352,7 +352,7 @@ impl AggregateService {
let address_mapping_module = self
.rpc_service
.executor
.as_module_binding::<AddressMapping>();
.as_module_binding::<AddressMappingModule>();
let (_address_mapping_handle, _mapping_handle, reverse_mapping_handle) =
address_mapping_module.address_mapping_handle()?;

Expand Down
43 changes: 32 additions & 11 deletions crates/rooch-types/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use bitcoin::{
};

use ethers::types::H160;
use fastcrypto::hash::Blake2b256;
use fastcrypto::hash::HashFunction;
use fastcrypto::secp256k1::Secp256k1PublicKey;
use move_core_types::language_storage::TypeTag;
use move_core_types::{
account_address::AccountAddress,
ident_str,
Expand All @@ -24,7 +27,7 @@ use move_core_types::{
};
#[cfg(any(test, feature = "fuzzing"))]
use moveos_types::h256;
use moveos_types::state::MoveState;
use moveos_types::state::{KeyState, MoveState};
use moveos_types::{
h256::H256,
state::{MoveStructState, MoveStructType},
Expand Down Expand Up @@ -117,6 +120,11 @@ impl MultiChainAddress {
pub fn to_bytes(&self) -> Vec<u8> {
bcs::to_bytes(self).expect("bcs encode should success")
}

pub fn to_key(&self) -> KeyState {
let key_type = TypeTag::Struct(Box::new(Self::struct_tag()));
KeyState::new(self.to_bytes(), key_type)
}
}

impl Serialize for MultiChainAddress {
Expand Down Expand Up @@ -229,13 +237,15 @@ impl TryFrom<MultiChainAddress> for RoochAddress {
type Error = anyhow::Error;

fn try_from(value: MultiChainAddress) -> Result<Self, Self::Error> {
if value.multichain_id != RoochMultiChainID::Rooch {
return Err(anyhow::anyhow!(
"multichain_id type {} is invalid",
value.multichain_id
));
}
Ok(Self(H256::from_slice(&value.raw_address)))
let address = if value.multichain_id != RoochMultiChainID::Rooch {
let mut hasher = Blake2b256::default();
hasher.update(&value.raw_address);
let g_arr = hasher.finalize();
Self(H256(g_arr.digest))
} else {
Self(H256::from_slice(&value.raw_address))
};
Ok(address)
}
}

Expand Down Expand Up @@ -915,15 +925,26 @@ mod test {
#[test]
pub fn test_bitcoin_address_to_rooch_address() -> Result<()> {
// let bitcoin_address_str = "bc1qvz9u76epzm67x0gkxj8l8udzldc0lskspecuf5";
let bitcoin_address_str = "18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX";
// let bitcoin_address_str = "18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX";
let bitcoin_address_str = "bc1q262qeyyhdakrje5qaux8m2a3r4z8sw8vu5mysh";

let maddress = MultiChainAddress::try_from_str_with_multichain_id(
RoochMultiChainID::Bitcoin,
bitcoin_address_str,
)?;
// println!(
// "test_bitcoin_address_to_rooch_address {} ",
// hex::encode(maddress.raw_address.clone())
// );

let rooch_address = RoochAddress::try_from(maddress)?;
println!(
"test_bitcoin_address_to_rooch_address {} ",
hex::encode(maddress.raw_address)
"test_bitcoin_address_to_rooch_address rooch_address {} ",
rooch_address.to_string()
);
assert_eq!(
rooch_address.to_string(),
"0x7fe695faf7047ccfbc85f7dccb6c405d4e9b7b44788e71a71c3891a06ce0ca12"
);

Ok(())
Expand Down
84 changes: 81 additions & 3 deletions crates/rooch-types/src/framework/address_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,99 @@ use crate::address::{MultiChainAddress, RoochAddress};
use crate::addresses::ROOCH_FRAMEWORK_ADDRESS;
use anyhow::{Ok, Result};
use move_core_types::{account_address::AccountAddress, ident_str, identifier::IdentStr};
use moveos_types::moveos_std::object;
use moveos_types::moveos_std::object::ObjectID;
use moveos_types::state::MoveStructType;
use moveos_types::{
module_binding::{ModuleBinding, MoveFunctionCaller},
move_std::option::MoveOption,
moveos_std::tx_context::TxContext,
state::MoveState,
transaction::FunctionCall,
};
use serde::{Deserialize, Serialize};

pub const MODULE_NAME: &IdentStr = ident_str!("address_mapping");

pub const NAMED_MAPPING_INDEX: u64 = 0;
pub const NAMED_REVERSE_MAPPING_INDEX: u64 = 1;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AddressMappingWrapper {
// mapping: Table<MultiChainAddress, AccountAddress>,
// mapping: Table<MultiChainAddress, RoochAddress>,
// reverse_mapping: Table<AccountAddress, Vec<MultiChainAddress>>,
// reverse_mapping: Table<RoochAddress, Vec<MultiChainAddress>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AddressMappingIndex {
pub index: u64,
}

impl MoveStructType for AddressMappingWrapper {
const ADDRESS: AccountAddress = ROOCH_FRAMEWORK_ADDRESS;
const MODULE_NAME: &'static IdentStr = MODULE_NAME;
const STRUCT_NAME: &'static IdentStr = ident_str!("AddressMapping");
}

impl AddressMappingWrapper {
pub fn address_mapping_object_id() -> ObjectID {
object::named_object_id(&Self::struct_tag())
}

pub fn mapping_object_id() -> ObjectID {
let named_index = AddressMappingIndex {
index: NAMED_MAPPING_INDEX,
};
object::custom_object_id(&named_index, &Self::struct_tag())
}

pub fn reverse_mapping_object_id() -> ObjectID {
let named_index = AddressMappingIndex {
index: NAMED_REVERSE_MAPPING_INDEX,
};
object::custom_object_id(&named_index, &Self::struct_tag())
}
}

// #[derive(Debug, Clone, Serialize, Deserialize)]
// pub struct AddressMapping {
// mapping: Table<MultiChainAddress, AccountAddress>,
// // mapping: Table<MultiChainAddress, RoochAddress>,
// reverse_mapping: Table<AccountAddress, Vec<MultiChainAddress>>,
// // reverse_mapping: Table<RoochAddress, Vec<MultiChainAddress>>,
// }
//
// impl MoveStructType for AddressMapping {
// const ADDRESS: AccountAddress = ROOCH_FRAMEWORK_ADDRESS;
// const MODULE_NAME: &'static IdentStr = MODULE_NAME;
// const STRUCT_NAME: &'static IdentStr = ident_str!("AddressMapping");
// }
//
// impl MoveStructState for AddressMapping {
// fn struct_layout() -> MoveStructLayout {
// MoveStructLayout::new(vec![
// MoveTypeLayout::Struct(Table::<MultiChainAddress, AccountAddress>::struct_layout()),
// MoveTypeLayout::Struct(
// Table::<AccountAddress, Vec<MultiChainAddress>>::struct_layout(),
// ),
// ])
// }
// }
//
// impl AddressMapping {
// pub fn address_mapping_object_id() -> ObjectID {
// object::named_object_id(&Self::struct_tag())
// }
// }

/// Rust bindings for RoochFramework address_mapping module
pub struct AddressMapping<'a> {
pub struct AddressMappingModule<'a> {
caller: &'a dyn MoveFunctionCaller,
}

impl<'a> AddressMapping<'a> {
impl<'a> AddressMappingModule<'a> {
const RESOLVE_FUNCTION_NAME: &'static IdentStr = ident_str!("resolve");
const RESOLVE_OR_GENERATE_FUNCTION_NAME: &'static IdentStr = ident_str!("resolve_or_generate");
const ADDRESS_MAPPING_HANDLE_FUNCTION_NAME: &'static IdentStr =
Expand Down Expand Up @@ -124,7 +202,7 @@ impl<'a> AddressMapping<'a> {
}
}

impl<'a> ModuleBinding<'a> for AddressMapping<'a> {
impl<'a> ModuleBinding<'a> for AddressMappingModule<'a> {
const MODULE_NAME: &'static IdentStr = ident_str!("address_mapping");
const MODULE_ADDRESS: AccountAddress = ROOCH_FRAMEWORK_ADDRESS;

Expand Down
3 changes: 3 additions & 0 deletions crates/rooch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ moveos = { workspace = true }
moveos-verifier = { workspace = true }
moveos-object-runtime = { workspace = true }
framework-builder = { workspace = true }
raw-store = { workspace = true }
smt = { workspace = true }
bitcoin = { workspace = true }

rooch-key = { workspace = true }
rooch-types = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions crates/rooch/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ pub mod rpc;
pub mod server;
pub mod session_key;
pub mod state;
pub mod statedb;
pub mod transaction;
40 changes: 40 additions & 0 deletions crates/rooch/src/commands/statedb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Rooch Statedb tool

A tool to export and import rooch statedb.

### Usage

1. rooch statedb genesis-utxo
```shell
rooch statedb genesis-utxo --input ~/utxo.txt -d ~/.rooch -n local
```

Step 1, cleanup database files
```shell
rooch server clean -n local
```

Step 2, start server to initialization genesis
```shell
rooch server start -n local
```

Step 3, stop server
```shell
kill {server pid} or Ctrl-C
```

Step 4 run statedb genesis-utxo command
```shell
rooch statedb genesis-utxo --input {utxo.file} -d {rooch.database.file} -n {rooch.network}
```

2. rooch statedb export
```shell
todo!
```

3. rooch statedb import
```shell
todo!
```
26 changes: 26 additions & 0 deletions crates/rooch/src/commands/statedb/commands/export.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use crate::cli_types::WalletContextOptions;
use clap::Parser;
use rooch_types::error::RoochResult;
use std::path::PathBuf;

/// Export statedb
#[derive(Debug, Parser)]
pub struct ExportCommand {
#[clap(long, short = 'o')]
/// export output file. like ~/.rooch/local/utxo.csv or utxo.csv
pub output: PathBuf,

#[clap(flatten)]
pub context_options: WalletContextOptions,
}

impl ExportCommand {
pub async fn execute(self) -> RoochResult<()> {
let mut _context = self.context_options.build()?;

todo!()
}
}
Loading

0 comments on commit 592f471

Please sign in to comment.