Skip to content

Commit bdfbe37

Browse files
ryaniog11techacolytec3
authored
client: optimistic (beacon) sync (#1878)
* beacon sync (optimistic sync) implementation Co-authored-by: harkamal <gajinder@g11.in> Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com>
1 parent e8fd471 commit bdfbe37

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2395
-209
lines changed

packages/client/bin/cli.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { _getInitializedChains } from '@ethereumjs/common/dist/chains'
1111
import { Address, toBuffer, BN } from 'ethereumjs-util'
1212
import { parseMultiaddrs, parseGenesisState, parseCustomParams } from '../lib/util'
1313
import EthereumClient from '../lib/client'
14-
import { Config, DataDirectory } from '../lib/config'
14+
import { Config, DataDirectory, SyncMode } from '../lib/config'
1515
import { Logger, getLogger } from '../lib/logging'
1616
import { startRPCServers, helprpc } from './startRpc'
1717
import type { Chain as IChain, GenesisState } from '@ethereumjs/common/dist/types'
@@ -39,7 +39,7 @@ const args = yargs(hideBin(process.argv))
3939
})
4040
.option('syncmode', {
4141
describe: 'Blockchain sync mode (light sync experimental)',
42-
choices: ['light', 'full'],
42+
choices: Object.values(SyncMode),
4343
default: Config.SYNCMODE_DEFAULT,
4444
})
4545
.option('lightserv', {
@@ -250,6 +250,11 @@ const args = yargs(hideBin(process.argv))
250250
'Save tx receipts and logs in the meta db (warning: may use a large amount of storage). With `--rpc` allows querying via eth_getLogs (max 10000 logs per request) and eth_getTransactionReceipt (within `--txLookupLimit`)',
251251
boolean: true,
252252
})
253+
.option('disableBeaconSync', {
254+
describe:
255+
'Disables beacon (optimistic) sync if the CL provides blocks at the head of the chain',
256+
boolean: true,
257+
})
253258
.option('txLookupLimit', {
254259
describe:
255260
'Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)',
@@ -276,13 +281,10 @@ function initDBs(config: Config) {
276281
ensureDirSync(stateDataDir)
277282
const stateDB = level(stateDataDir)
278283

279-
// Meta DB (receipts, logs, indexes)
280-
let metaDB
281-
if (args.saveReceipts) {
282-
const metaDataDir = config.getDataDirectory(DataDirectory.Meta)
283-
ensureDirSync(metaDataDir)
284-
metaDB = level(metaDataDir)
285-
}
284+
// Meta DB (receipts, logs, indexes, skeleton chain)
285+
const metaDataDir = config.getDataDirectory(DataDirectory.Meta)
286+
ensureDirSync(metaDataDir)
287+
const metaDB = level(metaDataDir)
286288

287289
return { chainDB, stateDB, metaDB }
288290
}
@@ -621,6 +623,7 @@ async function run() {
621623
port: args.port,
622624
saveReceipts: args.saveReceipts,
623625
syncmode: args.syncmode,
626+
disableBeaconSync: args.disableBeaconSync,
624627
transports: args.transports,
625628
txLookupLimit: args.txLookupLimit,
626629
})

packages/client/kiln/README.md

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ Kiln v2 public testnet has been bootstrapped:
66

77
The config files can be downloaded from the [merge-testnets](https://github.com/eth-clients/merge-testnets/tree/main/kiln) config GitHub repository.
88

9-
109
## Execution - EthereumJS Setup
1110

12-
Please ensure you have Node 12.x+ installed.
11+
Please ensure you have Node 16.x installed.
1312

1413
### Client Installation
1514

@@ -28,7 +27,7 @@ The `v0.4.0` client release (respectively follow-up bug fix releases) is ready f
2827
npm install -g @ethereumjs/client
2928
```
3029

31-
Note that you eventually want to adopt the `config` download and accordingly modify the config file access paths as well as start the client just with `ethereumjs` instad of using the `npm run client:start` GitHub start command (also leave the inbetween `--` to forward the client config options).
30+
Note that you eventually want to adopt the `config` download and accordingly modify the config file access paths as well as start the client just with `ethereumjs` instead of using the `npm run client:start` GitHub start command (also leave the in-between `--` to forward the client config options).
3231

3332
#### Docker
3433

@@ -67,7 +66,7 @@ To prevent the secret to be re-generated next time you restart the client, pass
6766
1. Use lodestar branch `master` and run `yarn && yarn build`
6867
2. Export path of the downloaded config dir `export CONFIG_PATH=/path/to/ethereumjs-monorepo/packages/client/kiln/config`
6968
3. Export path of the written jwt secret file `export JWT_SECRET_PATH=/path/to/ethereumjs-monorepo/packages/client/kiln/datadir/jwtsecret`
70-
4. Run cmd: `./lodestar beacon --rootDir kiln/temp --paramsFile $CONFIG_PATH/config.yaml --genesisStateFile $CONFIG_PATH/genesis.ssz --bootnodesFile $CONFIG_PATH/boot_enr.yaml --network.connectToDiscv5Bootnodes --network.discv5.enabled true --eth1.enabled true --eth1.providerUrls=http://localhost:8545 --execution.urls=http://localhost:8551 --eth1.disableEth1DepositDataTracker true --jwt-secret $JWT_SECRET_PATH`
69+
4. Run cmd: `./lodestar beacon --rootDir kiln/temp --paramsFile $CONFIG_PATH/config.yaml --genesisStateFile $CONFIG_PATH/genesis.ssz --bootnodesFile $CONFIG_PATH/boot_enr.yaml --network.connectToDiscv5Bootnodes --network.discv5.enabled true --eth1.enabled true --eth1.providerUrls=http://localhost:8545 --execution.urls=http://localhost:8551 --eth1.disableEth1DepositDataTracker true --jwt-secret $JWT_SECRET_PATH --weakSubjectivityServerUrl https://lodestar-kiln.chainsafe.io --weakSubjectivitySyncLatest`
7170

7271
#### Validator
7372

@@ -77,8 +76,26 @@ Also, one will need to remove `--eth1.disableEth1DepositDataTracker true` and in
7776

7877
### Lighthouse
7978

80-
### Beacon
79+
#### Beacon
8180

8281
1. Use lighthouse branch `unstable` and run `make`
83-
1. Make dir `lighthouse/kiln` and copy in from the downloaded config dir: `config.yaml`, `genesis.ssz`, `deploy_block.txt`, `deposit_contract.txt`, `deposit_contract_block.txt`
84-
1. Run cmd: `lighthouse --debug-level=info --datadir=kiln/datadir --testnet-dir=kiln beacon_node --disable-enr-auto-update --dummy-eth1 --boot-nodes="enr:" --merge --http-allow-sync-stalled --metrics --disable-packet-filter --execution-endpoints=http://127.0.0.1:8551 --terminal-total-difficulty-override=`
82+
2. Make dir `lighthouse/kiln` and copy in from the downloaded config dir: `config.yaml`, `genesis.ssz`, `deploy_block.txt`, `deposit_contract.txt`, `deposit_contract_block.txt`
83+
3. Run cmd: `lighthouse --debug-level=info --datadir=kiln/datadir --testnet-dir=kiln beacon_node --disable-enr-auto-update --dummy-eth1 --boot-nodes="enr:" --merge --http-allow-sync-stalled --metrics --disable-packet-filter --execution-endpoints=http://127.0.0.1:8551 --terminal-total-difficulty-override=20000000000000`
84+
4. Run cmd (with checkpoint sync - tested this with a locally running syncd Nimbus client): `lighthouse bn --network kiln --terminal-total-difficulty-override=20000000000000 --merge --http-allow-sync-stalled --checkpoint-sync-url "http://localhost:5052" --logfile logs.txt --logfile-debug-level trace`
85+
86+
### Teku
87+
88+
#### Beacon
89+
90+
1. Download latest Teku binary [here](https://github.com/ConsenSys/teku/releases) and extract from archive
91+
2. Run cmd (with checkpoint sync): `./teku --data-path "./data" --network kiln --initial-state="https://lodestar-kiln.chainsafe.io/eth/v2/debug/beacon/states/finalized" --ee-endpoint http://localhost:8551 --ee-jwt-secret-file "/path/to/ethereumjs-monorepo/packages/client/kiln/datadir/jwtsecret" --logging=DEBUG`
92+
93+
### Nimbus
94+
95+
#### Beacon
96+
97+
1. Build Nimbus following the [kiln instructions](https://nimbus.guide/kiln.html#3-nimbus)
98+
2. Get your hands on a SSZ encoded finalized state/block snapshot from a synced client. Assuming you have a synced Teku (or other CL node running locally that exposes the Beacon REST API), you can use the below `curl` commands to get it.
99+
`curl -H 'Accept: application/octet-stream' http://127.0.0.1:5051/eth/v2/debug/beacon/states/finalized > state.ssz`
100+
`curl -H 'Accept: application/octet-stream' http://127.0.0.1:5051/eth/v2/beacon/blocks/[block number corresponding to finalized state above] > block.ssz`
101+
3. Run cmd (with checkpoint sync and adjust ports/paths accordingly for your setup): `build/nimbus_beacon_node --network=vendor/merge-testnets/kiln --web3-url=ws://127.0.0.1:8551 --log-level=DEBUG --jwt-secret="/path/to/ethereumjs-monorepo/packages/client/kiln/datadir/jwtsecret" --data-dir=build/kiln --data-dir:trusted --finalized-checkpoint-state=state.ssz --finalized-checkpoint-block=block.ssz`

packages/client/lib/blockchain/chain.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ export class Chain {
182182
await this.blockchain.db.open()
183183
await this.blockchain.initPromise
184184
this.opened = true
185-
await this.update()
185+
await this.update(false)
186186

187187
this.config.chainCommon.on('hardforkChanged', async (hardfork: string) => {
188188
if (hardfork !== Hardfork.Merge) {

packages/client/lib/client.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ export interface EthereumClientOptions {
3131
* Database to store tx receipts, logs, and indexes.
3232
* Should be an abstract-leveldown compliant store.
3333
*
34-
* Default: Database created in datadir folder when
35-
* `--saveReceipts` is enabled, otherwise undefined
34+
* Default: Database created in datadir folder
3635
*/
3736
metaDB?: LevelUp
3837

packages/client/lib/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ export interface ConfigOptions {
3838
*/
3939
syncmode?: SyncMode
4040

41+
/**
42+
* Whether to disable beacon (optimistic) sync if CL provides
43+
* blocks at the head of chain.
44+
*
45+
* Default: false
46+
*/
47+
disableBeaconSync?: boolean
48+
4149
/**
4250
* Provide a custom VM instance to process blocks
4351
*
@@ -259,6 +267,7 @@ export class Config {
259267
public readonly accounts: [address: Address, privKey: Buffer][]
260268
public readonly minerCoinbase?: Address
261269
public readonly safeReorgDistance: number
270+
public readonly disableBeaconSync: boolean
262271

263272
public synchronized: boolean
264273
public lastSyncDate: number
@@ -295,6 +304,7 @@ export class Config {
295304
this.accounts = options.accounts ?? []
296305
this.minerCoinbase = options.minerCoinbase
297306
this.safeReorgDistance = options.safeReorgDistance ?? Config.SAFE_REORG_DISTANCE
307+
this.disableBeaconSync = options.disableBeaconSync ?? false
298308

299309
this.synchronized = false
300310
this.lastSyncDate = 0

packages/client/lib/execution/receipt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Log } from '@ethereumjs/vm/dist/evm/types'
33
import Bloom from '@ethereumjs/vm/dist/bloom'
44
import { TypedTransaction } from '@ethereumjs/tx'
55
import { rlp, intToBuffer, bufferToInt } from 'ethereumjs-util'
6-
import { MetaDBManager, DBKey } from './metaDBManager'
6+
import { MetaDBManager, DBKey } from '../util/metaDBManager'
77
import type { Block } from '@ethereumjs/block'
88

99
/**

packages/client/lib/execution/vmexecution.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class VMExecution extends Execution {
5353
;(this.vm as any).blockchain = this.chain.blockchain
5454
}
5555

56-
if (this.metaDB) {
56+
if (this.metaDB && this.config.saveReceipts) {
5757
this.receiptsManager = new ReceiptsManager({
5858
chain: this.chain,
5959
config: this.config,

packages/client/lib/miner/miner.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Event } from '../types'
66
import { Config } from '../config'
77
import { FullEthereumService } from '../service'
88
import { VMExecution } from '../execution'
9+
import type { FullSynchronizer } from '../sync'
910

1011
const level = require('level-mem')
1112

@@ -300,7 +301,7 @@ export class Miner {
300301
this.assembling = false
301302
if (interrupt) return
302303
// Put block in blockchain
303-
await this.service.synchronizer.handleNewBlock(block)
304+
await (this.service.synchronizer as FullSynchronizer).handleNewBlock(block)
304305
// Remove included txs from TxPool
305306
this.service.txPool.removeNewBlockTxs([block])
306307
this.config.events.removeListener(Event.CHAIN_UPDATED, _boundSetInterruptHandler)

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ export interface EthProtocolMethods {
6666
getReceipts: (opts: GetReceiptsOpts) => Promise<[BN, TxReceipt[]]>
6767
}
6868

69-
const id = new BN(0)
70-
7169
/**
7270
* Implements eth/66 protocol
7371
* @memberof module:net/protocol
7472
*/
7573
export class EthProtocol extends Protocol {
7674
private chain: Chain
75+
private nextReqId = new BN(0)
7776

77+
/* eslint-disable no-invalid-this */
7878
private protocolMessages: Message[] = [
7979
{
8080
name: 'NewBlockHashes',
@@ -108,7 +108,7 @@ export class EthProtocol extends Protocol {
108108
code: 0x03,
109109
response: 0x04,
110110
encode: ({ reqId, block, max, skip = 0, reverse = false }: GetBlockHeadersOpts) => [
111-
(reqId === undefined ? id.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
111+
(reqId === undefined ? this.nextReqId.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
112112
[BN.isBN(block) ? block.toArrayLike(Buffer) : block, max, skip, !reverse ? 0 : 1],
113113
],
114114
decode: ([reqId, [block, max, skip, reverse]]: any) => ({
@@ -135,7 +135,7 @@ export class EthProtocol extends Protocol {
135135
// and we look backwards for the correct block)
136136
BlockHeader.fromValuesArray(h, {
137137
hardforkByBlockNumber: true,
138-
common: this.config.chainCommon, // eslint-disable-line no-invalid-this
138+
common: this.config.chainCommon,
139139
})
140140
),
141141
],
@@ -145,7 +145,7 @@ export class EthProtocol extends Protocol {
145145
code: 0x05,
146146
response: 0x06,
147147
encode: ({ reqId, hashes }: GetBlockBodiesOpts) => [
148-
(reqId === undefined ? id.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
148+
(reqId === undefined ? this.nextReqId.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
149149
hashes,
150150
],
151151
decode: ([reqId, hashes]: [Buffer, Buffer[]]) => ({
@@ -168,7 +168,6 @@ export class EthProtocol extends Protocol {
168168
encode: ([block, td]: [Block, BN]) => [block.raw(), td.toArrayLike(Buffer)],
169169
decode: ([block, td]: [BlockBuffer, Buffer]) => [
170170
Block.fromValuesArray(block, {
171-
// eslint-disable-next-line no-invalid-this
172171
common: this.config.chainCommon,
173172
hardforkByBlockNumber: true,
174173
}),
@@ -184,7 +183,7 @@ export class EthProtocol extends Protocol {
184183
code: 0x09,
185184
response: 0x0a,
186185
encode: ({ reqId, hashes }: GetPooledTransactionsOpts) => [
187-
(reqId === undefined ? id.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
186+
(reqId === undefined ? this.nextReqId.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
188187
hashes,
189188
],
190189
decode: ([reqId, hashes]: [Buffer, Buffer[]]) => ({
@@ -219,7 +218,7 @@ export class EthProtocol extends Protocol {
219218
code: 0x0f,
220219
response: 0x10,
221220
encode: ({ reqId, hashes }: { reqId: BN; hashes: Buffer[] }) => [
222-
(reqId === undefined ? id.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
221+
(reqId === undefined ? this.nextReqId.iaddn(1) : new BN(reqId)).toArrayLike(Buffer),
223222
hashes,
224223
],
225224
decode: ([reqId, hashes]: [Buffer, Buffer[]]) => ({
@@ -319,7 +318,6 @@ export class EthProtocol extends Protocol {
319318
: this.chain.blocks.td.toArrayLike(Buffer),
320319
bestHash: this.chain.blocks.latest!.hash(),
321320
genesisHash: this.chain.genesis.hash,
322-
latestBlock: this.chain.blocks.latest!.header.number.toArrayLike(Buffer),
323321
}
324322
}
325323

0 commit comments

Comments
 (0)