Skip to content
Snippets Groups Projects
Commit 5bedff1e authored by Cédric Moreau's avatar Cédric Moreau
Browse files

[fix] dal: `getBlocks` function was broken if the chunk was targeting the archives

parent 78a9bc66
Branches
No related tags found
No related merge requests found
......@@ -412,8 +412,25 @@ export class FileDAL {
return this.blockDAL.getCountOfBlocksIssuedBy(issuer)
}
getBlocksBetween (start:number, end:number) {
return this.blockDAL.getBlocks(Math.max(0, start), end)
async getBlocksBetween (start:number, end:number) {
start = Math.max(0, start)
end= Math.max(0, end)
const blocks = await this.blockDAL.getBlocks(Math.max(0, start), end)
if (blocks[0] && blocks[0].number === start) {
// OK: we have all the blocks from memory
return blocks
}
// Else: we have to pick them from archives
const last = blocks[0] ? blocks[0].number - 1 : end
const archiveBlocks = await this.blockchainArchiveDAL.getBlocks(start, last)
const lastInArchives = archiveBlocks[archiveBlocks.length - 1] ? archiveBlocks[archiveBlocks.length - 1].number - 1 : end
if (lastInArchives === end) {
// OK: we have all the blocks from archives
return archiveBlocks
}
// Otherwise: what is not taken in the archives are in memory
const memBlocks = await this.blockDAL.getBlocks(archiveBlocks[archiveBlocks.length - 1].number + 1, end)
return archiveBlocks.concat(memBlocks)
}
getForkBlocksFollowing(current:DBBlock) {
......
import {BlockchainArchiveDAO, BlockLike} from "./abstract/BlockchainArchiveDAO"
import {CFSCore} from "../fileDALs/CFSCore"
import {Underscore} from "../../common-libs/underscore"
export class CFSBlockchainArchive<T extends BlockLike> implements BlockchainArchiveDAO<T> {
......@@ -15,7 +16,7 @@ export class CFSBlockchainArchive<T extends BlockLike> implements BlockchainArch
}
const chunks = this.splitIntoChunks(records)
for (const c of chunks) {
const fileName = this.getFileName(c[0].number)
const fileName = this.getFileNameForBlock(c[0].number)
await this.cfs.writeJSON(fileName, c)
}
return chunks.length
......@@ -62,7 +63,7 @@ export class CFSBlockchainArchive<T extends BlockLike> implements BlockchainArch
if (number < 0) {
return null
}
const content = await this.getChunk(number)
const content = await this.getChunkForBlock(number)
if (!content) {
// The block's chunk is not archived
return null
......@@ -70,8 +71,38 @@ export class CFSBlockchainArchive<T extends BlockLike> implements BlockchainArch
return content[this.getPositionInChunk(number)]
}
async getBlocks(start: number, end: number): Promise<T[]> {
const chunkStart = this.getChunkNumber(start)
const chunkLast = this.getChunkNumber(end)
const chunkRange = Underscore.range(chunkStart, chunkLast + 1)
const chunks = await Promise.all(chunkRange.map(c => this.getChunk(c)))
const startInFirst = start - chunkStart * this._chunkSize
const endInLast = end % this._chunkSize + 1
let blocks: T[] = []
for (let i = 0; i < chunks.length; i++) {
let toConcat: T[] = []
const chunk = chunks[i]
if (chunk) {
if (i === 0) {
toConcat = chunk.slice(startInFirst, chunkStart === chunkLast ? endInLast : this._chunkSize)
} else if (i === chunks.length - 1) {
toConcat = chunk.slice(0, endInLast)
} else {
toConcat = chunk.slice()
}
}
blocks = blocks.concat(toConcat)
}
return blocks
}
async getChunk(number:number): Promise<(T[])|null> {
const file = this.getFileName(number)
const file = this.getFileNameForChunk(number)
return this.cfs.readJSON(file)
}
async getChunkForBlock(number:number): Promise<(T[])|null> {
const file = this.getFileNameForBlock(number)
return this.cfs.readJSON(file)
}
......@@ -84,19 +115,27 @@ export class CFSBlockchainArchive<T extends BlockLike> implements BlockchainArch
.reduce((v, max) => {
return Math.max(v, max)
}, 0)
const content = await this.getChunk(max * this._chunkSize)
const content = await this.getChunkForBlock(max * this._chunkSize)
if (!content) {
return null
}
return this.getBlock(content[content.length - 1].number, content[content.length - 1].hash)
}
private getFileName(number:number) {
const rest = number % this._chunkSize
const chunk = (number - rest) / this._chunkSize
private getFileNameForChunk(number:number) {
return CFSBlockchainArchive.getChunkName(number, this._chunkSize)
}
private getFileNameForBlock(number:number) {
const chunk = this.getChunkNumber(number)
return CFSBlockchainArchive.getChunkName(chunk, this._chunkSize)
}
private getChunkNumber(number:number) {
const rest = number % this._chunkSize
return (number - rest) / this._chunkSize
}
private static getChunkName(chunkNumber:number, chunkSize:number) {
return `chunk_${chunkNumber}-${chunkSize}.json`
}
......
......@@ -29,6 +29,14 @@ export interface BlockchainArchiveDAO<T extends BlockLike> extends Initiable {
*/
getBlockByNumber(number:number): Promise<T|null>
/**
* Get the blocks whose number is between [start ; end].
* @param {number} start Starting number to be included.
* @param {number} end Ending number to be included.
* @returns {Promise<T[]>} The corresponding blocks.
*/
getBlocks(start: number, end: number): Promise<T[]>
/**
* Archives a suite of blocks.
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment