Skip to content

Commit 1e32d3f

Browse files
jochem-brouwerholgerd77
authored andcommitted
client: fix fetcher type problems
1 parent 285014d commit 1e32d3f

File tree

6 files changed

+95
-81
lines changed

6 files changed

+95
-81
lines changed

packages/client/lib/net/protocol/ethprotocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { BN, bufferToInt } from 'ethereumjs-util'
2-
import { Block, BlockHeader, BlockHeaderBuffer } from '@ethereumjs/block'
2+
import { BlockHeader, BlockHeaderBuffer } from '@ethereumjs/block'
33
import { Chain } from './../../blockchain'
44
import { Message, Protocol, ProtocolOptions } from './protocol'
55
import { BlockBodyBuffer } from '../../../../block/dist'

packages/client/lib/sync/fetcher/blockfetcher.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
import { Fetcher, FetcherOptions } from './fetcher'
21
import { Block, BlockBodyBuffer } from '@ethereumjs/block'
3-
import { BN } from 'ethereumjs-util'
42
import { Peer } from '../../net/peer'
53
import { EthProtocolMethods } from '../../net/protocol'
6-
import { Chain } from '../../blockchain'
74
import { Job } from '../../types'
85
import { BlockFetcherBase, JobTask, BlockFetcherOptions } from './blockfetcherbase'
96

10-
117
/**
128
* Implements an eth/62 based block fetcher
139
* @memberof module:sync/fetcher
1410
*/
15-
export class BlockFetcher extends BlockFetcherBase<Block>{
11+
export class BlockFetcher extends BlockFetcherBase<Block[], Block> {
1612
/**
1713
* Create new block fetcher
1814
* @param {BlockFetcherOptions}
@@ -44,14 +40,16 @@ export class BlockFetcher extends BlockFetcherBase<Block>{
4440
* Requests blocks associated with this job
4541
* @param job
4642
*/
47-
async request(job: Job<JobTask, Block>): Promise<Block[]> {
43+
async request(job: Job<JobTask, Block[]>): Promise<Block[]> {
4844
const { task, peer } = job
4945
const { first, count } = task
5046
const headers = await (peer!.eth as EthProtocolMethods).getBlockHeaders({
5147
block: first,
5248
max: count,
5349
})
54-
const bodies: BlockBodyBuffer[] = <BlockBodyBuffer[]>await peer!.eth!.getBlockBodies(headers.map((h) => h.hash()))
50+
const bodies: BlockBodyBuffer[] = <BlockBodyBuffer[]>(
51+
await peer!.eth!.getBlockBodies(headers.map((h) => h.hash()))
52+
)
5553
const blocks: Block[] = bodies.map(([txsData, unclesData]: BlockBodyBuffer, i: number) =>
5654
Block.fromValuesArray([headers[i].raw(), txsData, unclesData], { common: this.config.common })
5755
)
@@ -64,7 +62,8 @@ export class BlockFetcher extends BlockFetcherBase<Block>{
6462
* @param result fetch result
6563
* @return {*} results of processing job or undefined if job not finished
6664
*/
67-
process(job: Job<JobTask, Block>, result: Block[]): Block[] | null {
65+
process(job: Job<JobTask, Block[]>, result: Block[]): Block[] | null {
66+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
6867
if (result && result.length === job.task.count) {
6968
return result
7069
}

packages/client/lib/sync/fetcher/blockfetcherbase.ts

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Fetcher, FetcherOptions } from './fetcher'
22
import { BN } from 'ethereumjs-util'
33
import { Chain } from '../../blockchain'
44

5-
65
export interface BlockFetcherOptions extends FetcherOptions {
76
/* Blockchain */
87
chain: Chain
@@ -15,45 +14,48 @@ export interface BlockFetcherOptions extends FetcherOptions {
1514
}
1615

1716
export type JobTask = {
18-
first: BN
19-
count: number
17+
first: BN
18+
count: number
2019
}
21-
22-
23-
export abstract class BlockFetcherBase<JobResult> extends Fetcher<JobTask, JobResult>{
24-
protected chain: Chain
25-
protected first: BN
26-
protected count: BN
27-
28-
/**
29-
* Create new block fetcher
30-
* @param {BlockFetcherOptions}
31-
*/
32-
constructor(options: BlockFetcherOptions) {
33-
super(options)
34-
35-
this.chain = options.chain
36-
this.maxPerRequest = options.maxPerRequest ?? 128
37-
this.first = options.first
38-
this.count = options.count
20+
21+
export abstract class BlockFetcherBase<JobResult, StorageItem> extends Fetcher<
22+
JobTask,
23+
JobResult,
24+
StorageItem
25+
> {
26+
protected chain: Chain
27+
protected first: BN
28+
protected count: BN
29+
30+
/**
31+
* Create new block fetcher
32+
* @param {BlockFetcherOptions}
33+
*/
34+
constructor(options: BlockFetcherOptions) {
35+
super(options)
36+
37+
this.chain = options.chain
38+
this.maxPerRequest = options.maxPerRequest ?? 128
39+
this.first = options.first
40+
this.count = options.count
41+
}
42+
43+
/**
44+
* Generate list of tasks to fetch
45+
* @return {Object[]} tasks
46+
*/
47+
tasks(): JobTask[] {
48+
const { first, count } = this
49+
const max = this.maxPerRequest
50+
const tasks: JobTask[] = []
51+
while (count.gten(max)) {
52+
tasks.push({ first: first.clone(), count: max })
53+
first.iaddn(max)
54+
count.isubn(max)
3955
}
40-
41-
/**
42-
* Generate list of tasks to fetch
43-
* @return {Object[]} tasks
44-
*/
45-
tasks(): JobTask[] {
46-
const { first, count } = this
47-
const max = this.maxPerRequest
48-
const tasks: JobTask[] = []
49-
while (count.gten(max)) {
50-
tasks.push({ first: first.clone(), count: max })
51-
first.iaddn(max)
52-
count.isubn(max)
53-
}
54-
if (count.gtn(0)) {
55-
tasks.push({ first: first.clone(), count: count.toNumber() })
56-
}
57-
return tasks
56+
if (count.gtn(0)) {
57+
tasks.push({ first: first.clone(), count: count.toNumber() })
5858
}
59-
}
59+
return tasks
60+
}
61+
}

packages/client/lib/sync/fetcher/fetcher.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const Heap = require('qheap')
44
import { PeerPool } from '../../net/peerpool'
55
import { Config } from '../../config'
66

7-
import {QHeap, Job} from '../../types'
7+
import { QHeap, Job } from '../../types'
88
import { Peer } from '../../net/peer'
99

1010
export interface FetcherOptions {
@@ -37,7 +37,7 @@ export interface FetcherOptions {
3737
* inorder.
3838
* @memberof module:sync/fetcher
3939
*/
40-
export abstract class Fetcher<JobTask, JobResult> extends Readable {
40+
export abstract class Fetcher<JobTask, JobResult, StorageItem> extends Readable {
4141
public config: Config
4242

4343
protected pool: PeerPool
@@ -53,7 +53,8 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
5353
protected finished: number // number of tasks which are both processed and also finished writing
5454
protected running: boolean
5555
protected reading: boolean
56-
private _readableState?: { // This property is inherited from Readable. We only need `length`.
56+
private _readableState?: {
57+
// This property is inherited from Readable. We only need `length`.
5758
length: number
5859
}
5960

@@ -72,8 +73,12 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
7273
this.maxQueue = options.maxQueue ?? 16
7374
this.maxPerRequest = options.maxPerRequest ?? 128
7475

75-
this.in = new Heap({ comparBefore: (a: Job<JobTask, JobResult>, b: Job<JobTask, JobResult>) => a.index < b.index })
76-
this.out = new Heap({ comparBefore: (a: Job<JobTask, JobResult>, b: Job<JobTask, JobResult>) => a.index < b.index })
76+
this.in = new Heap({
77+
comparBefore: (a: Job<JobTask, JobResult>, b: Job<JobTask, JobResult>) => a.index < b.index,
78+
})
79+
this.out = new Heap({
80+
comparBefore: (a: Job<JobTask, JobResult>, b: Job<JobTask, JobResult>) => a.index < b.index,
81+
})
7782
this.total = 0
7883
this.processed = 0
7984
this.finished = 0
@@ -131,7 +136,7 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
131136
* @param job successful job
132137
* @param result job result
133138
*/
134-
success(job: Job<JobTask, JobResult>, result?: JobResult[]) {
139+
success(job: Job<JobTask, JobResult>, result?: JobResult) {
135140
if (job.state !== 'active') return
136141
if (result === undefined) {
137142
this.enqueue(job)
@@ -194,7 +199,7 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
194199
this.expire(job)
195200
}, this.timeout)
196201
this.request(job, peer)
197-
.then((result: JobResult[]) => this.success(job, result))
202+
.then((result?: JobResult) => this.success(job, result))
198203
.catch((error: Error) => this.failure(job, error))
199204
.finally(() => clearTimeout(timeout))
200205
return job
@@ -217,7 +222,7 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
217222
* to support backpressure from storing results.
218223
*/
219224
write() {
220-
const _write = async (result: JobResult[], encoding: string | null, cb: Function) => {
225+
const _write = async (result: StorageItem[], encoding: string | null, cb: Function) => {
221226
try {
222227
await this.store(result)
223228
this.finished++
@@ -230,8 +235,14 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
230235
const writer = new Writable({
231236
objectMode: true,
232237
write: _write,
233-
writev: (many: { chunk: JobResult, encoding: string}[], cb: Function) =>
234-
_write((<JobResult[]>[]).concat(...many.map((x: { chunk: JobResult, encoding: string}) => x.chunk)), null, cb),
238+
writev: (many: { chunk: StorageItem; encoding: string }[], cb: Function) =>
239+
_write(
240+
(<StorageItem[]>[]).concat(
241+
...many.map((x: { chunk: StorageItem; encoding: string }) => x.chunk)
242+
),
243+
null,
244+
cb
245+
),
235246
})
236247
this.on('close', () => {
237248
this.running = false
@@ -296,14 +307,14 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
296307
* @param peer
297308
* @return {Promise}
298309
*/
299-
abstract request(_job?: Job<JobTask, JobResult>, _peer?: Peer): Promise<JobResult[]>
310+
abstract request(_job?: Job<JobTask, JobResult>, _peer?: Peer): Promise<JobResult | undefined>
300311

301312
/**
302313
* Process the reply for the given job
303314
* @param job fetch job
304315
* @param result result data
305316
*/
306-
abstract process(_job?: Job<JobTask, JobResult>, _result?: JobResult[]): JobResult[] | null
317+
abstract process(_job?: Job<JobTask, JobResult>, _result?: JobResult): JobResult | null
307318

308319
/**
309320
* Expire job that has timed out and ban associated peer. Timed out tasks will
@@ -329,7 +340,7 @@ export abstract class Fetcher<JobTask, JobResult> extends Readable {
329340
* @param result fetch result
330341
* @return {Promise}
331342
*/
332-
abstract async store(_result?: JobResult[]): Promise<void>
343+
abstract async store(_result?: StorageItem[]): Promise<void>
333344

334345
async wait(delay?: number) {
335346
await new Promise((resolve) => setTimeout(resolve, delay || this.interval))

packages/client/lib/sync/fetcher/headerfetcher.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type BlockHeaderResult = { reqId: BN; bv: BN; headers: BlockHeader[] }
1616
* Implements an les/1 based header fetcher
1717
* @memberof module:sync/fetcher
1818
*/
19-
export class HeaderFetcher extends BlockFetcherBase<BlockHeaderResult> {
19+
export class HeaderFetcher extends BlockFetcherBase<BlockHeaderResult, BlockHeader> {
2020
private flow: FlowControl
2121

2222
/**
@@ -39,9 +39,13 @@ export class HeaderFetcher extends BlockFetcherBase<BlockHeaderResult> {
3939
// we reached our request limit. try with a different peer.
4040
return undefined
4141
}
42-
const response = await (peer!.les as LesProtocolMethods).getBlockHeaders({ block: task.first, max: task.count })
42+
const response = await (peer!.les as LesProtocolMethods).getBlockHeaders({
43+
block: task.first,
44+
max: task.count,
45+
})
46+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
4347
if (response) {
44-
return response.headers
48+
return response
4549
}
4650
return undefined
4751
}

packages/client/lib/types.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Peer } from "./net/peer"
1+
import { Peer } from './net/peer'
22

33
export type Key = Buffer
44
export type KeyLike = string | Key
@@ -15,33 +15,31 @@ export type BootnodeLike = string | string[] | Bootnode | Bootnode[]
1515

1616
// QHeap types. @types/qheap does not exist, so we create a custom interface here.
1717
type QHeapOptions = {
18-
comparBefore(a: any, b:any): boolean
19-
compar(a: any, b:any): number
20-
freeSpace: number
21-
size: number
18+
comparBefore(a: any, b: any): boolean
19+
compar(a: any, b: any): number
20+
freeSpace: number
21+
size: number
2222
}
2323

24-
export interface QHeap<T> {
25-
constructor(opts: QHeapOptions): QHeap<T>
24+
export interface QHeap<T> {
25+
// eslint-disable-next-line @typescript-eslint/no-misused-new
26+
new (opts: QHeapOptions): QHeap<T>
2627
insert(item: T): void
2728
push(item: T): void
28-
enqueue(item: T): void
29-
remove(): T | undefined
29+
enqueue(item: T): void
30+
remove(): T | undefined
3031
shift(): T | undefined
3132
dequeue(): T | undefined
32-
peek(): T | undefined
33+
peek(): T | undefined
3334
length: number
34-
gc(opts: {
35-
minLength: number
36-
maxLength: number
37-
}): void
35+
gc(opts: { minLength: number; maxLength: number }): void
3836
}
3937

4038
export type Job<JobTask, JobResult> = {
4139
task: JobTask
4240
time: number
4341
index: number
44-
result: JobResult[] | null
42+
result: JobResult | null
4543
state: 'idle' | 'expired' | 'active'
4644
peer: Peer | null
47-
}
45+
}

0 commit comments

Comments
 (0)