blank node skolemization should work without BASE

master
Niko PLP 1 month ago
parent 077ba6265e
commit cc89bb1808
  1. 4
      ng-net/src/app_protocol.rs
  2. 6
      ng-sdk-js/app-node/index.js
  3. 95
      ng-verifier/src/commits/transaction.rs

@ -248,7 +248,7 @@ impl NuriV0 {
} }
pub fn repo_skolem( pub fn repo_skolem(
prefix: &String, repo_id: &RepoId,
peer_id: &Vec<u8>, peer_id: &Vec<u8>,
random: u128, random: u128,
) -> Result<String, NgError> { ) -> Result<String, NgError> {
@ -256,7 +256,7 @@ impl NuriV0 {
arr.extend_from_slice(peer_id); arr.extend_from_slice(peer_id);
arr.extend_from_slice(&random.to_be_bytes()); arr.extend_from_slice(&random.to_be_bytes());
let sko: SymKey = arr.as_slice().try_into()?; let sko: SymKey = arr.as_slice().try_into()?;
Ok(format!("{prefix}:u:{sko}")) Ok(format!("{DID_PREFIX}:o:{repo_id}:u:{sko}"))
} }
pub fn overlay_id(overlay_id: &OverlayId) -> String { pub fn overlay_id(overlay_id: &OverlayId) -> String {

@ -27,7 +27,7 @@ ng.init_headless(config).then( async() => {
let user_id = "NnAJWxO-KapuWyCm7RGwO5VszZwaJARGit-i3i1mXbkA"; let user_id = "NnAJWxO-KapuWyCm7RGwO5VszZwaJARGit-i3i1mXbkA";
let base = "did:ng:o:8mqfhoSprneBjkAASinRk0OYvFpbiyhjMBVHKQIarDEA:v:dmn9xLARD-LrCz1tdmRiTKelikOCadGEvsLklUrwee4A"; let base = "did:ng:o:8mqfhoSprneBjkAASinRk0OYvFpbiyhjMBVHKQIarDEA";
let session = await ng.session_headless_start(user_id); let session = await ng.session_headless_start(user_id);
session_id = session.session_id; session_id = session.session_id;
@ -67,8 +67,8 @@ ng.init_headless(config).then( async() => {
//await ng.sparql_update(session.session_id, "INSERT DATA { <> <a:self> <a:self> . }",base); //await ng.sparql_update(session.session_id, "INSERT DATA { <> <a:self> <a:self> . }",base);
await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:TEST3> <did:ng:j> _:_ . _:_ <did:ng:m> <did:ng:n> . }", base); await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:TEST4> <did:ng:j> _:_ . _:_ <did:ng:m> <did:ng:n> . }");
await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:TEST4> <did:ng:j> [ <did:ng:m> <did:ng:n> ]. }", base); await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:TEST5> <did:ng:j> [ <did:ng:m> <did:ng:n> ]. }");
sparql_result = await ng.sparql_query(session.session_id, "SELECT ?a WHERE { ?a <did:ng:j> _:abc. _:abc <did:ng:m> <did:ng:n> }", base); sparql_result = await ng.sparql_query(session.session_id, "SELECT ?a WHERE { ?a <did:ng:j> _:abc. _:abc <did:ng:m> <did:ng:n> }", base);
console.log(sparql_result); console.log(sparql_result);

@ -328,12 +328,12 @@ impl Verifier {
&self, &self,
quad: &Quad, quad: &Quad,
branches: &mut HashMap<BranchId, (StoreRepo, RepoId, bool, TopicId, Digest, OverlayId)>, branches: &mut HashMap<BranchId, (StoreRepo, RepoId, bool, TopicId, Digest, OverlayId)>,
nuri_branches: &mut HashMap<String, (BranchId, bool)>, nuri_branches: &mut HashMap<String, (RepoId, BranchId, bool)>,
) -> Result<(BranchId, bool), VerifierError> { ) -> Result<(RepoId, BranchId, bool), VerifierError> {
match &quad.graph_name { match &quad.graph_name {
GraphName::NamedNode(named_node) => { GraphName::NamedNode(named_node) => {
let graph_name = named_node.as_string(); let graph_name = named_node.as_string();
log_debug!("graph_name {graph_name}"); //log_debug!("graph_name {graph_name}");
if let Some(branch_found) = nuri_branches.get(graph_name) { if let Some(branch_found) = nuri_branches.get(graph_name) {
return Ok(branch_found.clone()); return Ok(branch_found.clone());
} }
@ -378,10 +378,12 @@ impl Verifier {
token, token,
store.overlay_id, store.overlay_id,
)); ));
let _ = nuri_branches let _ = nuri_branches.entry(graph_name.clone()).or_insert((
.entry(graph_name.clone()) repo.id,
.or_insert((branch_id, is_publisher)); branch_id,
Ok((branch_id, is_publisher)) is_publisher,
));
Ok((repo.id, branch_id, is_publisher))
} }
_ => Err(VerifierError::InvalidNamedGraph), _ => Err(VerifierError::InvalidNamedGraph),
} }
@ -391,6 +393,7 @@ impl Verifier {
&mut self, &mut self,
inserts: Vec<Quad>, inserts: Vec<Quad>,
removes: Vec<Quad>, removes: Vec<Quad>,
peer_id: Vec<u8>,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
// options when not a publisher on the repo: // options when not a publisher on the repo:
// - skip // - skip
@ -401,11 +404,12 @@ impl Verifier {
let mut removes_map: HashMap<BranchId, HashSet<Triple>> = HashMap::with_capacity(1); let mut removes_map: HashMap<BranchId, HashSet<Triple>> = HashMap::with_capacity(1);
let mut branches: HashMap<BranchId, (StoreRepo, RepoId, bool, TopicId, Digest, OverlayId)> = let mut branches: HashMap<BranchId, (StoreRepo, RepoId, bool, TopicId, Digest, OverlayId)> =
HashMap::with_capacity(1); HashMap::with_capacity(1);
let mut nuri_branches: HashMap<String, (BranchId, bool)> = HashMap::with_capacity(1); let mut nuri_branches: HashMap<String, (RepoId, BranchId, bool)> =
HashMap::with_capacity(1);
let mut inserts_len = inserts.len(); let mut inserts_len = inserts.len();
let mut removes_len = removes.len(); let mut removes_len = removes.len();
for insert in inserts { for mut insert in inserts {
let (branch_id, is_publisher) = let (repo_id, branch_id, is_publisher) =
self.find_branch_and_repo_for_quad(&insert, &mut branches, &mut nuri_branches)?; self.find_branch_and_repo_for_quad(&insert, &mut branches, &mut nuri_branches)?;
if !is_publisher { if !is_publisher {
continue; continue;
@ -415,10 +419,32 @@ impl Verifier {
inserts_len = 1; inserts_len = 1;
set set
}); });
// changing blank node to skolemized node
//log_debug!("INSERTING BN {}", quad);
if insert.subject.is_blank_node() {
//log_debug!("INSERTING SUBJECT BN {}", insert.subject);
if let Subject::BlankNode(b) = &insert.subject {
let iri =
NuriV0::repo_skolem(&repo_id, &peer_id, b.as_ref().unique_id().unwrap())?;
insert.subject = Subject::NamedNode(NamedNode::new_unchecked(iri));
}
}
if insert.object.is_blank_node() {
//log_debug!("INSERTING OBJECT BN {}", insert.object);
if let Term::BlankNode(b) = &insert.object {
let iri =
NuriV0::repo_skolem(&repo_id, &peer_id, b.as_ref().unique_id().unwrap())?;
insert.object = Term::NamedNode(NamedNode::new_unchecked(iri));
}
}
// TODO deal with triples in subject and object (RDF-STAR)
set.insert(insert.into()); set.insert(insert.into());
} }
for remove in removes { for remove in removes {
let (branch_id, is_publisher) = let (repo_id, branch_id, is_publisher) =
self.find_branch_and_repo_for_quad(&remove, &mut branches, &mut nuri_branches)?; self.find_branch_and_repo_for_quad(&remove, &mut branches, &mut nuri_branches)?;
if !is_publisher { if !is_publisher {
continue; continue;
@ -689,46 +715,13 @@ impl Verifier {
if inserts.is_empty() && removes.is_empty() { if inserts.is_empty() && removes.is_empty() {
Ok(()) Ok(())
} else { } else {
let mut new_inserts = Vec::with_capacity(inserts.len()); self.prepare_sparql_update(
for mut quad in inserts.drain() { Vec::from_iter(inserts),
//log_debug!("INSERTING BN {}", quad); Vec::from_iter(removes),
if quad.subject.is_blank_node() { peer_id,
if base.is_none() { )
return Err("Cannot insert blank nodes without a base".to_string()); .await
} .map_err(|e| e.to_string())
//log_debug!("INSERTING SUBJECT BN {}", quad.subject);
if let Subject::BlankNode(b) = &quad.subject {
let iri = NuriV0::repo_skolem(
base.as_ref().unwrap(),
&peer_id,
b.as_ref().unique_id().unwrap(),
)
.map_err(|e| e.to_string())?;
quad.subject = Subject::NamedNode(NamedNode::new_unchecked(iri));
}
}
if quad.object.is_blank_node() {
if base.is_none() {
return Err("Cannot insert blank nodes without a base".to_string());
}
//log_debug!("INSERTING OBJECT BN {}", quad.object);
if let Term::BlankNode(b) = &quad.object {
let iri = NuriV0::repo_skolem(
base.as_ref().unwrap(),
&peer_id,
b.as_ref().unique_id().unwrap(),
)
.map_err(|e| e.to_string())?;
quad.object = Term::NamedNode(NamedNode::new_unchecked(iri));
}
}
// TODO deal with triples in subject and object (RDF-STAR)
new_inserts.push(quad);
}
self.prepare_sparql_update(new_inserts, Vec::from_iter(removes))
.await
.map_err(|e| e.to_string())
} }
} }
} }

Loading…
Cancel
Save