mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-02 13:23:10 +00:00
Merge pull request #82 from vacp2p/start_from_block
Start from snapshot block
This commit is contained in:
commit
e826fc4a31
48
Cargo.lock
generated
48
Cargo.lock
generated
@ -767,7 +767,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "bonsai-sdk"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"duplicate",
|
||||
"maybe-async",
|
||||
@ -3716,7 +3716,7 @@ checksum = "3df6368f71f205ff9c33c076d170dd56ebf68e8161c733c0caa07a7a5509ed53"
|
||||
[[package]]
|
||||
name = "risc0-binfmt"
|
||||
version = "2.0.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"borsh",
|
||||
@ -3733,8 +3733,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "risc0-build"
|
||||
version = "2.1.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
version = "2.1.2"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_metadata",
|
||||
@ -3757,7 +3757,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-build-kernel"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"directories",
|
||||
@ -3770,8 +3770,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "risc0-circuit-keccak"
|
||||
version = "2.0.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
version = "2.0.2"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytemuck",
|
||||
@ -3792,7 +3792,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-circuit-keccak-sys"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cust",
|
||||
@ -3806,8 +3806,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "risc0-circuit-recursion"
|
||||
version = "2.0.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
version = "2.0.2"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytemuck",
|
||||
@ -3832,7 +3832,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-circuit-recursion-sys"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"risc0-build-kernel",
|
||||
@ -3843,8 +3843,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "risc0-circuit-rv32im"
|
||||
version = "2.0.3"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
version = "2.0.4"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"auto_ops",
|
||||
@ -3874,8 +3874,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "risc0-circuit-rv32im-sys"
|
||||
version = "2.0.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
version = "2.0.2"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cust",
|
||||
@ -3890,7 +3890,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-core"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"bytemuck_derive",
|
||||
@ -3902,7 +3902,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-groth16"
|
||||
version = "2.0.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ark-bn254",
|
||||
@ -3926,7 +3926,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-sys"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cust",
|
||||
@ -3937,7 +3937,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-zkos-v1compat"
|
||||
version = "2.0.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"include_bytes_aligned",
|
||||
"no_std_strings",
|
||||
@ -3946,7 +3946,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-zkp"
|
||||
version = "2.0.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"blake2",
|
||||
@ -3976,8 +3976,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "risc0-zkvm"
|
||||
version = "2.0.2"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
version = "2.1.0"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"addr2line 0.22.0",
|
||||
"anyhow",
|
||||
@ -4023,7 +4023,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "risc0-zkvm-platform"
|
||||
version = "2.0.2"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
@ -4185,7 +4185,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
[[package]]
|
||||
name = "rzup"
|
||||
version = "0.4.1"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.0#c0db0713671c8ec467b3efc26b22a0b0591897ff"
|
||||
source = "git+https://github.com/risc0/risc0.git?branch=release-2.1#f34d6913945ab9f214219f3cbee1703f63936cc4"
|
||||
dependencies = [
|
||||
"semver",
|
||||
"serde",
|
||||
|
||||
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||
use common::{merkle_tree_public::TreeHashType, transaction::Tag};
|
||||
use k256::AffinePoint;
|
||||
use log::info;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utxo::utxo_core::UTXO;
|
||||
|
||||
use crate::key_management::{
|
||||
@ -16,7 +16,7 @@ use crate::key_management::{
|
||||
pub type PublicKey = AffinePoint;
|
||||
pub type AccountAddress = TreeHashType;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Clone)]
|
||||
pub struct Account {
|
||||
pub key_holder: AddressKeyHolder,
|
||||
pub address: AccountAddress,
|
||||
@ -24,6 +24,64 @@ pub struct Account {
|
||||
pub utxos: HashMap<TreeHashType, UTXO>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct AccountForSerialization {
|
||||
pub key_holder: AddressKeyHolder,
|
||||
pub address: AccountAddress,
|
||||
pub balance: u64,
|
||||
pub utxos: HashMap<String, UTXO>,
|
||||
}
|
||||
|
||||
impl From<Account> for AccountForSerialization {
|
||||
fn from(value: Account) -> Self {
|
||||
AccountForSerialization {
|
||||
key_holder: value.key_holder,
|
||||
address: value.address,
|
||||
balance: value.balance,
|
||||
utxos: value
|
||||
.utxos
|
||||
.into_iter()
|
||||
.map(|(key, val)| (hex::encode(key), val))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AccountForSerialization> for Account {
|
||||
fn from(value: AccountForSerialization) -> Self {
|
||||
Account {
|
||||
key_holder: value.key_holder,
|
||||
address: value.address,
|
||||
balance: value.balance,
|
||||
utxos: value
|
||||
.utxos
|
||||
.into_iter()
|
||||
.map(|(key, val)| (hex::decode(key).unwrap().try_into().unwrap(), val))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Account {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let account_for_serialization: AccountForSerialization = From::from(self.clone());
|
||||
account_for_serialization.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Account {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let account_for_serialization = <AccountForSerialization>::deserialize(deserializer)?;
|
||||
Ok(account_for_serialization.into())
|
||||
}
|
||||
}
|
||||
|
||||
///A strucure, which represents all the visible(public) information
|
||||
///
|
||||
/// known to each node about account `address`
|
||||
|
||||
@ -6,7 +6,7 @@ use ephemeral_key_holder::EphemeralKeyHolder;
|
||||
use k256::AffinePoint;
|
||||
use log::info;
|
||||
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::account_core::PublicKey;
|
||||
|
||||
@ -14,7 +14,7 @@ pub mod constants_types;
|
||||
pub mod ephemeral_key_holder;
|
||||
pub mod secret_holders;
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
///Entrypoint to key management
|
||||
pub struct AddressKeyHolder {
|
||||
//Will be useful in future
|
||||
|
||||
@ -2,7 +2,7 @@ use common::merkle_tree_public::TreeHashType;
|
||||
use elliptic_curve::PrimeField;
|
||||
use k256::{AffinePoint, FieldBytes, Scalar};
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{digest::FixedOutput, Digest};
|
||||
|
||||
use super::constants_types::{NULLIFIER_SECRET_CONST, VIEWING_SECRET_CONST};
|
||||
@ -14,13 +14,13 @@ pub struct SeedHolder {
|
||||
seed: Scalar,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
///Secret spending key holder. Produces `UTXOSecretKeyHolder` objects.
|
||||
pub struct TopSecretKeyHolder {
|
||||
pub secret_spending_key: Scalar,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
///Nullifier secret key and viewing secret key holder. Produces public keys. Can produce address. Can produce shared secret for recepient.
|
||||
pub struct UTXOSecretKeyHolder {
|
||||
pub nullifier_secret_key: Scalar,
|
||||
|
||||
@ -9,7 +9,7 @@ thiserror.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde.workspace = true
|
||||
reqwest.workspace = true
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0" }
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.1" }
|
||||
|
||||
rs_merkle.workspace = true
|
||||
sha2.workspace = true
|
||||
|
||||
@ -18,7 +18,7 @@ reqwest.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
tempfile.workspace = true
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0" }
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.1" }
|
||||
hex.workspace = true
|
||||
actix-rt.workspace = true
|
||||
|
||||
|
||||
@ -1,11 +1,19 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::Path;
|
||||
|
||||
use accounts::account_core::Account;
|
||||
use anyhow::{anyhow, Result};
|
||||
use common::block::Block;
|
||||
use common::merkle_tree_public::merkle_tree::HashStorageMerkleTree;
|
||||
use common::nullifier::UTXONullifier;
|
||||
use common::transaction::Transaction;
|
||||
use common::utxo_commitment::UTXOCommitment;
|
||||
use log::error;
|
||||
use storage::sc_db_utils::{DataBlob, DataBlobChangeVariant};
|
||||
use storage::RocksDBIO;
|
||||
|
||||
use crate::chain_storage::AccMap;
|
||||
|
||||
pub struct NodeBlockStore {
|
||||
dbio: RocksDBIO,
|
||||
}
|
||||
@ -22,9 +30,9 @@ impl NodeBlockStore {
|
||||
}
|
||||
|
||||
///Reopening existing database
|
||||
pub fn open_db_restart(location: &Path) -> Result<Self> {
|
||||
pub fn open_db_restart(location: &Path, genesis_block: Block) -> Result<Self> {
|
||||
NodeBlockStore::db_destroy(location)?;
|
||||
NodeBlockStore::open_db_with_genesis(location, None)
|
||||
NodeBlockStore::open_db_with_genesis(location, Some(genesis_block))
|
||||
}
|
||||
|
||||
///Reloading existing database
|
||||
@ -58,6 +66,33 @@ impl NodeBlockStore {
|
||||
Ok(self.dbio.get_sc_sc_state(sc_addr)?)
|
||||
}
|
||||
|
||||
pub fn get_snapshot_block_id(&self) -> Result<u64> {
|
||||
Ok(self.dbio.get_snapshot_block_id()?)
|
||||
}
|
||||
|
||||
pub fn get_snapshot_account(&self) -> Result<HashMap<[u8; 32], Account>> {
|
||||
let temp: AccMap = serde_json::from_slice(&self.dbio.get_snapshot_account()?)?;
|
||||
Ok(temp.into())
|
||||
}
|
||||
|
||||
pub fn get_snapshot_commitment(&self) -> Result<HashStorageMerkleTree<UTXOCommitment>> {
|
||||
Ok(serde_json::from_slice(
|
||||
&self.dbio.get_snapshot_commitment()?,
|
||||
)?)
|
||||
}
|
||||
|
||||
pub fn get_snapshot_nullifier(&self) -> Result<HashSet<UTXONullifier>> {
|
||||
Ok(serde_json::from_slice(
|
||||
&self.dbio.get_snapshot_nullifier()?,
|
||||
)?)
|
||||
}
|
||||
|
||||
pub fn get_snapshot_transaction(&self) -> Result<HashStorageMerkleTree<Transaction>> {
|
||||
Ok(serde_json::from_slice(
|
||||
&self.dbio.get_snapshot_transaction()?,
|
||||
)?)
|
||||
}
|
||||
|
||||
pub fn put_snapshot_at_block_id(
|
||||
&self,
|
||||
id: u64,
|
||||
@ -140,13 +175,26 @@ mod tests {
|
||||
let path = temp_dir.path();
|
||||
|
||||
let genesis_block = create_genesis_block();
|
||||
let _ = NodeBlockStore::open_db_with_genesis(path, Some(genesis_block)).unwrap();
|
||||
{
|
||||
let node_store_old =
|
||||
NodeBlockStore::open_db_with_genesis(path, Some(genesis_block.clone())).unwrap();
|
||||
|
||||
let block = create_sample_block(1, 0);
|
||||
node_store_old.put_block_at_id(block.clone()).unwrap();
|
||||
}
|
||||
|
||||
// Check that the first block is still in the old database
|
||||
{
|
||||
let node_store_old = NodeBlockStore::open_db_reload(path).unwrap();
|
||||
let result = node_store_old.get_block_at_id(1);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
// Restart the database
|
||||
let node_store = NodeBlockStore::open_db_restart(path).unwrap();
|
||||
let node_store = NodeBlockStore::open_db_restart(path, genesis_block).unwrap();
|
||||
|
||||
// The block should no longer be available since no genesis block is set on restart
|
||||
let result = node_store.get_block_at_id(0);
|
||||
// The block should no longer be available since no first block is set on restart
|
||||
let result = node_store.get_block_at_id(1);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
@ -182,17 +230,6 @@ mod tests {
|
||||
assert_eq!(retrieved_block.hash, block.hash);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_block_not_found() {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let path = temp_dir.path();
|
||||
|
||||
let node_store = NodeBlockStore::open_db_with_genesis(path, None).unwrap();
|
||||
|
||||
let result = node_store.get_block_at_id(42);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_put_snapshot_at_block_id() {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
|
||||
@ -12,6 +12,7 @@ use common::{
|
||||
use k256::AffinePoint;
|
||||
use log::{info, warn};
|
||||
use public_context::PublicSCContext;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utxo::utxo_core::UTXO;
|
||||
|
||||
use crate::{config::NodeConfig, ActionData};
|
||||
@ -20,6 +21,32 @@ pub mod accounts_store;
|
||||
pub mod block_store;
|
||||
pub mod public_context;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct AccMap {
|
||||
pub acc_map: HashMap<String, Account>,
|
||||
}
|
||||
|
||||
impl From<HashMap<[u8; 32], Account>> for AccMap {
|
||||
fn from(value: HashMap<[u8; 32], Account>) -> Self {
|
||||
AccMap {
|
||||
acc_map: value
|
||||
.into_iter()
|
||||
.map(|(key, val)| (hex::encode(key), val))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AccMap> for HashMap<[u8; 32], Account> {
|
||||
fn from(value: AccMap) -> Self {
|
||||
value
|
||||
.acc_map
|
||||
.into_iter()
|
||||
.map(|(key, val)| (hex::decode(key).unwrap().try_into().unwrap(), val))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NodeChainStore {
|
||||
pub acc_map: HashMap<AccountAddress, Account>,
|
||||
pub block_store: NodeBlockStore,
|
||||
@ -30,11 +57,12 @@ pub struct NodeChainStore {
|
||||
}
|
||||
|
||||
impl NodeChainStore {
|
||||
pub fn new_with_genesis(config: NodeConfig, genesis_block: Block) -> Self {
|
||||
let acc_map = HashMap::new();
|
||||
let nullifier_store = HashSet::new();
|
||||
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
pub fn new(config: NodeConfig, genesis_block: Block) -> Result<(Self, u64)> {
|
||||
let mut acc_map = HashMap::new();
|
||||
let mut nullifier_store = HashSet::new();
|
||||
let mut utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let mut pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
let mut block_id = genesis_block.block_id;
|
||||
|
||||
//Sequencer should panic if unable to open db,
|
||||
//as fixing this issue may require actions non-native to program scope
|
||||
@ -42,14 +70,57 @@ impl NodeChainStore {
|
||||
NodeBlockStore::open_db_with_genesis(&config.home.join("rocksdb"), Some(genesis_block))
|
||||
.unwrap();
|
||||
|
||||
Self {
|
||||
acc_map,
|
||||
block_store,
|
||||
nullifier_store,
|
||||
utxo_commitments_store,
|
||||
pub_tx_store,
|
||||
node_config: config,
|
||||
if let Ok(temp_block_id) = block_store.get_snapshot_block_id() {
|
||||
utxo_commitments_store = block_store.get_snapshot_commitment()?;
|
||||
nullifier_store = block_store.get_snapshot_nullifier()?;
|
||||
acc_map = block_store.get_snapshot_account()?;
|
||||
pub_tx_store = block_store.get_snapshot_transaction()?;
|
||||
block_id = temp_block_id;
|
||||
}
|
||||
|
||||
Ok((
|
||||
Self {
|
||||
acc_map: From::from(acc_map),
|
||||
block_store,
|
||||
nullifier_store,
|
||||
utxo_commitments_store,
|
||||
pub_tx_store,
|
||||
node_config: config,
|
||||
},
|
||||
block_id,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn new_after_restart(config: NodeConfig, genesis_block: Block) -> Result<(Self, u64)> {
|
||||
let mut acc_map = HashMap::new();
|
||||
let mut nullifier_store = HashSet::new();
|
||||
let mut utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let mut pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
let mut block_id = genesis_block.block_id;
|
||||
|
||||
//Sequencer should panic if unable to open db,
|
||||
//as fixing this issue may require actions non-native to program scope
|
||||
let block_store = NodeBlockStore::open_db_reload(&config.home.join("rocksdb")).unwrap();
|
||||
|
||||
if let Ok(temp_block_id) = block_store.get_snapshot_block_id() {
|
||||
utxo_commitments_store = block_store.get_snapshot_commitment()?;
|
||||
nullifier_store = block_store.get_snapshot_nullifier()?;
|
||||
acc_map = block_store.get_snapshot_account()?;
|
||||
pub_tx_store = block_store.get_snapshot_transaction()?;
|
||||
block_id = temp_block_id;
|
||||
}
|
||||
|
||||
Ok((
|
||||
Self {
|
||||
acc_map,
|
||||
block_store,
|
||||
nullifier_store,
|
||||
utxo_commitments_store,
|
||||
pub_tx_store,
|
||||
node_config: config,
|
||||
},
|
||||
block_id,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn dissect_insert_block(&mut self, block: Block) -> Result<()> {
|
||||
@ -113,7 +184,7 @@ impl NodeChainStore {
|
||||
let nonce =
|
||||
accounts::key_management::constants_types::Nonce::clone_from_slice(slice);
|
||||
for (acc_id, acc) in self.acc_map.iter_mut() {
|
||||
if acc_id[0] == tag {
|
||||
if hex::decode(acc_id).unwrap()[0] == tag {
|
||||
let decoded_data_curr_acc = acc.decrypt_data(
|
||||
ephemeral_public_key_sender,
|
||||
ciphertext.clone(),
|
||||
@ -144,8 +215,9 @@ impl NodeChainStore {
|
||||
|
||||
//If we fail serialization, it is not the reason to stop running
|
||||
//Logging on warn level in this cases
|
||||
let acc_map: AccMap = self.acc_map.clone().into();
|
||||
|
||||
if let Ok(accounts_ser) = serde_json::to_vec(&self.acc_map).inspect_err(|err| {
|
||||
if let Ok(accounts_ser) = serde_json::to_vec(&acc_map).inspect_err(|err| {
|
||||
warn!("Failed to serialize accounts data {err:#?}");
|
||||
}) {
|
||||
if let Ok(comm_ser) =
|
||||
@ -198,3 +270,173 @@ impl NodeChainStore {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::GasConfig;
|
||||
use accounts::account_core::Account;
|
||||
use common::block::{Block, Data};
|
||||
use common::merkle_tree_public::TreeHashType;
|
||||
use common::transaction::{Transaction, TxKind};
|
||||
use secp256k1_zkp::Tweak;
|
||||
use std::path::PathBuf;
|
||||
use tempfile::tempdir;
|
||||
|
||||
fn create_genesis_block() -> Block {
|
||||
Block {
|
||||
block_id: 0,
|
||||
prev_block_id: 0,
|
||||
prev_block_hash: [0; 32],
|
||||
hash: [1; 32],
|
||||
transactions: vec![],
|
||||
data: Data::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_dummy_transaction(
|
||||
hash: TreeHashType,
|
||||
// execution_input: Vec<u8>,
|
||||
nullifier_created_hashes: Vec<[u8; 32]>,
|
||||
utxo_commitments_spent_hashes: Vec<[u8; 32]>,
|
||||
utxo_commitments_created_hashes: Vec<[u8; 32]>,
|
||||
) -> Transaction {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
Transaction {
|
||||
hash,
|
||||
tx_kind: TxKind::Private,
|
||||
execution_input: vec![],
|
||||
execution_output: vec![],
|
||||
utxo_commitments_spent_hashes,
|
||||
utxo_commitments_created_hashes,
|
||||
nullifier_created_hashes,
|
||||
execution_proof_private: "dummy_proof".to_string(),
|
||||
encoded_data: vec![],
|
||||
ephemeral_pub_key: vec![10, 11, 12],
|
||||
commitment: vec![],
|
||||
tweak: Tweak::new(&mut rng),
|
||||
secret_r: [0; 32],
|
||||
sc_addr: "sc_addr".to_string(),
|
||||
state_changes: (serde_json::Value::Null, 0),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block {
|
||||
Block {
|
||||
block_id: block_id,
|
||||
prev_block_id: prev_block_id,
|
||||
prev_block_hash: [0; 32],
|
||||
hash: [1; 32],
|
||||
transactions: vec![],
|
||||
data: Data::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_sample_node_config(home: PathBuf) -> NodeConfig {
|
||||
NodeConfig {
|
||||
home,
|
||||
override_rust_log: None,
|
||||
sequencer_addr: "http://127.0.0.1".to_string(),
|
||||
seq_poll_timeout_secs: 1,
|
||||
port: 8000,
|
||||
gas_config: create_sample_gas_config(),
|
||||
shapshot_frequency_in_blocks: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_sample_gas_config() -> GasConfig {
|
||||
GasConfig {
|
||||
gas_fee_per_byte_deploy: 0,
|
||||
gas_fee_per_input_buffer_runtime: 0,
|
||||
gas_fee_per_byte_runtime: 0,
|
||||
gas_cost_runtime: 0,
|
||||
gas_cost_deploy: 0,
|
||||
gas_limit_deploy: 0,
|
||||
gas_limit_runtime: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_dummy_utxo(address: TreeHashType, amount: u128) -> UTXO {
|
||||
UTXO::new(address, vec![], amount, false)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_initializes_correctly() {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let path = temp_dir.path();
|
||||
|
||||
let config = create_sample_node_config(path.to_path_buf());
|
||||
|
||||
let genesis_block = create_genesis_block();
|
||||
|
||||
let (store, block_id) = NodeChainStore::new(config.clone(), genesis_block.clone()).unwrap();
|
||||
|
||||
assert_eq!(block_id, 0);
|
||||
assert!(store.acc_map.is_empty());
|
||||
assert!(store.nullifier_store.is_empty());
|
||||
assert_eq!(
|
||||
store.utxo_commitments_store.get_root().unwrap_or([0; 32]),
|
||||
[0; 32]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_recovers_from_snapshot() {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let path = temp_dir.path().to_path_buf();
|
||||
|
||||
let config = create_sample_node_config(path);
|
||||
|
||||
let nullifier_secret_const =
|
||||
"261d61d294ac4bdc24f91b6f490efa263757a4a95f65871cd4f16b2ea23c3b5d";
|
||||
std::env::set_var("NULLIFIER_SECRET_CONST", nullifier_secret_const);
|
||||
|
||||
let viewing_secret_const =
|
||||
"6117af750b30d7a296672ec3b3b25d3489beca3cfe5770fa39f275cec395d5ce";
|
||||
std::env::set_var("VIEWING_SECRET_CONST", viewing_secret_const);
|
||||
|
||||
let genesis_block = create_genesis_block();
|
||||
|
||||
// Initialize once to create DB and store fake snapshot
|
||||
{
|
||||
let (mut store, _) =
|
||||
NodeChainStore::new(config.clone(), genesis_block.clone()).unwrap();
|
||||
|
||||
// Insert state
|
||||
let mut account = Account::new();
|
||||
account
|
||||
.add_new_utxo_outputs(vec![generate_dummy_utxo(account.address, 100)])
|
||||
.unwrap();
|
||||
store.acc_map.insert(account.address, account);
|
||||
store.nullifier_store.insert(UTXONullifier {
|
||||
utxo_hash: [2u8; 32],
|
||||
});
|
||||
store
|
||||
.utxo_commitments_store
|
||||
.add_tx_multiple(vec![UTXOCommitment { hash: [3u8; 32] }]);
|
||||
store.pub_tx_store.add_tx(create_dummy_transaction(
|
||||
[12; 32],
|
||||
vec![[9; 32]],
|
||||
vec![[7; 32]],
|
||||
vec![[8; 32]],
|
||||
));
|
||||
|
||||
// Put block snapshot to trigger snapshot recovery on next load
|
||||
let dummy_block = create_sample_block(1, 0);
|
||||
|
||||
store.dissect_insert_block(dummy_block).unwrap();
|
||||
}
|
||||
|
||||
// Now reload and verify snapshot is used
|
||||
let (recovered_store, block_id) =
|
||||
NodeChainStore::new_after_restart(config.clone(), genesis_block).unwrap();
|
||||
|
||||
assert_eq!(block_id, 1);
|
||||
assert_eq!(recovered_store.acc_map.len(), 1);
|
||||
assert_eq!(
|
||||
recovered_store.utxo_commitments_store.get_root().is_some(),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,12 +98,10 @@ impl NodeCore {
|
||||
|
||||
let genesis_block = client.get_block(genesis_id.genesis_id).await?.block;
|
||||
|
||||
let mut storage = NodeChainStore::new_with_genesis(config.clone(), genesis_block);
|
||||
let (mut storage, mut chain_height) = NodeChainStore::new(config.clone(), genesis_block)?;
|
||||
|
||||
pre_start::setup_empty_sc_states(&storage).await?;
|
||||
|
||||
let mut chain_height = genesis_id.genesis_id;
|
||||
|
||||
//Chain update loop
|
||||
loop {
|
||||
let next_block = chain_height + 1;
|
||||
|
||||
@ -19,7 +19,7 @@ light-poseidon.workspace = true
|
||||
ark-bn254.workspace = true
|
||||
ark-ff.workspace = true
|
||||
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0" }
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.1" }
|
||||
|
||||
[dependencies.accounts]
|
||||
path = "../accounts"
|
||||
|
||||
@ -2,7 +2,6 @@ use std::{path::Path, sync::Arc};
|
||||
|
||||
use common::block::Block;
|
||||
use error::DbError;
|
||||
use log::warn;
|
||||
use rocksdb::{
|
||||
BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options,
|
||||
};
|
||||
@ -103,9 +102,8 @@ impl RocksDBIO {
|
||||
|
||||
Ok(dbio)
|
||||
} else {
|
||||
warn!("Starting db in unset mode, will have to set starting block manually");
|
||||
|
||||
Ok(dbio)
|
||||
// Here we are trying to start a DB without a block, one should not do it.
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,19 +122,19 @@ impl RocksDBIO {
|
||||
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))
|
||||
}
|
||||
|
||||
pub fn meta_column(&self) -> Arc<BoundColumnFamily> {
|
||||
pub fn meta_column(&self) -> Arc<BoundColumnFamily<'_>> {
|
||||
self.db.cf_handle(CF_META_NAME).unwrap()
|
||||
}
|
||||
|
||||
pub fn block_column(&self) -> Arc<BoundColumnFamily> {
|
||||
pub fn block_column(&self) -> Arc<BoundColumnFamily<'_>> {
|
||||
self.db.cf_handle(CF_BLOCK_NAME).unwrap()
|
||||
}
|
||||
|
||||
pub fn sc_column(&self) -> Arc<BoundColumnFamily> {
|
||||
pub fn sc_column(&self) -> Arc<BoundColumnFamily<'_>> {
|
||||
self.db.cf_handle(CF_SC_NAME).unwrap()
|
||||
}
|
||||
|
||||
pub fn snapshot_column(&self) -> Arc<BoundColumnFamily> {
|
||||
pub fn snapshot_column(&self) -> Arc<BoundColumnFamily<'_>> {
|
||||
self.db.cf_handle(CF_SNAPSHOT_NAME).unwrap()
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ serde.workspace = true
|
||||
thiserror.workspace = true
|
||||
rand.workspace = true
|
||||
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0" }
|
||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.1" }
|
||||
test-methods = { path = "test_methods" }
|
||||
|
||||
[dependencies.accounts]
|
||||
|
||||
@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[build-dependencies]
|
||||
risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0" }
|
||||
risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.1" }
|
||||
|
||||
[package.metadata.risc0]
|
||||
methods = ["guest"]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user