Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: grovedbg v1.0.0-rc.6 #333

Merged
merged 6 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions grovedb/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ fn main() {
use sha2::{digest::FixedOutput, Digest, Sha256};

const GROVEDBG_SHA256: [u8; 32] =
hex!("c6636f10b43c703128b621a7c4b94139a1a7d0a603e26fca1771734a7994bb7c");
const GROVEDBG_VERSION: &str = "v1.0.0-rc.5";
hex!("ea7d9258973aa765eaf5064451fc83efa22e0ce6eaf2938507e2703571364e35");
const GROVEDBG_VERSION: &str = "v1.0.0-rc.6";

let out_dir = PathBuf::from(&env::var_os("OUT_DIR").unwrap());
let grovedbg_zip_path = out_dir.join("grovedbg.zip");
Expand Down
133 changes: 103 additions & 30 deletions grovedb/src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ use tower_http::services::ServeDir;

use crate::{
operations::proof::{GroveDBProof, LayerProof, ProveOptions},
query_result_type::{QueryResultElement, QueryResultElements, QueryResultType},
reference_path::ReferencePathType,
GroveDb,
};

const GROVEDBG_ZIP: [u8; include_bytes!(concat!(env!("OUT_DIR"), "/grovedbg.zip")).len()] =
*include_bytes!(concat!(env!("OUT_DIR"), "/grovedbg.zip"));
const GROVEDBG_ZIP: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/grovedbg.zip"));

pub(super) fn start_visualizer<A>(grovedb: Weak<GroveDb>, addr: A)
where
Expand All @@ -40,15 +40,16 @@ where
let grovedbg_zip = grovedbg_tmp.path().join("grovedbg.zip");
let grovedbg_www = grovedbg_tmp.path().join("grovedbg_www");

fs::write(&grovedbg_zip, &GROVEDBG_ZIP).expect("cannot crate grovedbg.zip");
fs::write(&grovedbg_zip, GROVEDBG_ZIP).expect("cannot crate grovedbg.zip");
zip_extensions::read::zip_extract(&grovedbg_zip, &grovedbg_www)
.expect("cannot extract grovedbg contents");

let (shutdown_send, mut shutdown_receive) = mpsc::channel::<()>(1);
let app = Router::new()
.route("/fetch_node", post(fetch_node))
.route("/fetch_root_node", post(fetch_root_node))
.route("/execute_path_query", post(execute_path_query))
.route("/prove_path_query", post(prove_path_query))
.route("/fetch_with_path_query", post(fetch_with_path_query))
.fallback_service(ServeDir::new(grovedbg_www))
.with_state((shutdown_send, grovedb));

Expand Down Expand Up @@ -136,7 +137,7 @@ async fn fetch_root_node(
}
}

async fn execute_path_query(
async fn prove_path_query(
State((shutdown, grovedb)): State<(Sender<()>, Weak<GroveDb>)>,
Json(json_path_query): Json<PathQuery>,
) -> Result<Json<grovedbg_types::Proof>, AppError> {
Expand All @@ -153,6 +154,66 @@ async fn execute_path_query(
Ok(Json(proof_to_grovedbg(grovedb_proof)?))
}

async fn fetch_with_path_query(
State((shutdown, grovedb)): State<(Sender<()>, Weak<GroveDb>)>,
Json(json_path_query): Json<PathQuery>,
) -> Result<Json<Vec<grovedbg_types::NodeUpdate>>, AppError> {
let Some(db) = grovedb.upgrade() else {
shutdown.send(()).await.ok();
return Err(AppError::Closed);
};

let path_query = path_query_to_grovedb(json_path_query);

let grovedb_query_result = db
.query_raw(
&path_query,
false,
true,
false,
QueryResultType::QueryPathKeyElementTrioResultType,
None,
GroveVersion::latest(),
)
.unwrap()?
.0;
Ok(Json(query_result_to_grovedbg(&db, grovedb_query_result)?))
}

fn query_result_to_grovedbg(
db: &GroveDb,
query_result: QueryResultElements,
) -> Result<Vec<NodeUpdate>, crate::Error> {
let mut result = Vec::new();

let mut last_merk: Option<(Vec<Vec<u8>>, grovedb_merk::Merk<_>)> = None;

for qr in query_result.elements.into_iter() {
if let QueryResultElement::PathKeyElementTrioResultItem((path, key, _)) = qr {
let merk: &grovedb_merk::Merk<_> = match &mut last_merk {
Some((last_merk_path, last_merk)) if last_merk_path == &path => last_merk,
_ => {
last_merk = Some((
path.clone(),
db.open_non_transactional_merk_at_path(
path.as_slice().into(),
None,
GroveVersion::latest(),
)
.unwrap()?,
));
&last_merk.as_ref().unwrap().1
}
};

if let Some(node) = merk.get_node_dbg(&key)? {
result.push(node_to_update(path, node)?);
}
}
}
Ok(result)
}

fn proof_to_grovedbg(proof: GroveDBProof) -> Result<grovedbg_types::Proof, crate::Error> {
match proof {
GroveDBProof::V0(p) => Ok(grovedbg_types::Proof {
Expand Down Expand Up @@ -334,64 +395,72 @@ fn element_to_grovedbg(element: crate::Element) -> grovedbg_types::Element {
ReferencePathType::AbsolutePathReference(path),
_,
element_flags,
) => grovedbg_types::Element::AbsolutePathReference {
) => grovedbg_types::Element::Reference(grovedbg_types::Reference::AbsolutePathReference {
path,
element_flags,
},
}),
crate::Element::Reference(
ReferencePathType::UpstreamRootHeightReference(n_keep, path_append),
_,
element_flags,
) => grovedbg_types::Element::UpstreamRootHeightReference {
n_keep: n_keep.into(),
path_append,
element_flags,
},
) => grovedbg_types::Element::Reference(
grovedbg_types::Reference::UpstreamRootHeightReference {
n_keep: n_keep.into(),
path_append,
element_flags,
},
),
crate::Element::Reference(
ReferencePathType::UpstreamRootHeightWithParentPathAdditionReference(
n_keep,
path_append,
),
_,
element_flags,
) => grovedbg_types::Element::UpstreamRootHeightWithParentPathAdditionReference {
n_keep: n_keep.into(),
path_append,
element_flags,
},
) => grovedbg_types::Element::Reference(
grovedbg_types::Reference::UpstreamRootHeightWithParentPathAdditionReference {
n_keep: n_keep.into(),
path_append,
element_flags,
},
),
crate::Element::Reference(
ReferencePathType::UpstreamFromElementHeightReference(n_remove, path_append),
_,
element_flags,
) => grovedbg_types::Element::UpstreamFromElementHeightReference {
n_remove: n_remove.into(),
path_append,
element_flags,
},
) => grovedbg_types::Element::Reference(
grovedbg_types::Reference::UpstreamFromElementHeightReference {
n_remove: n_remove.into(),
path_append,
element_flags,
},
),
crate::Element::Reference(
ReferencePathType::CousinReference(swap_parent),
_,
element_flags,
) => grovedbg_types::Element::CousinReference {
) => grovedbg_types::Element::Reference(grovedbg_types::Reference::CousinReference {
swap_parent,
element_flags,
},
}),
crate::Element::Reference(
ReferencePathType::RemovedCousinReference(swap_parent),
_,
element_flags,
) => grovedbg_types::Element::RemovedCousinReference {
swap_parent,
element_flags,
},
) => {
grovedbg_types::Element::Reference(grovedbg_types::Reference::RemovedCousinReference {
swap_parent,
element_flags,
})
}
crate::Element::Reference(
ReferencePathType::SiblingReference(sibling_key),
_,
element_flags,
) => grovedbg_types::Element::SiblingReference {
) => grovedbg_types::Element::Reference(grovedbg_types::Reference::SiblingReference {
sibling_key,
element_flags,
},
}),
crate::Element::SumItem(value, element_flags) => grovedbg_types::Element::SumItem {
value,
element_flags,
Expand All @@ -410,7 +479,9 @@ fn node_to_update(
key,
value,
left_child,
left_merk_hash,
right_child,
right_merk_hash,
value_hash,
kv_digest_hash,
feature_type,
Expand All @@ -426,7 +497,9 @@ fn node_to_update(
key,
element,
left_child,
left_merk_hash,
right_child,
right_merk_hash,
feature_type: match feature_type {
TreeFeatureType::BasicMerkNode => grovedbg_types::TreeFeatureType::BasicMerkNode,
TreeFeatureType::SummedMerkNode(x) => {
Expand Down
60 changes: 35 additions & 25 deletions grovedbg-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ pub struct NodeUpdate {
#[serde_as(as = "Option<Base64>")]
pub left_child: Option<Key>,
#[serde_as(as = "Option<Base64>")]
pub left_merk_hash: Option<CryptoHash>,
#[serde_as(as = "Option<Base64>")]
pub right_child: Option<Key>,
#[serde_as(as = "Option<Base64>")]
pub right_merk_hash: Option<CryptoHash>,
#[serde_as(as = "Vec<Base64>")]
pub path: Path,
#[serde_as(as = "Base64")]
Expand All @@ -40,31 +44,7 @@ pub struct NodeUpdate {

#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum Element {
Subtree {
#[serde_as(as = "Option<Base64>")]
root_key: Option<Key>,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
Sumtree {
#[serde_as(as = "Option<Base64>")]
root_key: Option<Key>,
sum: i64,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
Item {
#[serde_as(as = "Base64")]
value: Vec<u8>,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
SumItem {
value: i64,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
pub enum Reference {
AbsolutePathReference {
#[serde_as(as = "Vec<Base64>")]
path: Path,
Expand Down Expand Up @@ -112,6 +92,36 @@ pub enum Element {
},
}

#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum Element {
Subtree {
#[serde_as(as = "Option<Base64>")]
root_key: Option<Key>,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
Sumtree {
#[serde_as(as = "Option<Base64>")]
root_key: Option<Key>,
sum: i64,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
Item {
#[serde_as(as = "Base64")]
value: Vec<u8>,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
SumItem {
value: i64,
#[serde_as(as = "Option<Base64>")]
element_flags: Option<Vec<u8>>,
},
Reference(Reference),
}

#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PathQuery {
Expand Down
6 changes: 6 additions & 0 deletions merk/src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ impl<'a, S: StorageContext<'a>> Merk<S> {
key: tree.inner.key_as_slice().to_owned(),
value: tree.inner.value_as_slice().to_owned(),
left_child: tree.link(true).map(|link| link.key().to_owned()),
left_merk_hash: tree.link(true).map(|link| *link.hash()),
right_child: tree.link(false).map(|link| link.key().to_owned()),
right_merk_hash: tree.link(false).map(|link| *link.hash()),
value_hash: *tree.inner.kv.value_hash(),
kv_digest_hash: *tree.inner.kv.hash(),
feature_type: tree.inner.kv.feature_type(),
Expand All @@ -34,7 +36,9 @@ impl<'a, S: StorageContext<'a>> Merk<S> {
key: tree.inner.key_as_slice().to_owned(),
value: tree.inner.value_as_slice().to_owned(),
left_child: tree.link(true).map(|link| link.key().to_owned()),
left_merk_hash: tree.link(true).map(|link| *link.hash()),
right_child: tree.link(false).map(|link| link.key().to_owned()),
right_merk_hash: tree.link(false).map(|link| *link.hash()),
value_hash: *tree.inner.kv.value_hash(),
kv_digest_hash: *tree.inner.kv.hash(),
feature_type: tree.inner.kv.feature_type(),
Expand All @@ -48,7 +52,9 @@ pub struct NodeDbg {
pub key: Vec<u8>,
pub value: Vec<u8>,
pub left_child: Option<Vec<u8>>,
pub left_merk_hash: Option<[u8; 32]>,
pub right_child: Option<Vec<u8>>,
pub right_merk_hash: Option<[u8; 32]>,
pub value_hash: CryptoHash,
pub kv_digest_hash: CryptoHash,
pub feature_type: TreeFeatureType,
Expand Down
Loading