This repository has been archived by the owner on Dec 10, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 32
/
blockfetcher.ts
104 lines (93 loc) · 2.66 KB
/
blockfetcher.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { Fetcher, FetcherOptions } from './fetcher'
import { Block, BlockBodyBuffer } from '@ethereumjs/block'
import { BN } from 'ethereumjs-util'
import { Peer } from '../../net/peer'
import { Chain } from '../../blockchain'
export interface BlockFetcherOptions extends FetcherOptions {
/* Blockchain */
chain: Chain
/* Block number to start fetching from */
first: BN
/* How many blocks to fetch */
count: BN
}
/**
* Implements an eth/62 based block fetcher
* @memberof module:sync/fetcher
*/
export class BlockFetcher extends Fetcher {
protected chain: Chain
protected first: BN
protected count: BN
/**
* Create new block fetcher
* @param {BlockFetcherOptions}
*/
constructor(options: BlockFetcherOptions) {
super(options)
this.chain = options.chain
this.maxPerRequest = options.maxPerRequest ?? 128
this.first = options.first
this.count = options.count
}
/**
* Generate list of tasks to fetch
* @return {Object[]} tasks
*/
tasks(): object[] {
const { first, count } = this
const max = this.maxPerRequest
const tasks = []
while (count.gten(max)) {
tasks.push({ first: first.clone(), count: max })
first.iaddn(max)
count.isubn(max)
}
if (count.gtn(0)) {
tasks.push({ first: first.clone(), count: count.toNumber() })
}
return tasks
}
/**
* Requests blocks associated with this job
* @param job
*/
async request(job: any): Promise<any> {
const { task, peer } = job
const { first, count } = task
const headers = await peer.eth.getBlockHeaders({ block: first, max: count })
const bodies = await peer.eth.getBlockBodies(headers.map((h: any) => h.hash()))
const blocks = bodies.map(([txsData, unclesData]: BlockBodyBuffer, i: number) =>
Block.fromValuesArray([headers[i].raw(), txsData, unclesData], { common: this.config.common })
)
return { blocks }
}
/**
* Process fetch result
* @param job fetch job
* @param result fetch result
* @return {*} results of processing job or undefined if job not finished
*/
process(job: any, result: any) {
if (result.blocks && result.blocks.length === job.task.count) {
return result.blocks
}
}
/**
* Store fetch result. Resolves once store operation is complete.
* @param {Block[]} blocks fetch result
* @return {Promise}
*/
async store(blocks: Array<any>) {
await this.chain.putBlocks(blocks)
}
/**
* Returns a peer that can process the given job
* @param job job
* @return {Peer}
*/
// TODO: find out what _job is supposed to be doing here...
peer(_job: any): Peer {
return this.pool.idle((p: any) => p.eth)
}
}