feat(db): attribute a wot_id to each identity
This commit is contained in:
parent
4a7d3270df
commit
6d7a35dd8b
7 changed files with 90 additions and 16 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1025,6 +1025,7 @@ dependencies = [
|
|||
"lz4_flex",
|
||||
"maplit",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"resiter",
|
||||
"smallvec",
|
||||
]
|
||||
|
|
|
@ -45,6 +45,7 @@ pub(crate) use duniter_core::dbs::{
|
|||
bincode_db, CorruptedBytes, HashKeyV2, PubKeyKeyV2, SourceAmountValV2, ToDumpString,
|
||||
WalletConditionsV2,
|
||||
};
|
||||
pub(crate) use duniter_core::wot::WotId;
|
||||
pub(crate) use serde::{Deserialize, Serialize};
|
||||
pub(crate) use std::collections::BTreeSet;
|
||||
|
||||
|
|
|
@ -15,12 +15,13 @@
|
|||
|
||||
use crate::*;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct GvaIdtyDbV1 {
|
||||
pub is_member: bool,
|
||||
pub joins: SmallVec<[BlockNumber; 2]>,
|
||||
pub leaves: BTreeSet<BlockNumber>,
|
||||
pub first_ud: Option<BlockNumber>,
|
||||
pub wot_id: WotId,
|
||||
}
|
||||
|
||||
impl AsBytes for GvaIdtyDbV1 {
|
||||
|
|
|
@ -471,8 +471,8 @@ fn collect_uds<BC: BackendCol, I: Iterator<Item = BlockNumber>>(
|
|||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use duniter_core::dbs::smallvec::smallvec as svec;
|
||||
use duniter_core::dbs::{databases::bc_v2::BcV2DbWritable, SourceAmountValV2, UdIdV2};
|
||||
use duniter_core::{dbs::smallvec::smallvec as svec, wot::WotId};
|
||||
use duniter_gva_db::GvaV1DbWritable;
|
||||
|
||||
#[test]
|
||||
|
@ -482,6 +482,7 @@ mod tests {
|
|||
joins: svec![BlockNumber(26), BlockNumber(51)],
|
||||
leaves: [BlockNumber(32)].iter().copied().collect(),
|
||||
first_ud: Some(BlockNumber(29)),
|
||||
wot_id: WotId(0),
|
||||
};
|
||||
let blocks_with_ud = vec![
|
||||
BlockNumber(3),
|
||||
|
@ -531,6 +532,7 @@ mod tests {
|
|||
joins: svec![BlockNumber(26), BlockNumber(51)],
|
||||
leaves: [BlockNumber(32)].iter().copied().collect(),
|
||||
first_ud: Some(BlockNumber(29)),
|
||||
wot_id: WotId(0),
|
||||
};
|
||||
|
||||
let bc_db = duniter_core::dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
|
||||
|
|
|
@ -18,12 +18,13 @@ duniter-core = { git = "https://git.duniter.org/nodes/rust/duniter-core" }
|
|||
duniter-gva-db = { path = "../db" }
|
||||
dubp = { version = "0.54.1", features = ["duniter"] }
|
||||
lz4_flex = { version = "0.7", default-features = false }
|
||||
once_cell = "1.5.2"
|
||||
once_cell = "1.7"
|
||||
resiter = "0.4.0"
|
||||
|
||||
[dev-dependencies]
|
||||
duniter-core = { git = "https://git.duniter.org/nodes/rust/duniter-core", features = ["mem"] }
|
||||
maplit = "1.0.2"
|
||||
parking_lot = "0.11"
|
||||
smallvec = { version = "1.4.0", features = ["serde", "write"] }
|
||||
|
||||
[features]
|
||||
|
|
|
@ -19,13 +19,35 @@ pub(crate) fn update_identities<B: Backend>(
|
|||
block: &DubpBlockV10,
|
||||
identities: &mut TxColRw<B::Col, GvaIdentitiesEvent>,
|
||||
) -> KvResult<()> {
|
||||
let mut identities_pubkeys = HashSet::new();
|
||||
for idty in block.identities() {
|
||||
let pubkey = idty.issuers()[0];
|
||||
identities_pubkeys.insert(pubkey);
|
||||
let wot_id = crate::get_next_wot_id();
|
||||
|
||||
identities.upsert(
|
||||
PubKeyKeyV2(pubkey),
|
||||
GvaIdtyDbV1 {
|
||||
is_member: true,
|
||||
joins: smallvec![block.number()],
|
||||
leaves: BTreeSet::new(),
|
||||
first_ud: None,
|
||||
wot_id,
|
||||
},
|
||||
);
|
||||
}
|
||||
for mb in block.joiners() {
|
||||
let pubkey = mb.issuers()[0];
|
||||
|
||||
let mut idty = identities.get(&PubKeyKeyV2(pubkey))?.unwrap_or_default();
|
||||
idty.is_member = true;
|
||||
idty.joins.push(block.number());
|
||||
identities.upsert(PubKeyKeyV2(pubkey), idty);
|
||||
// Update identity only if the join event concerns an identity already created in the past
|
||||
if !identities_pubkeys.contains(&pubkey) {
|
||||
let mut idty = identities
|
||||
.get(&PubKeyKeyV2(pubkey))?
|
||||
.ok_or_else(|| KvError::DbCorrupted("Joiner without identity".to_owned()))?;
|
||||
idty.is_member = true;
|
||||
idty.joins.push(block.number());
|
||||
identities.upsert(PubKeyKeyV2(pubkey), idty);
|
||||
}
|
||||
}
|
||||
for revo in block.revoked() {
|
||||
let pubkey = revo.issuer;
|
||||
|
@ -52,7 +74,9 @@ pub(crate) fn revert_identities<B: Backend>(
|
|||
for mb in block.joiners() {
|
||||
let pubkey = mb.issuers()[0];
|
||||
|
||||
let mut idty = identities.get(&PubKeyKeyV2(pubkey))?.unwrap_or_default();
|
||||
let mut idty = identities
|
||||
.get(&PubKeyKeyV2(pubkey))?
|
||||
.ok_or_else(|| KvError::DbCorrupted("Joiner without identity".to_owned()))?;
|
||||
idty.is_member = false;
|
||||
idty.joins.pop();
|
||||
identities.upsert(PubKeyKeyV2(pubkey), idty);
|
||||
|
@ -60,6 +84,7 @@ pub(crate) fn revert_identities<B: Backend>(
|
|||
for idty in block.identities() {
|
||||
let pubkey = idty.issuers()[0];
|
||||
identities.remove(PubKeyKeyV2(pubkey));
|
||||
crate::revert_wot_id();
|
||||
}
|
||||
for revo in block.revoked() {
|
||||
let pubkey = revo.issuer;
|
||||
|
|
|
@ -36,21 +36,24 @@ use dubp::{
|
|||
},
|
||||
wallet::prelude::*,
|
||||
};
|
||||
use duniter_core::dbs::{
|
||||
bincode_db, kv_typed::prelude::*, prelude::*, FileBackend, HashKeyV2, PubKeyKeyV2,
|
||||
SourceAmountValV2, WalletConditionsV2,
|
||||
use duniter_core::{
|
||||
dbs::{
|
||||
bincode_db, kv_typed::prelude::*, prelude::*, smallvec::smallvec, FileBackend, HashKeyV2,
|
||||
PubKeyKeyV2, SourceAmountValV2, WalletConditionsV2,
|
||||
},
|
||||
wot::{WebOfTrust, WotId, MAIN_WOT},
|
||||
};
|
||||
use duniter_gva_db::*;
|
||||
use once_cell::sync::OnceCell;
|
||||
use resiter::filter::Filter;
|
||||
use std::{
|
||||
collections::{BTreeSet, HashMap},
|
||||
collections::{BTreeSet, HashMap, HashSet},
|
||||
ops::AddAssign,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
static GVA_DB_RO: once_cell::sync::OnceCell<GvaV1DbRo<FileBackend>> =
|
||||
once_cell::sync::OnceCell::new();
|
||||
static GVA_DB_RW: once_cell::sync::OnceCell<GvaV1Db<FileBackend>> =
|
||||
once_cell::sync::OnceCell::new();
|
||||
static GVA_DB_RO: OnceCell<GvaV1DbRo<FileBackend>> = OnceCell::new();
|
||||
static GVA_DB_RW: OnceCell<GvaV1Db<FileBackend>> = OnceCell::new();
|
||||
|
||||
pub fn get_gva_db_ro(profile_path_opt: Option<&Path>) -> &'static GvaV1DbRo<FileBackend> {
|
||||
GVA_DB_RO.get_or_init(|| get_gva_db_rw(profile_path_opt).get_ro_handler())
|
||||
|
@ -65,6 +68,39 @@ pub fn get_gva_db_rw(profile_path_opt: Option<&Path>) -> &'static GvaV1Db<FileBa
|
|||
})
|
||||
}
|
||||
|
||||
static mut NEXT_WOT_ID: Option<usize> = None;
|
||||
|
||||
fn get_next_wot_id() -> WotId {
|
||||
WotId(unsafe {
|
||||
if let Some(ref mut next_wot_id_) = NEXT_WOT_ID {
|
||||
let next_wot_id = *next_wot_id_;
|
||||
next_wot_id_.add_assign(1);
|
||||
next_wot_id
|
||||
} else {
|
||||
NEXT_WOT_ID = Some(if let Some(main_wot) = MAIN_WOT.get() {
|
||||
main_wot.read().size()
|
||||
} else {
|
||||
0
|
||||
});
|
||||
0
|
||||
}
|
||||
})
|
||||
}
|
||||
fn revert_wot_id() {
|
||||
unsafe {
|
||||
if let Some(ref mut next_wot_id_) = NEXT_WOT_ID {
|
||||
use std::ops::SubAssign as _;
|
||||
next_wot_id_.sub_assign(1);
|
||||
} else {
|
||||
NEXT_WOT_ID = Some(if let Some(main_wot) = MAIN_WOT.get() {
|
||||
main_wot.read().size() - 1
|
||||
} else {
|
||||
unreachable!()
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub struct UtxoV10<'s> {
|
||||
pub id: UtxoIdV10,
|
||||
pub amount: SourceAmount,
|
||||
|
@ -256,9 +292,13 @@ mod tests {
|
|||
documents::transaction::TransactionDocumentV10Stringified,
|
||||
documents_parser::prelude::FromStringObject,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
static TESTS_MUTEX: Lazy<parking_lot::Mutex<()>> = Lazy::new(|| parking_lot::Mutex::new(()));
|
||||
|
||||
#[test]
|
||||
fn test_gva_apply_block() -> anyhow::Result<()> {
|
||||
let _ = TESTS_MUTEX.lock();
|
||||
let gva_db = GvaV1Db::<Mem>::open(MemConf::default())?;
|
||||
|
||||
let s1 = WalletScriptV10::single_sig(PublicKey::from_base58(
|
||||
|
@ -272,6 +312,7 @@ mod tests {
|
|||
version: 10,
|
||||
median_time: 5_243,
|
||||
dividend: Some(1000),
|
||||
identities: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:Ydnclvw76/JHcKSmU9kl9Ie0ne5/X8NYOqPqbGnufIK3eEPRYYdEYaQh+zffuFhbtIRjv6m/DkVLH5cLy/IyAg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois".to_owned()],
|
||||
joiners: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:FFeyrvYio9uYwY5aMcDGswZPNjGLrl8THn9l3EPKSNySD3SDSHjCljSfFEwb87sroyzJQoVzPwER0sW/cbZMDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois".to_owned()],
|
||||
inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
|
||||
signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
|
||||
|
@ -430,6 +471,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_gva_revert_block() -> anyhow::Result<()> {
|
||||
let _ = TESTS_MUTEX.lock();
|
||||
let gva_db = GvaV1Db::<Mem>::open(MemConf::default())?;
|
||||
|
||||
let s1 = WalletScriptV10::single_sig(PublicKey::from_base58(
|
||||
|
@ -443,6 +485,7 @@ mod tests {
|
|||
version: 10,
|
||||
median_time: 5_243,
|
||||
dividend: Some(1000),
|
||||
identities: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:Ydnclvw76/JHcKSmU9kl9Ie0ne5/X8NYOqPqbGnufIK3eEPRYYdEYaQh+zffuFhbtIRjv6m/DkVLH5cLy/IyAg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois".to_owned()],
|
||||
joiners: vec!["D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:FFeyrvYio9uYwY5aMcDGswZPNjGLrl8THn9l3EPKSNySD3SDSHjCljSfFEwb87sroyzJQoVzPwER0sW/cbZMDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois".to_owned()],
|
||||
inner_hash: Some("0000000A65A12DB95B3153BCD05DB4D5C30CC7F0B1292D9FFBC3DE67F72F6040".to_owned()),
|
||||
signature: "7B0hvcfajE2G8nBLp0vLVaQcQdQIyli21Gu8F2l+nimKHRe+fUNi+MWd1e/u29BYZa+RZ1yxhbHIbFzytg7fAA==".to_owned(),
|
||||
|
|
Loading…
Add table
Reference in a new issue