diff --git a/app/lib/blockchain/DuniterBlockchain.ts b/app/lib/blockchain/DuniterBlockchain.ts index 92b419a626901f8510474b3b902486c840fabbd9..a9827549263aeac69940d3eb26abd47da694cdd0 100644 --- a/app/lib/blockchain/DuniterBlockchain.ts +++ b/app/lib/blockchain/DuniterBlockchain.ts @@ -353,7 +353,7 @@ export class DuniterBlockchain { static async revertBlock(number:number, hash:string, dal:FileDAL) { const blockstamp = [number, hash].join('-'); - const block = await dal.getBlockByBlockstampOrNull(blockstamp) + const block = await dal.getAbsoluteValidBlockInForkWindow(number, hash) if (!block) { throw DataErrors[DataErrors.BLOCK_TO_REVERT_NOT_FOUND] @@ -387,7 +387,7 @@ export class DuniterBlockchain { await dal.sindexDAL.removeBlock(blockstamp); // Then: normal updates - const previousBlock = await dal.getBlock(number - 1); + const previousBlock = await dal.getFullBlockOf(number - 1) // Set the block as SIDE block (equivalent to removal from main branch) await dal.blockDAL.setSideBlock(number, previousBlock); diff --git a/app/lib/blockchain/Switcher.ts b/app/lib/blockchain/Switcher.ts index 9d9a7979a367741c76fd776c53fc295620a08322..083aae273a887e55cd40b75e9a8928b250b97048 100644 --- a/app/lib/blockchain/Switcher.ts +++ b/app/lib/blockchain/Switcher.ts @@ -26,7 +26,7 @@ export interface SwitcherDao<T extends SwitchBlock> { getCurrent(): Promise<T|null> getPotentials(numberStart:number, timeStart:number, maxNumber:number): Promise<T[]> getBlockchainBlock(number:number, hash:string): Promise<T|null> - getSandboxBlock(number:number, hash:string): Promise<T|null> + getAbsoluteBlockInForkWindow(number:number, hash:string): Promise<T|null> revertTo(number:number): Promise<T[]> addBlock(block:T): Promise<T> } @@ -126,7 +126,7 @@ export class Switcher<T extends SwitchBlock> { commonRootFound = true } else { // Have a look in sandboxes - previous = await this.dao.getSandboxBlock(previousNumber, previousHash) + previous = await this.dao.getAbsoluteBlockInForkWindow(previousNumber, previousHash) if (previous) { knownForkBlocks[BlockDTO.fromJSONObject(previous).blockstamp] = true const alreadyKnownInvalidBlock = this.invalidForks.indexOf([previous.number, previous.hash].join('-')) !== -1 diff --git a/app/lib/common/Tristamp.ts b/app/lib/common/Tristamp.ts new file mode 100644 index 0000000000000000000000000000000000000000..4ea9d85459297ba061b9149dc84555049f80ebc7 --- /dev/null +++ b/app/lib/common/Tristamp.ts @@ -0,0 +1,5 @@ +export interface Tristamp { + number: number + hash: string + medianTime: number +} diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index c0ea819094a21e5029badc3c4f4bbc2a13d4f72c..fea640891fd65d6cc3cefddc38871c94b5a3bd75 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -65,6 +65,7 @@ import {PeerDAO} from "./indexDAL/abstract/PeerDAO" import {LokiPeer} from "./indexDAL/loki/LokiPeer" import {DBTx} from "../db/DBTx" import {DBWallet} from "../db/DBWallet" +import {Tristamp} from "../common/Tristamp" const fs = require('fs') const path = require('path') @@ -220,61 +221,67 @@ export class FileDAL { return this.peerDAL.getPeersWithEndpointsLike('WS2P') } - async getBlock(number:number): Promise<DBBlock|null> { - const block = await this.blockDAL.getBlock(number) - return block || null; + getAbsoluteBlockInForkWindowByBlockstamp(blockstamp:string) { + if (!blockstamp) throw "Blockstamp is required to find the block"; + const sp = blockstamp.split('-'); + const number = parseInt(sp[0]); + const hash = sp[1]; + return this.getAbsoluteBlockInForkWindow(number, hash) + } + + getAbsoluteValidBlockInForkWindowByBlockstamp(blockstamp:string) { + if (!blockstamp) throw "Blockstamp is required to find the block"; + const sp = blockstamp.split('-'); + const number = parseInt(sp[0]); + const hash = sp[1]; + return this.getAbsoluteValidBlockInForkWindow(number, hash) } async getBlockWeHaveItForSure(number:number): Promise<DBBlock> { return (await this.blockDAL.getBlock(number)) as DBBlock } - getAbsoluteBlockByNumberAndHash(number:number, hash:string) { - return this.blockDAL.getAbsoluteBlock(number, hash) + async getFullBlockOf(number: number): Promise<DBBlock|null> { + // TODO + return this.blockDAL.getBlock(number) } - getAbsoluteBlockByBlockstamp(blockstamp:string) { - if (!blockstamp) throw "Blockstamp is required to find the block" - const sp = blockstamp.split('-') - const number = parseInt(sp[0]) - const hash = sp[1] - return this.getAbsoluteBlockByNumberAndHash(number, hash) + async getBlockstampOf(number: number): Promise<string|null> { + // TODO + const block = await this.blockDAL.getBlock(number) + if (block) { + return [block.number, block.hash].join('-') + } + return null } - getBlockByBlockstampOrNull(blockstamp:string) { - if (!blockstamp) throw "Blockstamp is required to find the block"; - const sp = blockstamp.split('-'); - const number = parseInt(sp[0]); - const hash = sp[1]; - return this.getBlockByNumberAndHashOrNull(number, hash); + async getTristampOf(number: number): Promise<Tristamp|null> { + // TODO + return this.blockDAL.getBlock(number) } - getBlockByBlockstamp(blockstamp:string) { - if (!blockstamp) throw "Blockstamp is required to find the block"; - const sp = blockstamp.split('-'); - const number = parseInt(sp[0]); - const hash = sp[1]; - return this.getBlockByNumberAndHash(number, hash); + async existsAbsoluteBlockInForkWindow(number:number, hash:string): Promise<boolean> { + // TODO + return !!(await this.blockDAL.getAbsoluteBlock(number, hash)) } - async getBlockByNumberAndHash(number:number, hash:string): Promise<DBBlock> { - try { - const block = await this.getBlock(number); - if (!block || block.hash != hash) - throw "Not found"; - else - return block; - } catch (err) { - throw 'Block ' + [number, hash].join('-') + ' not found'; - } + async getAbsoluteBlockInForkWindow(number:number, hash:string): Promise<DBBlock|null> { + // TODO + return this.blockDAL.getAbsoluteBlock(number, hash) } - async getBlockByNumberAndHashOrNull(number:number, hash:string): Promise<DBBlock|null> { - try { - return await this.getBlockByNumberAndHash(number, hash) - } catch (e) { - return null; + async getAbsoluteValidBlockInForkWindow(number:number, hash:string): Promise<DBBlock|null> { + // TODO: blocks that are not forks + const block = await this.blockDAL.getAbsoluteBlock(number, hash) + if (block && !block.fork) { + return block } + return null + } + + getAbsoluteBlockByNumberAndHash(number:number, hash:string): Promise<DBBlock|null> { + // TODO: first, look at fork window, and then fallback on archives + return this.blockDAL.getAbsoluteBlock(number, hash) } async existsNonChainableLink(from:string, vHEAD_1:DBHead, sigStock:number) { @@ -302,15 +309,11 @@ export class FileDAL { } getPromoted(number:number) { - return this.getBlock(number) + return this.getFullBlockOf(number) } // Block - getRootBlock() { - return this.getBlock(0) - } - getPotentialRootBlocks() { return this.blockDAL.getPotentialRoots() } @@ -728,9 +731,9 @@ export class FileDAL { return _(pending).sortBy((ms:any) => -ms.number)[0]; } - async findNewcomers(blockMedianTime = 0) { + async findNewcomers(blockMedianTime = 0): Promise<DBMembership[]> { const pending = await this.msDAL.getPendingIN() - const mss = await Promise.all(pending.map(async (p:any) => { + const mss: DBMembership[] = await Promise.all<DBMembership>(pending.map(async (p:any) => { const reduced = await this.mindexDAL.getReducedMS(p.issuer) if (!reduced || !reduced.chainable_on || blockMedianTime >= reduced.chainable_on || blockMedianTime < constants.TIME_TO_TURN_ON_BRG_107) { return p @@ -738,12 +741,12 @@ export class FileDAL { return null })) return _.chain(mss) - .filter((ms:any) => ms) - .sortBy((ms:any) => -ms.sigDate) + .filter((ms:DBMembership) => ms) + .sortBy((ms:DBMembership) => -ms.blockNumber) .value() } - async findLeavers(blockMedianTime = 0) { + async findLeavers(blockMedianTime = 0): Promise<DBMembership[]> { const pending = await this.msDAL.getPendingOUT(); const mss = await Promise.all(pending.map(async (p:any) => { const reduced = await this.mindexDAL.getReducedMS(p.issuer) @@ -753,8 +756,8 @@ export class FileDAL { return null })) return _.chain(mss) - .filter((ms:any) => ms) - .sortBy((ms:any) => -ms.sigDate) + .filter((ms:DBMembership) => ms) + .sortBy((ms:DBMembership) => -ms.blockNumber) .value(); } @@ -984,7 +987,7 @@ export class FileDAL { async saveTxsInFiles(txs:TransactionDTO[], block_number:number, medianTime:number) { return Promise.all(txs.map(async (tx) => { const sp = tx.blockstamp.split('-'); - const basedBlock = (await this.getBlockByNumberAndHash(parseInt(sp[0]), sp[1])) as DBBlock + const basedBlock = (await this.getAbsoluteBlockByNumberAndHash(parseInt(sp[0]), sp[1])) as DBBlock tx.blockstampTime = basedBlock.medianTime; const txEntity = TransactionDTO.fromJSONObject(tx) txEntity.computeAllHashes(); diff --git a/app/lib/dal/indexDAL/loki/LokiBlockchain.ts b/app/lib/dal/indexDAL/loki/LokiBlockchain.ts index 80d37f88c1c116c6b6e6a0d7b8dbb393fb858d7e..105e555e450c5d2f9273a7f85168f3ca7b6a20bf 100644 --- a/app/lib/dal/indexDAL/loki/LokiBlockchain.ts +++ b/app/lib/dal/indexDAL/loki/LokiBlockchain.ts @@ -139,7 +139,7 @@ export class LokiBlockchain extends LokiIndex<DBBlock> implements BlockchainDAO number: { $between: [numberStart, maxNumber] }, medianTime: { $gte: medianTimeStart } }) - .simplesort('number') + .simplesort('number', true) .data() } diff --git a/app/lib/indexer.ts b/app/lib/indexer.ts index cff677eb08c51dfdaf239750a601acb333cec0a7..9f4e720f6527903afb6c15c44208fe0f43b95f0e 100644 --- a/app/lib/indexer.ts +++ b/app/lib/indexer.ts @@ -24,9 +24,9 @@ import {CommonConstants} from "./common-libs/constants" import {MembershipDTO} from "./dto/MembershipDTO" import {UnlockMetadata} from "./common-libs/txunlock" import {FileDAL} from "./dal/fileDAL" -import {DataErrors} from "./common-libs/errors" import {DBBlock} from "./db/DBBlock" import {DBWallet} from "./db/DBWallet" +import {Tristamp} from "./common/Tristamp" const _ = require('underscore'); @@ -951,7 +951,7 @@ export class Indexer { if (HEAD.number == 0 && ENTRY.created_on == '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855') { ENTRY.age = 0; } else { - let ref = await dal.getBlockByBlockstamp(ENTRY.created_on as string); + let ref = await dal.getAbsoluteValidBlockInForkWindowByBlockstamp(ENTRY.created_on as string); if (ref && blockstamp(ref.number, ref.hash) == ENTRY.created_on) { ENTRY.age = HEAD_1.medianTime - ref.medianTime; } else { @@ -1195,7 +1195,7 @@ export class Indexer { if (HEAD.number == 0 && ENTRY.created_on == '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855') { ENTRY.age = 0; } else { - let ref = await dal.getBlockByBlockstamp(ENTRY.created_on as string); + let ref = await dal.getAbsoluteValidBlockInForkWindowByBlockstamp(ENTRY.created_on as string); if (ref && blockstamp(ref.number, ref.hash) == ENTRY.created_on) { ENTRY.age = HEAD_1.medianTime - ref.medianTime; } else { @@ -1211,7 +1211,7 @@ export class Indexer { if (HEAD.number == 0 && ENTRY.created_on == '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855') { ENTRY.age = 0; } else { - let ref = ENTRY.created_on_ref || await dal.getBlockByBlockstamp(ENTRY.created_on) + let ref = ENTRY.created_on_ref || await dal.getAbsoluteValidBlockInForkWindowByBlockstamp(ENTRY.created_on) if (ref && blockstamp(ref.number, ref.hash) == ENTRY.created_on) { ENTRY.created_on_ref = ref ENTRY.age = HEAD_1.medianTime - ref.medianTime; @@ -1228,7 +1228,7 @@ export class Indexer { if (HEAD.number == 0) { ENTRY.age = 0; } else { - let ref = ENTRY.created_on_ref || await dal.getBlock(ENTRY.created_on) + let ref = ENTRY.created_on_ref || await dal.getTristampOf(ENTRY.created_on) if (ref) { if (!ENTRY.created_on_ref) { ENTRY.created_on_ref = ref @@ -1811,7 +1811,7 @@ export class Indexer { if (HEAD.number == 0) { basedBlock = HEAD; } else { - basedBlock = MS.created_on_ref || await dal.getBlockByBlockstamp(MS.created_on) + basedBlock = MS.created_on_ref || await dal.getAbsoluteValidBlockInForkWindowByBlockstamp(MS.created_on) || basedBlock } if (MS.expires_on === null) { MS.expires_on = 0 @@ -1832,7 +1832,7 @@ export class Indexer { if (HEAD.number == 0) { basedBlock = HEAD; } else { - basedBlock = CERT.created_on_ref || ((await dal.getBlock(CERT.created_on)) as DBBlock) + basedBlock = CERT.created_on_ref || ((await dal.getTristampOf(CERT.created_on)) as DBBlock) // We are sure at this point in the rules } CERT.expires_on += basedBlock.medianTime; } @@ -2043,18 +2043,15 @@ async function checkCertificationIsValid (block: BlockDTO, cert: CindexEntry, fi throw Error('Number must be 0 for root block\'s certifications'); } else { try { - let basedBlock = new BlockDTO() - basedBlock.hash = constants.SPECIAL_HASH - + let basedBlock:Tristamp|null = { + number: 0, + hash: constants.SPECIAL_HASH, + medianTime: 0 + } if (block.number != 0) { - try { - const b = await dal.getBlock(cert.created_on) - if (!b) { - throw Error(DataErrors[DataErrors.CERT_BASED_ON_UNKNOWN_BLOCK]) - } - basedBlock = BlockDTO.fromJSONObject(b) - } catch (e) { - throw Error('Certification based on an unexisting block'); + basedBlock = await dal.getTristampOf(cert.created_on) + if (!basedBlock) { + throw Error('Certification based on an unexisting block') } } const idty = await findIdtyFunc(block, cert.receiver, dal) diff --git a/app/lib/other_constants.ts b/app/lib/other_constants.ts index 63162b599a680e000c9798f7b6f6397c4d6c25ae..d10528e99d6325e1c5fe5ced474a1164f9795cfc 100644 --- a/app/lib/other_constants.ts +++ b/app/lib/other_constants.ts @@ -13,7 +13,7 @@ export const OtherConstants = { - MUTE_LOGS_DURING_UNIT_TESTS: true, + MUTE_LOGS_DURING_UNIT_TESTS: false, SQL_TRACES: false, BC_EVENT: { diff --git a/app/lib/rules/global_rules.ts b/app/lib/rules/global_rules.ts index 56c1c8843e4b351f802ea38784fdc957017a9133..dbd0b858a05c2699b29edd8ac3cc83466e97234e 100644 --- a/app/lib/rules/global_rules.ts +++ b/app/lib/rules/global_rules.ts @@ -23,6 +23,7 @@ import {IdentityDTO} from "../dto/IdentityDTO" import {hashf} from "../common" import {Indexer} from "../indexer" import {DBTx} from "../db/DBTx" +import {Tristamp} from "../common/Tristamp" const _ = require('underscore') @@ -83,7 +84,7 @@ export const GLOBAL_RULES_FUNCTIONS = { // Because the window rule does not apply on initial certifications if (current && idty.buid != constants.SPECIAL_BLOCK) { // From DUP 0.5: we fully check the blockstamp - const basedBlock = await dal.getBlockByBlockstamp(idty.buid); + const basedBlock = await dal.getAbsoluteValidBlockInForkWindowByBlockstamp(idty.buid) || { medianTime: 0 } // Check if writable let duration = current.medianTime - basedBlock.medianTime if (duration > conf.idtyWindow) { @@ -224,7 +225,7 @@ export const GLOBAL_RULES_HELPERS = { checkTxBlockStamp: async (tx:TransactionDTO, dal:FileDAL) => { const number = parseInt(tx.blockstamp.split('-')[0]) const hash = tx.blockstamp.split('-')[1]; - const basedBlock = await dal.getBlockByNumberAndHashOrNull(number, hash); + const basedBlock = await dal.getAbsoluteValidBlockInForkWindow(number, hash) if (!basedBlock) { throw "Wrong blockstamp for transaction"; } @@ -253,11 +254,9 @@ async function checkMSTarget (ms:any, block:any, conf:ConfDTO, dal:FileDAL) { else if (block.number == 0) { return null; // Valid for root block } else { - let basedBlock; - try { - basedBlock = await dal.getBlockByNumberAndHash(ms.number, ms.fpr); - } catch (e) { - throw Error('Membership based on an unexisting block'); + const basedBlock = await dal.getAbsoluteValidBlockInForkWindow(ms.number, ms.fpr) + if (!basedBlock) { + throw Error('Membership based on an unexisting block') } let current = await dal.getCurrentBlockOrNull(); if (current && current.medianTime > basedBlock.medianTime + conf.msValidity) { @@ -276,13 +275,14 @@ async function checkCertificationShouldBeValid (block:{ number:number, currency: if (block.number == 0 && cert.block_number != 0) { throw Error('Number must be 0 for root block\'s certifications'); } else { - let basedBlock:any = { - hash: constants.SPECIAL_HASH - }; + let basedBlock:Tristamp|null = { + number: 0, + hash: constants.SPECIAL_HASH, + medianTime: 0 + } if (block.number != 0) { - try { - basedBlock = await dal.getBlock(cert.block_number); - } catch (e) { + basedBlock = await dal.getTristampOf(cert.block_number) + if (!basedBlock) { throw Error('Certification based on an unexisting block'); } try { diff --git a/app/modules/bma/lib/controllers/wot.ts b/app/modules/bma/lib/controllers/wot.ts index 6528c5472524bc30955bb07bed323faf033de83d..a19f44364f93791edf0d7fa692be316d63ec6aec 100644 --- a/app/modules/bma/lib/controllers/wot.ts +++ b/app/modules/bma/lib/controllers/wot.ts @@ -31,6 +31,7 @@ import { } from "../dtos"; import {IdentityDTO} from "../../../../lib/dto/IdentityDTO" import {FullIindexEntry} from "../../../../lib/indexer" +import {DBMembership} from "../../../../lib/dal/sqliteDAL/MembershipDAL" const _ = require('underscore'); const http2raw = require('../http2raw'); @@ -276,14 +277,14 @@ export class WOTBinding extends AbstractController { async pendingMemberships(): Promise<HttpMembershipList> { const memberships = await this.server.dal.findNewcomers(); const json = { - memberships: memberships.map((ms:any) => { + memberships: memberships.map((ms:DBMembership) => { return { pubkey: ms.issuer, uid: ms.userid, - version: ms.version || 0, + version: 10, currency: this.server.conf.currency, membership: ms.membership, - blockNumber: parseInt(ms.blockNumber), + blockNumber: ms.blockNumber, blockHash: ms.blockHash, written: (!ms.written_number && ms.written_number !== 0) ? null : ms.written_number }; diff --git a/app/modules/bma/lib/dtos.ts b/app/modules/bma/lib/dtos.ts index a048dfcce52a3434b664571279dd9128209232af..533600a6a350f2e85aa6575a8cac4bac6508e006 100644 --- a/app/modules/bma/lib/dtos.ts +++ b/app/modules/bma/lib/dtos.ts @@ -151,18 +151,16 @@ export const MembershipList = { }; export interface HttpMembershipList { - memberships: [ - { - pubkey: string - uid: string - version: number - currency: string - membership: string - blockNumber: number - blockHash: string - written: number - } - ] + memberships: { + pubkey: string + uid: string + version: number + currency: string + membership: string + blockNumber: number + blockHash: string + written: number|null + }[] } export const TransactionOfBlock = { diff --git a/app/modules/crawler/lib/sync.ts b/app/modules/crawler/lib/sync.ts index fbb7432d132d5fed6d286b4605feb14a1c3496c4..b0a1e14ad1e6d890e24ae1ffd88fe5c09cae369f 100644 --- a/app/modules/crawler/lib/sync.ts +++ b/app/modules/crawler/lib/sync.ts @@ -313,7 +313,7 @@ export class Synchroniser extends stream.Duplex { } // Save currency parameters given by root block - const rootBlock = await this.server.dal.getBlock(0); + const rootBlock = await this.server.dal.getFullBlockOf(0) await this.BlockchainService.saveParametersForRootBlock(BlockDTO.fromJSONObject(rootBlock)) this.server.dal.blockDAL.cleanCache(); diff --git a/app/modules/prover/lib/blockGenerator.ts b/app/modules/prover/lib/blockGenerator.ts index f180c283ed65c6f71bf0102ff0e7c27c09538ce8..7e9d229ec2630a849be853f1c55cbdb9fba62e5c 100644 --- a/app/modules/prover/lib/blockGenerator.ts +++ b/app/modules/prover/lib/blockGenerator.ts @@ -174,7 +174,7 @@ export class BlockGenerator { leave.idHash = (hashf(ms.userid + ms.certts + ms.issuer) + "").toUpperCase(); let block; if (current) { - block = await this.dal.getBlock(ms.number); + block = await this.dal.getAbsoluteValidBlockInForkWindowByBlockstamp(ms.block) } else { block = {}; @@ -283,7 +283,7 @@ export class BlockGenerator { for (const ms of memberships) { try { if (ms.block !== CommonConstants.SPECIAL_BLOCK) { - let msBasedBlock = await this.dal.getBlockByBlockstampOrNull(ms.block); + let msBasedBlock = await this.dal.getAbsoluteValidBlockInForkWindow(ms.blockNumber, ms.blockHash) if (!msBasedBlock) { throw constants.ERRORS.BLOCKSTAMP_DOES_NOT_MATCH_A_BLOCK; } @@ -366,7 +366,7 @@ export class BlockGenerator { throw constants.ERRORS.TOO_OLD_IDENTITY; } else if (!identity.wasMember && identity.buid != CommonConstants.SPECIAL_BLOCK) { - const idtyBasedBlock = await this.dal.getBlock(parseInt(identity.buid.split('-')[0])) + const idtyBasedBlock = await this.dal.getTristampOf(parseInt(identity.buid.split('-')[0])) if (!current || !idtyBasedBlock) { throw Error(DataErrors[DataErrors.CANNOT_DETERMINATE_IDENTITY_AGE]) } @@ -397,7 +397,7 @@ export class BlockGenerator { const certifiers = []; for (const cert of certs) { try { - const basedBlock = await this.dal.getBlock(cert.block_number); + const basedBlock = await this.dal.getTristampOf(cert.block_number) if (!basedBlock) { throw 'Unknown timestamp block for identity'; } @@ -734,7 +734,7 @@ class NextBlockGenerator implements BlockGeneratorInterface { if (targetIdty) { const certSig = cert.sig; // Do not rely on certification block UID, prefer using the known hash of the block by its given number - const targetBlock = await this.dal.getBlock(cert.block_number); + const targetBlock = await this.dal.getTristampOf(cert.block_number) // Check if writable let duration = current && targetBlock ? current.medianTime - targetBlock.medianTime : 0; if (targetBlock && duration <= this.conf.sigWindow) { diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index 36603358ddfe57a9319811a22d640d8ec5e3828a..2572225fa4dcdbd42020b06c07cf74e324da31bc 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -257,7 +257,7 @@ export class WS2PCluster { } if (!exists) { // Do we have this block in the DB? - exists = !!(await this.server.dal.getAbsoluteBlockByBlockstamp(blockstamp)) + exists = !!(await this.server.dal.getAbsoluteBlockInForkWindowByBlockstamp(blockstamp)) } // Update the last time it was checked this.blockstampsCache[blockstamp] = Date.now() diff --git a/app/modules/ws2p/lib/impl/WS2PReqMapperByServer.ts b/app/modules/ws2p/lib/impl/WS2PReqMapperByServer.ts index 90c5188de7b19434cfa04000750cb2b34d61bff0..ae805fdc2d5a5abe34c3027940db285ea03d9504 100644 --- a/app/modules/ws2p/lib/impl/WS2PReqMapperByServer.ts +++ b/app/modules/ws2p/lib/impl/WS2PReqMapperByServer.ts @@ -15,7 +15,6 @@ import {IdentityForRequirements} from './../../../../service/BlockchainService'; import {Server} from "../../../../../server" import {WS2PReqMapper} from "../interface/WS2PReqMapper" import {BlockDTO} from "../../../../lib/dto/BlockDTO" -import {IindexEntry} from '../../../../lib/indexer'; import {DBBlock} from "../../../../lib/db/DBBlock" export class WS2PReqMapperByServer implements WS2PReqMapper { @@ -27,7 +26,7 @@ export class WS2PReqMapperByServer implements WS2PReqMapper { } async getBlock(number: number): Promise<BlockDTO> { - return Promise.resolve(BlockDTO.fromJSONObject(await this.server.dal.getBlock(number))) + return Promise.resolve(BlockDTO.fromJSONObject(await this.server.dal.getFullBlockOf(number))) } async getBlocks(count: number, from: number): Promise<BlockDTO[]> { diff --git a/app/service/BlockchainService.ts b/app/service/BlockchainService.ts index 4e4e29e8d64b0c388b428b4db2c168e30f938961..63b6c89e688773bde85ba4cb761f664da62f17e9 100644 --- a/app/service/BlockchainService.ts +++ b/app/service/BlockchainService.ts @@ -89,16 +89,14 @@ export class BlockchainService extends FIFOService { } async getBlockchainBlock(number: number, hash: string): Promise<BlockDTO | null> { - try { - return BlockDTO.fromJSONObject(await this.bcService.dal.getBlockByNumberAndHash(number, hash)) - } catch (e) { - return null - } + const b = await this.bcService.dal.getAbsoluteValidBlockInForkWindow(number, hash) + if (!b) return null + return BlockDTO.fromJSONObject(b) } - async getSandboxBlock(number: number, hash: string): Promise<BlockDTO | null> { - const block = await this.bcService.dal.getAbsoluteBlockByNumberAndHash(number, hash) - if (block && block.fork) { + async getAbsoluteBlockInForkWindow(number: number, hash: string): Promise<BlockDTO | null> { + const block = await this.bcService.dal.getAbsoluteBlockInForkWindow(number, hash) + if (block) { return BlockDTO.fromJSONObject(block) } else { return null @@ -198,7 +196,7 @@ export class BlockchainService extends FIFOService { throw CommonConstants.ERRORS.OUT_OF_FORK_WINDOW } } - const absolute = await this.dal.getAbsoluteBlockByNumberAndHash(parseInt(obj.number), obj.hash) + const absolute = await this.dal.existsAbsoluteBlockInForkWindow(parseInt(obj.number), obj.hash) if (!absolute) { // Save the block in the sandbox await this.mainContext.addSideBlock(dto); @@ -350,8 +348,8 @@ export class BlockchainService extends FIFOService { const currentMSN = currentMembership ? parseInt(currentMembership.created_on) : -1; if (currentMSN >= 0) { if (join.identity.member) { - const msBlock = await this.dal.getBlock(currentMSN); - if (msBlock && msBlock.medianTime) { // special case for block #0 + const msBlock = await this.dal.getTristampOf(currentMSN) + if (msBlock) { // special case for block #0 expiresMS = Math.max(0, (msBlock.medianTime + this.conf.msValidity - currentTime)); } else { @@ -364,8 +362,8 @@ export class BlockchainService extends FIFOService { // Expiration of pending membership const lastJoin = await this.dal.lastJoinOfIdentity(idty.hash); if (lastJoin) { - const msBlock = await this.dal.getBlock(lastJoin.blockNumber); - if (msBlock && msBlock.medianTime) { // Special case for block#0 + const msBlock = await this.dal.getTristampOf(lastJoin.blockNumber) + if (msBlock) { // Special case for block#0 expiresPending = Math.max(0, (msBlock.medianTime + this.conf.msValidity - currentTime)); } else { @@ -417,7 +415,7 @@ export class BlockchainService extends FIFOService { const certsFromCerts = []; const certs = newCerts[newcomer] || []; for (const cert of certs) { - const block = await this.dal.getBlock(cert.block_number); + const block = await this.dal.getTristampOf(cert.block_number) if (block) { certsFromCerts.push({ from: cert.from, diff --git a/app/service/IdentityService.ts b/app/service/IdentityService.ts index f4e5a2b2fdf8e0e8ae051794dbcece4587e4ee31..dba4089fc4d5d858dd36b3c26f9a743f3926c05a 100644 --- a/app/service/IdentityService.ts +++ b/app/service/IdentityService.ts @@ -25,6 +25,7 @@ import {verify} from "../lib/common-libs/crypto/keyring" import {FIFOService} from "./FIFOService" import {MindexEntry} from "../lib/indexer" import {DataErrors} from "../lib/common-libs/errors" +import {Tristamp} from "../lib/common/Tristamp" "use strict"; const constants = require('../lib/constants'); @@ -141,7 +142,7 @@ export class IdentityService extends FIFOService { if (idty.buid == '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855' && current) { throw constants.ERRORS.BLOCKSTAMP_DOES_NOT_MATCH_A_BLOCK; } else if (current) { - let basedBlock = await this.dal.getBlockByBlockstamp(idty.buid); + let basedBlock = await this.dal.getAbsoluteValidBlockInForkWindowByBlockstamp(idty.buid); if (!basedBlock) { throw constants.ERRORS.BLOCKSTAMP_DOES_NOT_MATCH_A_BLOCK; } @@ -199,11 +200,12 @@ export class IdentityService extends FIFOService { } if (!anErr) { try { - let basedBlock: { number:number, hash:string, medianTime?:number }|null = await this.dal.getBlock(cert.block_number); + let basedBlock: Tristamp|null = await this.dal.getTristampOf(cert.block_number); if (cert.block_number == 0 && !basedBlock) { basedBlock = { number: 0, - hash: 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855' + hash: 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', + medianTime: 0 }; } if (!basedBlock) { @@ -217,7 +219,7 @@ export class IdentityService extends FIFOService { block_hash: basedBlock.hash, target: targetHash, to: idty.pubkey, - expires_on: (basedBlock.medianTime || 0) + this.conf.sigWindow, + expires_on: basedBlock.medianTime + this.conf.sigWindow, linked: false, written: false, expired: false, diff --git a/app/service/PeeringService.ts b/app/service/PeeringService.ts index ec90021f590af93888e9cb1d4e55652c5b3021f1..4187ef593825c12d223da7f46988ae7d4fea1ac2 100644 --- a/app/service/PeeringService.ts +++ b/app/service/PeeringService.ts @@ -107,7 +107,7 @@ export class PeeringService { thePeer.statusTS = 0; thePeer.status = 'UP'; } else { - block = await this.dal.getBlockByNumberAndHashOrNull(blockNumber, blockHash); + block = await this.dal.getAbsoluteValidBlockInForkWindow(blockNumber, blockHash) if (!block && makeCheckings) { throw constants.ERROR.PEER.UNKNOWN_REFERENCE_BLOCK; } else if (!block) { @@ -233,12 +233,12 @@ export class PeeringService { } // The number cannot be superior to current block minBlock = Math.min(minBlock, current ? current.number : minBlock); - let targetBlock = await this.server.dal.getBlock(minBlock); + const targetBlockstamp: string|null = await this.server.dal.getBlockstampOf(minBlock) const p2:any = { version: constants.DOCUMENTS_VERSION, currency: currency, pubkey: this.selfPubkey, - block: targetBlock ? [targetBlock.number, targetBlock.hash].join('-') : constants.PEER.SPECIAL_BLOCK, + block: targetBlockstamp ? targetBlockstamp : constants.PEER.SPECIAL_BLOCK, endpoints: _.uniq(endpointsToDeclare) }; const raw2 = dos2unix(PeerDTO.fromJSONObject(p2).getRaw()); diff --git a/test/dal/dal.js b/test/dal/dal.js index f28674f7d6db41aaba53b3de7a07c19d11547606..302879a1309fdc3eed06996eb873aea056d84aa7 100644 --- a/test/dal/dal.js +++ b/test/dal/dal.js @@ -153,7 +153,7 @@ describe("DAL", function(){ it('should be able to save a Block', function(){ return co(function *() { yield fileDAL.saveBlock(_.extend({ fork: false }, mocks.block0)); - let block = yield fileDAL.getBlock(0); + let block = yield fileDAL.getFullBlockOf(0); block.should.have.property('hash').equal(mocks.block0.hash); block.should.have.property('signature').equal(mocks.block0.signature); block.should.have.property('version').equal(mocks.block0.version); diff --git a/test/fast/fork-resolution-3-3.ts b/test/fast/fork-resolution-3-3.ts index 10e37d1fe9c14e68f2a5221894300e2825e01efd..1b63fa6fb677db9d1c7d2c5b3cf0016ad11d3b3e 100644 --- a/test/fast/fork-resolution-3-3.ts +++ b/test/fast/fork-resolution-3-3.ts @@ -206,7 +206,7 @@ class TestingSwitcherDao implements SwitcherDao<Block> { } - async getSandboxBlock(number: number, hash: string): Promise<Block | any> { + async getAbsoluteBlockInForkWindow(number: number, hash: string): Promise<Block | any> { return this.sbx.getBlock(number, hash) } diff --git a/test/integration/lookup.js b/test/integration/lookup.js index 3ce8d834f1093fdd4cdae8a57747cf52db26ef61..39d776da2fa8c13a03fbc90ed9c068a326ef9f95 100644 --- a/test/integration/lookup.js +++ b/test/integration/lookup.js @@ -100,7 +100,7 @@ describe("Lookup identity grouping", () => { res.should.have.property('memberships').length(2); res.memberships[0].should.have.property('pubkey').equal('DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'); res.memberships[0].should.have.property('uid').equal('tic1'); - res.memberships[0].should.have.property('version').equal(0); + res.memberships[0].should.have.property('version').equal(10); res.memberships[0].should.have.property('currency').equal('bb'); res.memberships[0].should.have.property('membership').equal('IN'); res.memberships[0].should.have.property('blockNumber').equal(0); diff --git a/test/integration/register-fork-blocks.js b/test/integration/register-fork-blocks.js index 7e1c803ddf11bea83fb5301ca37e0edcd5364d52..e905ed939ec39ec3a2d7bfad99af231a4b780db4 100644 --- a/test/integration/register-fork-blocks.js +++ b/test/integration/register-fork-blocks.js @@ -217,18 +217,18 @@ describe("Fork blocks", function() { yield s1.expect('/blockchain/branches', (res) => { assert.equal(res.blocks.length, 3) assert.equal(res.blocks[0].number, 3) - assert.equal(res.blocks[0].hash, '9A0FA1F0899124444ADC5B2C0AB66AC5B4303A0D851BED2E7382BB57E10AA2C5') + assert.equal(res.blocks[0].hash, '2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B') // This is s2 fork! assert.equal(res.blocks[1].number, 3) - assert.equal(res.blocks[1].hash, '2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B') // This is s2 fork! + assert.equal(res.blocks[1].hash, '9A0FA1F0899124444ADC5B2C0AB66AC5B4303A0D851BED2E7382BB57E10AA2C5') assert.equal(res.blocks[2].number, 8) assert.equal(res.blocks[2].hash, 'B8D2AA2A5556F7A2837FB4B881FCF50595F855D0BF8F71C0B432E27216BBA40B') }) yield s2.expect('/blockchain/branches', (res) => { assert.equal(res.blocks.length, 3) assert.equal(res.blocks[0].number, 3) - assert.equal(res.blocks[0].hash, '9A0FA1F0899124444ADC5B2C0AB66AC5B4303A0D851BED2E7382BB57E10AA2C5') + assert.equal(res.blocks[0].hash, '2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B') // This is s2 fork! assert.equal(res.blocks[1].number, 3) - assert.equal(res.blocks[1].hash, '2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B') // This is s2 fork! + assert.equal(res.blocks[1].hash, '9A0FA1F0899124444ADC5B2C0AB66AC5B4303A0D851BED2E7382BB57E10AA2C5') assert.equal(res.blocks[2].number, 8) assert.equal(res.blocks[2].hash, 'B8D2AA2A5556F7A2837FB4B881FCF50595F855D0BF8F71C0B432E27216BBA40B') })