mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-07 15:53:14 +00:00
feat: periodic snapshooting
This commit is contained in:
parent
0d577da288
commit
66def746e6
@ -16,6 +16,7 @@ use crate::key_management::{
|
|||||||
pub type PublicKey = AffinePoint;
|
pub type PublicKey = AffinePoint;
|
||||||
pub type AccountAddress = TreeHashType;
|
pub type AccountAddress = TreeHashType;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Account {
|
pub struct Account {
|
||||||
pub key_holder: AddressKeyHolder,
|
pub key_holder: AddressKeyHolder,
|
||||||
pub address: AccountAddress,
|
pub address: AccountAddress,
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use ephemeral_key_holder::EphemeralKeyHolder;
|
|||||||
use k256::AffinePoint;
|
use k256::AffinePoint;
|
||||||
use log::info;
|
use log::info;
|
||||||
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::account_core::PublicKey;
|
use crate::account_core::PublicKey;
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ pub mod constants_types;
|
|||||||
pub mod ephemeral_key_holder;
|
pub mod ephemeral_key_holder;
|
||||||
pub mod secret_holders;
|
pub mod secret_holders;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug, Serialize, Clone)]
|
||||||
///Entrypoint to key management
|
///Entrypoint to key management
|
||||||
pub struct AddressKeyHolder {
|
pub struct AddressKeyHolder {
|
||||||
//Will be useful in future
|
//Will be useful in future
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use common::merkle_tree_public::TreeHashType;
|
|||||||
use elliptic_curve::PrimeField;
|
use elliptic_curve::PrimeField;
|
||||||
use k256::{AffinePoint, FieldBytes, Scalar};
|
use k256::{AffinePoint, FieldBytes, Scalar};
|
||||||
use rand::{rngs::OsRng, RngCore};
|
use rand::{rngs::OsRng, RngCore};
|
||||||
|
use serde::Serialize;
|
||||||
use sha2::{digest::FixedOutput, Digest};
|
use sha2::{digest::FixedOutput, Digest};
|
||||||
|
|
||||||
use super::constants_types::{NULLIFIER_SECRET_CONST, VIEWING_SECRET_CONST};
|
use super::constants_types::{NULLIFIER_SECRET_CONST, VIEWING_SECRET_CONST};
|
||||||
@ -13,13 +14,13 @@ pub struct SeedHolder {
|
|||||||
seed: Scalar,
|
seed: Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Serialize, Clone)]
|
||||||
///Secret spending key holder. Produces `UTXOSecretKeyHolder` objects.
|
///Secret spending key holder. Produces `UTXOSecretKeyHolder` objects.
|
||||||
pub struct TopSecretKeyHolder {
|
pub struct TopSecretKeyHolder {
|
||||||
pub secret_spending_key: Scalar,
|
pub secret_spending_key: Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Serialize, Clone)]
|
||||||
///Nullifier secret key and viewing secret key holder. Produces public keys. Can produce address. Can produce shared secret for recepient.
|
///Nullifier secret key and viewing secret key holder. Produces public keys. Can produce address. Can produce shared secret for recepient.
|
||||||
pub struct UTXOSecretKeyHolder {
|
pub struct UTXOSecretKeyHolder {
|
||||||
pub nullifier_secret_key: Scalar,
|
pub nullifier_secret_key: Scalar,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use std::path::Path;
|
|||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use common::block::Block;
|
use common::block::Block;
|
||||||
|
use log::warn;
|
||||||
use storage::sc_db_utils::{DataBlob, DataBlobChangeVariant};
|
use storage::sc_db_utils::{DataBlob, DataBlobChangeVariant};
|
||||||
use storage::RocksDBIO;
|
use storage::RocksDBIO;
|
||||||
|
|
||||||
@ -56,6 +57,35 @@ impl NodeBlockStore {
|
|||||||
pub fn get_sc_sc_state(&self, sc_addr: &str) -> Result<Vec<DataBlob>> {
|
pub fn get_sc_sc_state(&self, sc_addr: &str) -> Result<Vec<DataBlob>> {
|
||||||
Ok(self.dbio.get_sc_sc_state(sc_addr)?)
|
Ok(self.dbio.get_sc_sc_state(sc_addr)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn put_snapshot_at_block_id(
|
||||||
|
&self,
|
||||||
|
id: u64,
|
||||||
|
accounts_ser: Vec<u8>,
|
||||||
|
comm_ser: Vec<u8>,
|
||||||
|
txs_ser: Vec<u8>,
|
||||||
|
nullifiers_ser: Vec<u8>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.dbio
|
||||||
|
.put_snapshot_block_id_db(id)
|
||||||
|
.inspect_err(|err| warn!("Failed to store snapshot block id with error {err:#?}"))?;
|
||||||
|
self.dbio
|
||||||
|
.put_snapshot_account_db(accounts_ser)
|
||||||
|
.inspect_err(|err| warn!("Failed to store snapshot accounts with error {err:#?}"))?;
|
||||||
|
self.dbio
|
||||||
|
.put_snapshot_commitement_db(comm_ser)
|
||||||
|
.inspect_err(|err| warn!("Failed to store snapshot commitments with error {err:#?}"))?;
|
||||||
|
self.dbio
|
||||||
|
.put_snapshot_transaction_db(txs_ser)
|
||||||
|
.inspect_err(|err| {
|
||||||
|
warn!("Failed to store snapshot transactions with error {err:#?}")
|
||||||
|
})?;
|
||||||
|
self.dbio
|
||||||
|
.put_snapshot_account_db(nullifiers_ser)
|
||||||
|
.inspect_err(|err| warn!("Failed to store snapshot nullifiers with error {err:#?}"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -13,10 +13,11 @@ use common::{
|
|||||||
utxo_commitment::UTXOCommitment,
|
utxo_commitment::UTXOCommitment,
|
||||||
};
|
};
|
||||||
use k256::AffinePoint;
|
use k256::AffinePoint;
|
||||||
|
use log::{info, warn};
|
||||||
use public_context::PublicSCContext;
|
use public_context::PublicSCContext;
|
||||||
use utxo::utxo_core::UTXO;
|
use utxo::utxo_core::UTXO;
|
||||||
|
|
||||||
use crate::ActionData;
|
use crate::{config::NodeConfig, ActionData};
|
||||||
|
|
||||||
pub mod accounts_store;
|
pub mod accounts_store;
|
||||||
pub mod block_store;
|
pub mod block_store;
|
||||||
@ -28,10 +29,11 @@ pub struct NodeChainStore {
|
|||||||
pub nullifier_store: HashSet<UTXONullifier>,
|
pub nullifier_store: HashSet<UTXONullifier>,
|
||||||
pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
|
pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
|
||||||
pub pub_tx_store: PublicTransactionMerkleTree,
|
pub pub_tx_store: PublicTransactionMerkleTree,
|
||||||
|
pub node_config: NodeConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeChainStore {
|
impl NodeChainStore {
|
||||||
pub fn new_with_genesis(home_dir: &Path, genesis_block: Block) -> Self {
|
pub fn new_with_genesis(config: NodeConfig, genesis_block: Block) -> Self {
|
||||||
let acc_map = HashMap::new();
|
let acc_map = HashMap::new();
|
||||||
let nullifier_store = HashSet::new();
|
let nullifier_store = HashSet::new();
|
||||||
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||||
@ -40,7 +42,7 @@ impl NodeChainStore {
|
|||||||
//Sequencer should panic if unable to open db,
|
//Sequencer should panic if unable to open db,
|
||||||
//as fixing this issue may require actions non-native to program scope
|
//as fixing this issue may require actions non-native to program scope
|
||||||
let block_store =
|
let block_store =
|
||||||
NodeBlockStore::open_db_with_genesis(&home_dir.join("rocksdb"), Some(genesis_block))
|
NodeBlockStore::open_db_with_genesis(&config.home.join("rocksdb"), Some(genesis_block))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -49,10 +51,13 @@ impl NodeChainStore {
|
|||||||
nullifier_store,
|
nullifier_store,
|
||||||
utxo_commitments_store,
|
utxo_commitments_store,
|
||||||
pub_tx_store,
|
pub_tx_store,
|
||||||
|
node_config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dissect_insert_block(&mut self, block: Block) -> Result<()> {
|
pub fn dissect_insert_block(&mut self, block: Block) -> Result<()> {
|
||||||
|
let block_id = block.block_id;
|
||||||
|
|
||||||
for tx in &block.transactions {
|
for tx in &block.transactions {
|
||||||
if !tx.execution_input.is_empty() {
|
if !tx.execution_input.is_empty() {
|
||||||
let public_action = serde_json::from_slice::<ActionData>(&tx.execution_input);
|
let public_action = serde_json::from_slice::<ActionData>(&tx.execution_input);
|
||||||
@ -136,6 +141,55 @@ impl NodeChainStore {
|
|||||||
|
|
||||||
self.block_store.put_block_at_id(block)?;
|
self.block_store.put_block_at_id(block)?;
|
||||||
|
|
||||||
|
//Snapshot
|
||||||
|
if block_id % self.node_config.shapshot_frequency_in_blocks == 0 {
|
||||||
|
//Serializing all important data structures
|
||||||
|
|
||||||
|
//If we fail snapshot, it is not the reason to stop running
|
||||||
|
//Logging on warn level in this cases
|
||||||
|
|
||||||
|
let accounts_ser = serde_json::to_vec(&self.acc_map).inspect_err(|err| {
|
||||||
|
warn!("Failed to serialize accounts data {err:#?}");
|
||||||
|
});
|
||||||
|
|
||||||
|
let comm_tree_serialized = serde_json::to_vec(&self.utxo_commitments_store)
|
||||||
|
.inspect_err(|err| {
|
||||||
|
warn!("Failed to serialize commitments {err:#?}");
|
||||||
|
});
|
||||||
|
|
||||||
|
let tx_tree_serialized = serde_json::to_vec(&self.pub_tx_store).inspect_err(|err| {
|
||||||
|
warn!("Failed to serialize transactions {err:#?}");
|
||||||
|
});
|
||||||
|
|
||||||
|
let nullifiers_serialized =
|
||||||
|
serde_json::to_vec(&self.nullifier_store).inspect_err(|err| {
|
||||||
|
warn!("Failed to serialize nullifiers {err:#?}");
|
||||||
|
});
|
||||||
|
|
||||||
|
match (
|
||||||
|
accounts_ser,
|
||||||
|
comm_tree_serialized,
|
||||||
|
tx_tree_serialized,
|
||||||
|
nullifiers_serialized,
|
||||||
|
) {
|
||||||
|
(Ok(accounts_ser), Ok(comm_ser), Ok(txs_ser), Ok(nullifiers_ser)) => {
|
||||||
|
let snapshot_trace = self.block_store.put_snapshot_at_block_id(
|
||||||
|
block_id,
|
||||||
|
accounts_ser,
|
||||||
|
comm_ser,
|
||||||
|
txs_ser,
|
||||||
|
nullifiers_ser,
|
||||||
|
);
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Snapshot executed at {:?} with results {snapshot_trace:#?}",
|
||||||
|
block_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => warn!("Failed to serialize node data for snapshot"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -49,4 +49,6 @@ pub struct NodeConfig {
|
|||||||
pub port: u16,
|
pub port: u16,
|
||||||
///Gas config
|
///Gas config
|
||||||
pub gas_config: GasConfig,
|
pub gas_config: GasConfig,
|
||||||
|
///Frequency of snapshots
|
||||||
|
pub shapshot_frequency_in_blocks: u64,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,11 +94,11 @@ impl NodeCore {
|
|||||||
let client = Arc::new(SequencerClient::new(config.clone())?);
|
let client = Arc::new(SequencerClient::new(config.clone())?);
|
||||||
|
|
||||||
let genesis_id = client.get_genesis_id().await?;
|
let genesis_id = client.get_genesis_id().await?;
|
||||||
info!("Gesesis id is {genesis_id:?}");
|
info!("Genesis id is {genesis_id:?}");
|
||||||
|
|
||||||
let genesis_block = client.get_block(genesis_id.genesis_id).await?.block;
|
let genesis_block = client.get_block(genesis_id.genesis_id).await?.block;
|
||||||
|
|
||||||
let mut storage = NodeChainStore::new_with_genesis(&config.home, genesis_block);
|
let mut storage = NodeChainStore::new_with_genesis(config.clone(), genesis_block);
|
||||||
|
|
||||||
pre_start::setup_empty_sc_states(&storage).await?;
|
pre_start::setup_empty_sc_states(&storage).await?;
|
||||||
|
|
||||||
|
|||||||
@ -12,5 +12,6 @@
|
|||||||
"gas_cost_deploy": 1000,
|
"gas_cost_deploy": 1000,
|
||||||
"gas_limit_deploy": 30000000,
|
"gas_limit_deploy": 30000000,
|
||||||
"gas_limit_runtime": 30000000
|
"gas_limit_runtime": 30000000
|
||||||
}
|
},
|
||||||
|
"shapshot_frequency_in_blocks": 10
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user