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

[fix] #1037 Migrating Entity Certification

parent 1ed2b6e5
......@@ -8,10 +8,10 @@ import {DBBlock} from "../db/DBBlock"
import {CHECK} from "../rules/index"
import {RevocationDTO} from "../dto/RevocationDTO"
import {IdentityDTO} from "../dto/IdentityDTO"
import {CertificationDTO} from "../dto/CertificationDTO"
const _ = require('underscore')
const common = require('duniter-common')
const Certification = require('../entity/certification')
const Membership = require('../entity/membership')
const Transaction = require('../entity/transaction')
......@@ -416,10 +416,13 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
*/
async removeCertificationsFromSandbox(block:BlockDTO, dal:any) {
for (let inlineCert of block.certifications) {
let cert = Certification.statics.fromInline(inlineCert);
let cert = CertificationDTO.fromInline(inlineCert)
let idty = await dal.getWritten(cert.to);
cert.target = IdentityDTO.getTargetHash(idty)
await dal.deleteCert(cert);
await dal.deleteCert({
from: cert.from,
target: IdentityDTO.getTargetHash(idty),
sig: cert.sig,
});
}
}
......
......@@ -122,7 +122,7 @@ export abstract class AbstractSQLite<T> {
return (await this.query('SELECT * FROM ' + this.table + ' WHERE ' + conditions, params))[0];
}
async deleteEntity(entity:T): Promise<void> {
async deleteEntity(entity:any): Promise<void> {
const toSave = this.toRow(entity);
if (this.beforeSaveHook) {
this.beforeSaveHook(toSave);
......
import {SQLiteDriver} from "../drivers/SQLiteDriver";
import {AbstractSQLite} from "./AbstractSQLite";
import {SandBox} from "./SandBox";
import {SQLiteDriver} from "../drivers/SQLiteDriver"
import {AbstractSQLite} from "./AbstractSQLite"
import {SandBox} from "./SandBox"
const constants = require('../../constants');
......@@ -114,7 +114,7 @@ export class CertDAL extends AbstractSQLite<DBCert> {
return this.sqlExisting(cert)
}
deleteCert(cert:DBCert) {
deleteCert(cert:{ from:string, target:string, sig:string }) {
return this.deleteEntity(cert)
}
......
export class CertificationDTO {
import {IdentityDTO} from "./IdentityDTO"
const DEFAULT_DOCUMENT_VERSION = 10
export class ShortCertificationDTO {
constructor(
public pubkey: string,
public to: string,
public block_number: number,
public sig: string
public sig: string,
public idty_issuer: string
) {}
static fromInline(inline:string): CertificationDTO {
get issuer() {
return this.pubkey
}
get from() {
return this.pubkey
}
get to() {
return this.idty_issuer
}
}
export class CertificationDTO extends ShortCertificationDTO {
constructor(
public version: number,
public currency: string,
public pubkey: string,
public buid: string,
public sig: string,
public idty_issuer:string,
public idty_uid:string,
public idty_buid:string,
public idty_sig:string
) {
super(pubkey, parseInt(buid.split(':')[0]), sig, idty_issuer)
}
getTargetHash() {
return IdentityDTO.getTargetHash({
uid: this.idty_uid,
buid: this.idty_buid,
pubkey: this.idty_issuer
})
}
getRaw() {
let raw = "";
raw += "Version: " + this.version + "\n";
raw += "Type: Certification\n";
raw += "Currency: " + this.currency + "\n";
raw += "Issuer: " + this.pubkey + "\n";
raw += "IdtyIssuer: " + this.idty_issuer + '\n';
raw += "IdtyUniqueID: " + this.idty_uid + '\n';
raw += "IdtyTimestamp: " + this.idty_buid + '\n';
raw += "IdtySignature: " + this.idty_sig + '\n';
raw += "CertTimestamp: " + this.buid + '\n';
raw += this.sig + '\n'
return raw
}
json() {
return {
"issuer": this.pubkey,
"timestamp": this.buid,
"sig": this.sig,
"target": {
"issuer": this.idty_issuer,
"uid": this.idty_uid,
"timestamp": this.idty_buid,
"sig": this.idty_sig
}
}
}
static fromInline(inline:string): ShortCertificationDTO {
const [pubkey, to, block_number, sig]: string[] = inline.split(':')
return new CertificationDTO(pubkey, to, parseInt(block_number), sig)
return new ShortCertificationDTO(pubkey, parseInt(block_number), sig, to)
}
static fromJSONObject(obj:any) {
return new CertificationDTO(
obj.version || DEFAULT_DOCUMENT_VERSION,
obj.currency,
obj.pubkey || obj.issuer,
obj.buid,
obj.sig,
obj.idty_issuer || obj.to,
obj.idty_uid,
obj.idty_buid,
obj.idty_sig
)
}
}
\ No newline at end of file
"use strict";
const _ = require('underscore');
const rawer = require('duniter-common').rawer;
const ucp = require('duniter-common').buid;
const Certification = function(json) {
this.linked = false;
_(json).keys().forEach((key) => {
this[key] = json[key];
});
this.from = this.pubkey = this.from || this.pubkey || this.issuer;
this.block = this.block_number = parseInt(this.block || this.block_number);
this.getRaw = () => rawer.getOfficialCertification(this);
this.getTargetHash = () => ucp.format.hashf(this.idty_uid + this.idty_buid + this.idty_issuer);
this.inline = () => [this.pubkey, this.to, this.block_number, this.sig].join(':');
this.json = () => {
return {
"issuer": this.issuer,
"timestamp": this.buid,
"sig": this.sig,
"target": {
"issuer": this.idty_issuer,
"uid": this.idty_uid,
"timestamp": this.idty_buid,
"sig": this.idty_sig
}
};
};
};
Certification.statics = {};
Certification.statics.fromInline = function (inline) {
const sp = inline.split(':');
return new Certification({
pubkey: sp[0],
to: sp[1],
block_number: parseInt(sp[2]),
sig: sp[3]
});
};
Certification.statics.toInline = function (entity, certificationModel) {
if (certificationModel) {
let model = new certificationModel();
_(model.aliases).keys().forEach((aliasKey) => {
let alias = model.aliases[aliasKey];
entity[aliasKey] = entity[alias];
});
}
return [entity.pubkey, entity.to, entity.block_number, entity.sig].join(':');
};
Certification.statics.fromJSON = (json) => new Certification(json);
module.exports = Certification;
......@@ -4,11 +4,11 @@ import {DBPeer} from "../dal/sqliteDAL/PeerDAL"
import {BlockDTO} from "../dto/BlockDTO"
import {RevocationDTO} from "../dto/RevocationDTO"
import {IdentityDTO} from "../dto/IdentityDTO"
import {CertificationDTO} from "../dto/CertificationDTO"
const request = require('request');
const constants = require('../../lib/constants');
const Peer = require('../../lib/entity/peer');
const Certification = require('../../lib/entity/certification');
const Membership = require('../../lib/entity/membership');
const Transaction = require('../../lib/entity/transaction');
const logger = require('../logger').NewLogger('multicaster');
......@@ -60,10 +60,10 @@ export class Multicaster extends stream.Transform {
async certForward(doc:any, peers:DBPeer[]) {
return this.forward({
transform: Certification.statics.fromJSON,
transform: (obj:any) => CertificationDTO.fromJSONObject(obj),
type: 'Cert',
uri: '/wot/certify',
getObj: (cert:any) => {
getObj: (cert:CertificationDTO) => {
return {
"cert": cert.getRaw()
};
......
......@@ -6,11 +6,12 @@ import {GLOBAL_RULES_FUNCTIONS, GLOBAL_RULES_HELPERS} from "../lib/rules/global_
import {BlockDTO} from "../lib/dto/BlockDTO"
import {RevocationDTO} from "../lib/dto/RevocationDTO"
import {BasicIdentity, IdentityDTO} from "../lib/dto/IdentityDTO"
import {CertificationDTO} from "../lib/dto/CertificationDTO"
import {DBCert} from "../lib/dal/sqliteDAL/CertDAL"
"use strict";
const keyring = require('duniter-common').keyring;
const constants = require('../lib/constants');
const Certification = require('../../app/lib/entity/certification');
const BY_ABSORPTION = true;
......@@ -129,7 +130,7 @@ export class IdentityService {
const potentialNext = BlockDTO.fromJSONObject({ currency: this.conf.currency, identities: [], number: current ? current.number + 1 : 0 });
// Force usage of local currency name, do not accept other currencies documents
obj.currency = this.conf.currency || obj.currency;
const cert = Certification.statics.fromJSON(obj);
const cert = CertificationDTO.fromJSONObject(obj)
const targetHash = cert.getTargetHash();
let idty = await this.dal.getIdentityByHashOrNull(targetHash);
let idtyAbsorbed = false
......@@ -142,14 +143,15 @@ export class IdentityService {
sig: cert.idty_sig
}, BY_ABSORPTION);
}
let anErr:any
return GlobalFifoPromise.pushFIFO(async () => {
this.logger.info('⬇ CERT %s block#%s -> %s', cert.from, cert.block_number, idty.uid);
try {
await GLOBAL_RULES_HELPERS.checkCertificationIsValid(cert, potentialNext, () => Promise.resolve(idty), this.conf, this.dal);
} catch (e) {
cert.err = e;
anErr = e;
}
if (!cert.err) {
if (!anErr) {
try {
let basedBlock = await this.dal.getBlock(cert.block_number);
if (cert.block_number == 0 && !basedBlock) {
......@@ -157,41 +159,44 @@ export class IdentityService {
number: 0,
hash: 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855'
};
} else {
cert.expires_on = basedBlock.medianTime + this.conf.sigWindow;
}
cert.block_hash = basedBlock.hash;
const mCert = new Certification({
pubkey: cert.from,
const mCert:DBCert = {
from: cert.from,
sig: cert.sig,
block_number: cert.block_number,
block_hash: cert.block_hash,
block_hash: basedBlock.hash,
target: targetHash,
to: idty.pubkey,
expires_on: cert.expires_on
});
expires_on: basedBlock.medianTime + this.conf.sigWindow,
linked: false,
written: false,
expired: false,
written_block: null,
written_hash: null,
block: cert.block_number
}
let existingCert = await this.dal.existsCert(mCert);
if (!existingCert) {
if (!(await this.dal.certDAL.getSandboxForKey(cert.from).acceptNewSandBoxEntry(mCert, this.conf.pair && this.conf.pair.pub))) {
throw constants.ERRORS.SANDBOX_FOR_CERT_IS_FULL;
}
await this.dal.registerNewCertification(new Certification(mCert));
await this.dal.registerNewCertification(mCert)
this.logger.info('✔ CERT %s', mCert.from);
} else {
throw constants.ERRORS.ALREADY_UP_TO_DATE;
}
} catch (e) {
cert.err = e
anErr = e
}
}
if (cert.err) {
if (anErr) {
if (idtyAbsorbed) {
await this.dal.idtyDAL.deleteByHash(targetHash)
}
const err = cert.err
const err = anErr
const errMessage = (err.uerr && err.uerr.message) || err.message || err
this.logger.info('✘ CERT %s %s', cert.from, errMessage);
throw cert.err;
throw anErr;
}
return cert;
})
......
......@@ -10,7 +10,7 @@ const parsers = require('duniter-common').parsers;
const keyring = common.keyring;
const rawer = common.rawer;
const constants = require('../../../app/lib/constants');
const Certification = require('../../../app/lib/entity/certification');
const CertificationDTO = require('../../../app/lib/dto/CertificationDTO').CertificationDTO
const Membership = require('../../../app/lib/entity/membership');
const RevocationDTO = require('../../../app/lib/dto/RevocationDTO').RevocationDTO
const Peer = require('../../../app/lib/entity/peer');
......@@ -83,7 +83,7 @@ function User (uid, options, node) {
_.extend(cert, overrideProps || {});
const rawCert = rawer.getOfficialCertification(cert);
cert.sig = keyring.Key(pub, sec).signSync(rawCert, sec);
return Certification.statics.fromJSON(cert);
return CertificationDTO.fromJSONObject(cert);
});
this.cert = (user, fromServer, toServer) => co(function*() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment