Commit dd75c1a9 authored by Cédric Moreau's avatar Cédric Moreau
Browse files

[enh] Refactoring: type FileDAL.iindexDAL

parent df03c695
......@@ -305,21 +305,21 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
}
}
async updateMembers(block:BlockDTO, dal:any) {
async updateMembers(block:BlockDTO, dal:FileDAL) {
// Joiners (come back)
for (const inlineMS of block.joiners) {
let ms = MembershipDTO.fromInline(inlineMS)
const idty = await dal.getWrittenIdtyByPubkey(ms.issuer);
const idty = await dal.getWrittenIdtyByPubkeyForWotbID(ms.issuer);
dal.wotb.setEnabled(true, idty.wotb_id);
}
// Revoked
for (const inlineRevocation of block.revoked) {
let revocation = RevocationDTO.fromInline(inlineRevocation)
await dal.revokeIdentity(revocation.pubkey, block.number);
await dal.revokeIdentity(revocation.pubkey)
}
// Excluded
for (const excluded of block.excluded) {
const idty = await dal.getWrittenIdtyByPubkey(excluded);
const idty = await dal.getWrittenIdtyByPubkeyForWotbID(excluded);
dal.wotb.setEnabled(false, idty.wotb_id);
}
}
......@@ -349,8 +349,8 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
// Revert links
const writtenOn = await dal.cindexDAL.getWrittenOn(blockstamp);
for (const entry of writtenOn) {
const from = await dal.getWrittenIdtyByPubkey(entry.issuer);
const to = await dal.getWrittenIdtyByPubkey(entry.receiver);
const from = await dal.getWrittenIdtyByPubkeyForWotbID(entry.issuer);
const to = await dal.getWrittenIdtyByPubkeyForWotbID(entry.receiver);
if (entry.op == CommonConstants.IDX_CREATE) {
// We remove the created link
dal.wotb.removeLink(from.wotb_id, to.wotb_id, true);
......@@ -394,7 +394,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
// Undo 'join' which can be either newcomers or comebackers
// => equivalent to i_index.member = true AND i_index.op = 'UPDATE'
if (entry.member === true && entry.op === CommonConstants.IDX_UPDATE) {
const idty = await dal.getWrittenIdtyByPubkey(entry.pub);
const idty = await dal.getWrittenIdtyByPubkeyForWotbID(entry.pub);
dal.wotb.setEnabled(false, idty.wotb_id);
}
}
......@@ -412,7 +412,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
// Undo excluded (make them become members again in wotb)
// => equivalent to m_index.member = false
if (entry.member === false && entry.op === CommonConstants.IDX_UPDATE) {
const idty = await dal.getWrittenIdtyByPubkey(entry.pub);
const idty = await dal.getWrittenIdtyByPubkeyForWotbID(entry.pub);
dal.wotb.setEnabled(true, idty.wotb_id);
}
}
......@@ -435,7 +435,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
static async removeCertificationsFromSandbox(block:BlockDTO, dal:FileDAL) {
for (let inlineCert of block.certifications) {
let cert = CertificationDTO.fromInline(inlineCert)
let idty = await dal.getWrittenIdtyByPubkey(cert.to);
let idty = await dal.getWrittenIdtyByPubkeyForHashing(cert.to);
await dal.deleteCert({
from: cert.from,
target: IdentityDTO.getTargetHash(idty),
......
export enum DataErrors {
MEMBER_NOT_FOUND
}
......@@ -31,7 +31,17 @@ export const getOfficialIdentity = (json:any, withSig = true) => {
}
}
export const getOfficialCertification = (json:any) => {
export const getOfficialCertification = (json:{
version?:number
currency:string
issuer:string
idty_issuer:string
idty_uid:string
idty_buid:string
idty_sig:string
buid:string
sig?:string
}) => {
let raw = getNormalHeader('Certification', json);
raw += "IdtyIssuer: " + json.idty_issuer + '\n';
raw += "IdtyUniqueID: " + json.idty_uid + '\n';
......@@ -91,7 +101,11 @@ export const getTransaction = (json:any) => {
return TransactionDTO.toRAW(json)
}
function getNormalHeader(doctype:string, json:any) {
function getNormalHeader(doctype:string, json:{
version?:number
currency:string
issuer:string
}) {
let raw = "";
raw += "Version: " + (json.version || DOCUMENTS_VERSION) + "\n";
raw += "Type: " + doctype + "\n";
......
......@@ -18,7 +18,7 @@ import {ConfDTO} from "../dto/ConfDTO"
import {BlockDTO} from "../dto/BlockDTO"
import {DBHead} from "../db/DBHead"
import {DBIdentity, IdentityDAL} from "./sqliteDAL/IdentityDAL"
import {CindexEntry, IindexEntry, IndexEntry, SindexEntry} from "../indexer"
import {CindexEntry, FullMindexEntry, IindexEntry, IndexEntry, SindexEntry} from "../indexer"
import {DBPeer} from "./sqliteDAL/PeerDAL"
import {TransactionDTO} from "../dto/TransactionDTO"
import {CertDAL, DBCert} from "./sqliteDAL/CertDAL"
......@@ -35,6 +35,9 @@ import {BIndexDAL} from "./sqliteDAL/index/BIndexDAL"
import {MIndexDAL} from "./sqliteDAL/index/MIndexDAL"
import {CIndexDAL} from "./sqliteDAL/index/CIndexDAL"
import {SIndexDAL} from "./sqliteDAL/index/SIndexDAL"
import {IIndexDAL} from "./sqliteDAL/index/IIndexDAL"
import {DataErrors} from "../common-libs/errors"
import {BasicRevocableIdentity, IdentityDTO} from "../dto/IdentityDTO"
const fs = require('fs')
const path = require('path')
......@@ -72,7 +75,7 @@ export class FileDAL {
walletDAL:WalletDAL
bindexDAL:BIndexDAL
mindexDAL:MIndexDAL
iindexDAL:any
iindexDAL:IIndexDAL
sindexDAL:SIndexDAL
cindexDAL:CIndexDAL
newDals:{ [k:string]: Initiable }
......@@ -297,36 +300,231 @@ export class FileDAL {
return this.sindexDAL.getAvailableForPubkey(pubkey)
}
async getIdentityByHashOrNull(hash:string): Promise<DBIdentity|null> {
const pending = await this.idtyDAL.getByHash(hash);
async getGlobalIdentityByHashForExistence(hash:string): Promise<boolean> {
const pending = await this.idtyDAL.getByHash(hash)
if (!pending) {
return this.iindexDAL.getFromHash(hash);
const idty = await this.iindexDAL.getFullFromHash(hash)
if (!idty) {
return false
}
}
return true
}
async getGlobalIdentityByHashForHashingAndSig(hash:string): Promise<{ pubkey:string, uid:string, buid:string, sig:string }|null> {
const pending = await this.idtyDAL.getByHash(hash)
if (!pending) {
const idty = await this.iindexDAL.getFullFromHash(hash)
if (!idty) {
return null
}
return {
pubkey: idty.pub,
uid: idty.uid,
buid: idty.created_on,
sig: idty.sig
}
}
return pending
}
async getGlobalIdentityByHashForLookup(hash:string): Promise<{ pubkey:string, uid:string, buid:string, sig:string, member:boolean, wasMember:boolean }|null> {
const pending = await this.idtyDAL.getByHash(hash)
if (!pending) {
const idty = await this.iindexDAL.getFullFromHash(hash)
if (!idty) {
return null
}
return {
pubkey: idty.pub,
uid: idty.uid,
buid: idty.created_on,
sig: idty.sig,
member: idty.member,
wasMember: idty.wasMember
}
}
return pending
}
async getGlobalIdentityByHashForJoining(hash:string): Promise<{ pubkey:string, uid:string, buid:string, sig:string, member:boolean, wasMember:boolean, revoked:boolean }|null> {
const pending = await this.idtyDAL.getByHash(hash)
if (!pending) {
const idty = await this.iindexDAL.getFullFromHash(hash)
if (!idty) {
return null
}
const membership = await this.mindexDAL.getReducedMS(idty.pub) as FullMindexEntry
return {
pubkey: idty.pub,
uid: idty.uid,
buid: idty.created_on,
sig: idty.sig,
member: idty.member,
wasMember: idty.wasMember,
revoked: !!(membership.revoked_on)
}
}
return pending
}
async getGlobalIdentityByHashForIsMember(hash:string): Promise<{ pub:string, member:boolean }|null> {
const pending = await this.idtyDAL.getByHash(hash)
if (!pending) {
const idty = await this.iindexDAL.getFullFromHash(hash)
if (!idty) {
return null
}
return {
pub: idty.pub,
member: idty.member
}
}
return {
pub: pending.pubkey,
member: pending.member
}
}
async getGlobalIdentityByHashForRevocation(hash:string): Promise<{ pub:string, uid:string, created_on:string, sig:string, member:boolean, wasMember:boolean, revoked:boolean, revocation_sig:string|null, expires_on:number }|null> {
const pending = await this.idtyDAL.getByHash(hash)
if (!pending) {
const idty = await this.iindexDAL.getFullFromHash(hash)
if (!idty) {
return null
}
const membership = await this.mindexDAL.getReducedMS(idty.pub) as FullMindexEntry
return {
pub: idty.pub,
uid: idty.uid,
sig: idty.sig,
member: idty.member,
wasMember: idty.wasMember,
expires_on: membership.expires_on,
created_on: idty.created_on,
revoked: !!(membership.revoked_on),
revocation_sig: membership.revocation
}
}
return {
pub: pending.pubkey,
uid: pending.uid,
sig: pending.sig,
expires_on: pending.expires_on,
created_on: pending.buid,
member: pending.member,
wasMember: pending.wasMember,
revoked: pending.revoked,
revocation_sig: pending.revocation_sig
}
return pending;
}
getMembers() {
return this.iindexDAL.getMembers()
}
async getWrittenIdtyByPubkey(pubkey:string) {
async getWrittenIdtyByPubkeyForHash(pubkey:string): Promise<{ hash:string }> {
return this.getWrittenForSureIdtyByPubkey(pubkey)
}
async getWrittenIdtyByPubkeyForHashing(pubkey:string): Promise<{ uid:string, created_on:string, pub:string }> {
return this.getWrittenForSureIdtyByPubkey(pubkey)
}
async getWrittenIdtyByPubkeyForWotbID(pubkey:string): Promise<{ wotb_id:number }> {
return this.getWrittenForSureIdtyByPubkey(pubkey)
}
async getWrittenIdtyByPubkeyForUidAndPubkey(pubkey:string): Promise<{ pub:string, uid:string }> {
return this.getWrittenForSureIdtyByPubkey(pubkey)
}
async getWrittenIdtyByPubkeyForIsMember(pubkey:string): Promise<{ member:boolean }|null> {
return this.iindexDAL.getFromPubkey(pubkey)
}
async getWrittenIdtyByPubkeyForUidAndIsMemberAndWasMember(pubkey:string): Promise<{ uid:string, member:boolean, wasMember:boolean }|null> {
return this.iindexDAL.getFromPubkey(pubkey)
}
async getWrittenIdtyByPubkeyOrUidForIsMemberAndPubkey(search:string): Promise<{ pub:string, member:boolean }|null> {
return this.iindexDAL.getFromPubkeyOrUid(search)
}
async getWrittenIdtyByPubkeyOrUIdForHashingAndIsMember(search:string): Promise<{ uid:string, created_on:string, pub:string, member:boolean }|null> {
return await this.iindexDAL.getFromPubkeyOrUid(search)
}
async getWrittenIdtyByPubkeyForRevocationCheck(pubkey:string): Promise<{ pub:string, uid:string, created_on:string, sig:string, revoked_on:number|null }|null> {
const idty = await this.iindexDAL.getFromPubkey(pubkey)
if (!idty) {
return null;
return null
}
const membership = await this.mindexDAL.getReducedMS(pubkey) as FullMindexEntry
return {
pub: idty.pub,
uid: idty.uid,
sig: idty.sig,
created_on: idty.created_on,
revoked_on: membership.revoked_on
}
const membership = await this.mindexDAL.getReducedMS(pubkey)
idty.revoked_on = membership.revoked_on
return idty;
}
async getWrittenIdtyByUID(uid:string) {
const idty = await this.iindexDAL.getFromUID(uid)
async getWrittenIdtyByPubkeyForCertificationCheck(pubkey:string): Promise<{ pub:string, uid:string, created_on:string, sig:string }|null> {
const idty = await this.iindexDAL.getFromPubkey(pubkey)
if (!idty) {
return null;
return null
}
const membership = await this.mindexDAL.getReducedMS(idty.pub)
idty.revoked_on = membership.revoked_on
return idty;
return {
pub: idty.pub,
uid: idty.uid,
sig: idty.sig,
created_on: idty.created_on,
}
}
async getWrittenIdtyByPubkeyForUidAndMemberAndCreatedOn(pubkey:string): Promise<{ uid:string, member:boolean, created_on:string }|null> {
const idty = await this.iindexDAL.getFromPubkey(pubkey)
if (!idty) {
return null
}
return {
uid: idty.uid,
member: idty.member,
created_on: idty.created_on,
}
}
private async getWrittenForSureIdtyByPubkey(pubkey:string) {
const idty = await this.iindexDAL.getFromPubkey(pubkey)
if (!idty) {
throw Error(DataErrors[DataErrors.MEMBER_NOT_FOUND])
}
return idty
}
private async getWrittenForSureIdtyByUid(pubkey:string) {
const idty = (await this.iindexDAL.getFullFromUID(pubkey))
if (!idty) {
throw Error(DataErrors[DataErrors.MEMBER_NOT_FOUND])
}
return idty
}
async getWrittenIdtyByPubkeyForExistence(uid:string) {
return !!(await this.iindexDAL.getFromPubkey(uid))
}
async getWrittenIdtyByUIDForExistence(uid:string) {
return !!(await this.iindexDAL.getFromUID(uid))
}
async getWrittenIdtyByUidForHashing(uid:string): Promise<{ uid:string, created_on:string, pub:string }> {
return this.getWrittenForSureIdtyByUid(uid)
}
async getWrittenIdtyByUIDForWotbId(uid:string): Promise<{ wotb_id:number }> {
return this.getWrittenForSureIdtyByUid(uid)
}
async findPeersWhoseHashIsIn(hashes:string[]) {
......@@ -355,8 +553,8 @@ export class FileDAL {
const revoking = await this.idtyDAL.getToRevoke();
const toRevoke = [];
for (const pending of revoking) {
const idty = await this.getWrittenIdtyByPubkey(pending.pubkey);
if (!idty.revoked_on) {
const idty = await this.getWrittenIdtyByPubkeyForRevocationCheck(pending.pubkey)
if (idty && !idty.revoked_on) {
toRevoke.push(pending);
}
}
......@@ -385,7 +583,7 @@ export class FileDAL {
return await Promise.all(found.map(async (f:any) => {
const ms = await this.mindexDAL.getReducedMS(f.pub);
if (ms) {
f.revoked_on = ms.revoked_on ? parseInt(ms.revoked_on) : null;
f.revoked_on = ms.revoked_on ? ms.revoked_on : null;
f.revoked = !!f.revoked_on;
f.revocation_sig = ms.revocation || null;
}
......@@ -420,7 +618,7 @@ export class FileDAL {
const links = await this.cindexDAL.getValidLinksFrom(pubkey);
let matching = certs;
await Promise.all(links.map(async (entry:any) => {
const idty = await this.getWrittenIdtyByPubkey(entry.receiver);
const idty = await this.getWrittenIdtyByPubkeyForHash(entry.receiver)
entry.from = entry.issuer;
entry.to = entry.receiver;
const cbt = entry.created_on.split('-');
......@@ -558,15 +756,17 @@ export class FileDAL {
}
async setRevoked(pubkey:string) {
const idty = await this.getWrittenIdtyByPubkey(pubkey);
idty.revoked = true;
return await this.idtyDAL.saveIdentity(idty);
return await this.idtyDAL.setRevoked(pubkey)
}
setRevocating = (existing:DBIdentity, revocation_sig:string) => {
existing.revocation_sig = revocation_sig;
existing.revoked = false;
return this.idtyDAL.saveIdentity(existing);
setRevocating = (idty:BasicRevocableIdentity, revocation_sig:string) => {
const dbIdentity = IdentityDTO.fromBasicIdentity(idty)
dbIdentity.member = idty.member
dbIdentity.wasMember = idty.wasMember
dbIdentity.expires_on = idty.expires_on
dbIdentity.revocation_sig = revocation_sig
dbIdentity.revoked = false
return this.idtyDAL.saveIdentity(dbIdentity)
}
async getPeerOrNull(pubkey:string) {
......@@ -682,8 +882,8 @@ export class FileDAL {
async updateWotbLinks(cindex:CindexEntry[]) {
for (const entry of cindex) {
const from = await this.getWrittenIdtyByPubkey(entry.issuer);
const to = await this.getWrittenIdtyByPubkey(entry.receiver);
const from = await this.getWrittenIdtyByPubkeyForWotbID(entry.issuer);
const to = await this.getWrittenIdtyByPubkeyForWotbID(entry.receiver);
if (entry.op == CommonConstants.IDX_CREATE) {
this.wotb.addLink(from.wotb_id, to.wotb_id);
} else {
......
......@@ -27,7 +27,19 @@ export abstract class DBIdentity implements Cloneable {
}
certs:any[] = []
signed:any[] = []
signed: {
idty: {
pubkey: string
uid: string
buid: string
sig: string
member: string
wasMember: string
}
block_number: number
block_hash: string
sig: string
}[] = []
revoked: boolean
currentMSN: null
......@@ -48,7 +60,11 @@ export abstract class DBIdentity implements Cloneable {
expires_on: number
getTargetHash() {
return IdentityDTO.getTargetHash(this)
return IdentityDTO.getTargetHash({
pub: this.pubkey,
created_on: this.buid,
uid: this.uid
})
}
json() {
......@@ -72,7 +88,7 @@ export abstract class DBIdentity implements Cloneable {
"timestamp": this.buid
},
"revoked": this.revoked,
"revoked_on": this.revoked_on,
"revoked_on": parseInt(String(this.revoked_on)),
"revocation_sig": this.revocation_sig,
"self": this.sig,
"others": others
......@@ -255,6 +271,10 @@ export class IdentityDAL extends AbstractSQLite<DBIdentity> {
})
}
setRevoked(pubkey: string) {
return this.query('UPDATE ' + this.table + ' SET revoked = ? WHERE pubkey = ?', [true, pubkey])
}
getByHash(hash:string) {
return this.sqlFindOne({
hash: hash
......
......@@ -13,7 +13,7 @@
import {SQLiteDriver} from "../../drivers/SQLiteDriver";
import {AbstractIndex} from "../AbstractIndex";
import {IindexEntry, Indexer} from "../../../indexer";
import {FullIindexEntry, IindexEntry, Indexer} from "../../../indexer";
const _ = require('underscore');
......@@ -126,15 +126,19 @@ export class IIndexDAL extends AbstractIndex<IindexEntry> {
}
getFromPubkey(pubkey:string) {
return this.entityOrNull('pub', pubkey)
return this.entityOrNull('pub', pubkey) as Promise<FullIindexEntry|null>
}
getFromUID(uid:string) {
return this.entityOrNull('uid', uid)
getFromUID(uid:string, retrieveOnPubkey = false) {
return this.entityOrNull('uid', uid, retrieveOnPubkey)
}
getFromHash(hash:string) {
return this.entityOrNull('hash', hash, true)
getFullFromUID(uid:string): Promise<FullIindexEntry|null> {
return this.entityOrNull('uid', uid, true) as Promise<FullIindexEntry|null>
}
getFullFromHash(hash:string): Promise<FullIindexEntry|null> {
return this.entityOrNull('hash', hash, true) as Promise<FullIindexEntry|null>
}
reducable(pub:string) {
......@@ -179,4 +183,12 @@ export class IIndexDAL extends AbstractIndex<IindexEntry> {
written_on: row.written_on
}
}
async getFromPubkeyOrUid(search: string) {
const idty = await this.getFromPubkey(search)
if (idty) {
return idty
}
return this.getFromUID(search, true) as Promise<FullIindexEntry|null>
}
}
......@@ -13,7 +13,7 @@
import {SQLiteDriver} from "../../drivers/SQLiteDriver";
import {AbstractIndex} from "../AbstractIndex";
import {Indexer, MindexEntry} from "../../../indexer";
import {FullMindexEntry, Indexer, MindexEntry} from "../../../indexer";
export class MIndexDAL extends AbstractIndex<MindexEntry> {
......@@ -68,12 +68,12 @@ export class MIndexDAL extends AbstractIndex<MindexEntry> {
'COMMIT;')
}
async getReducedMS(pub:string) {
async getReducedMS(pub:string): Promise<FullMindexEntry|null> {
const reducables = await this.reducable(pub);
if (reducables.length) {
return Indexer.DUP_HELPERS.reduce(reducables);
return Indexer.DUP_HELPERS.reduce(reducables) as FullMindexEntry
}
return null;
return null
}
reducable(pub:string) {
......
......@@ -63,8 +63,8 @@ export class CertificationDTO extends ShortCertificationDTO implements Cloneable
getTargetHash() {
return IdentityDTO.getTargetHash({
uid: this.idty_uid,
buid: this.idty_buid,
pubkey: this.idty_issuer
created_on: this.idty_buid,
pub: this.idty_issuer
})
}
......
......@@ -18,16 +18,26 @@ import {DBIdentity, NewDBIdentity} from "../dal/sqliteDAL/IdentityDAL"
const DEFAULT_DOCUMENT_VERSION = 10
export interface HashableIdentity {
created_on: string
uid: string
pub: string
}
export interface BasicIdentity {
buid: string
uid: string
pubkey: string
sig: string
}
export interface BasicIdentity {
export interface BasicRevocableIdentity {
buid: string
uid: string