@@ -25,6 +25,7 @@ import {
25
25
import { DBManager } from './db/manager.js'
26
26
import { DBTarget } from './db/operation.js'
27
27
28
+ import type { OptimisticOpts } from './db/operation.js'
28
29
import type {
29
30
BlockchainEvents ,
30
31
BlockchainInterface ,
@@ -272,8 +273,8 @@ export class Blockchain implements BlockchainInterface {
272
273
* heads/hashes are overwritten.
273
274
* @param block - The block to be added to the blockchain
274
275
*/
275
- async putBlock ( block : Block , optimistic : boolean = false ) {
276
- await this . _putBlockOrHeader ( block , optimistic )
276
+ async putBlock ( block : Block , opts ?: OptimisticOpts ) {
277
+ await this . _putBlockOrHeader ( block , opts )
277
278
}
278
279
279
280
/**
@@ -344,7 +345,7 @@ export class Blockchain implements BlockchainInterface {
344
345
* header using the iterator method.
345
346
* @hidden
346
347
*/
347
- private async _putBlockOrHeader ( item : Block | BlockHeader , optimistic : boolean = false ) {
348
+ private async _putBlockOrHeader ( item : Block | BlockHeader , optimisticOpts ?: OptimisticOpts ) {
348
349
await this . runWithLock < void > ( async ( ) => {
349
350
// Save the current sane state incase _putBlockOrHeader midway with some
350
351
// dirty changes in head trackers
@@ -362,13 +363,13 @@ export class Blockchain implements BlockchainInterface {
362
363
if ( isGenesis ) {
363
364
if ( equalsBytes ( this . genesisBlock . hash ( ) , block . hash ( ) ) ) {
364
365
// Try to re-put the existing genesis block, accept this
365
- optimistic = false
366
+ // genesis block is not optimistic
367
+ optimisticOpts = undefined
366
368
return
367
369
}
368
370
throw new Error (
369
371
'Cannot put a different genesis block than current blockchain genesis: create a new Blockchain' ,
370
372
)
371
- // genesis block is not optimistic
372
373
}
373
374
374
375
if ( block . common . chainId ( ) !== this . common . chainId ( ) ) {
@@ -377,12 +378,12 @@ export class Blockchain implements BlockchainInterface {
377
378
)
378
379
}
379
380
380
- if ( this . _validateBlocks && ! isGenesis && item instanceof Block ) {
381
+ if ( this . _validateBlocks && ! isGenesis && item instanceof Block && optimisticOpts === undefined ) {
381
382
// this calls into `getBlock`, which is why we cannot lock yet
382
383
await this . validateBlock ( block )
383
384
}
384
385
385
- if ( this . _validateConsensus ) {
386
+ if ( this . _validateConsensus && optimisticOpts === undefined ) {
386
387
await this . consensus ! . validateConsensus ( block )
387
388
}
388
389
@@ -397,20 +398,20 @@ export class Blockchain implements BlockchainInterface {
397
398
if ( ! block . isGenesis ( ) ) {
398
399
td += parentTd
399
400
}
400
- // since its linked its no more optimistic
401
- optimistic = false
402
401
} catch ( e ) {
403
402
// opimistic insertion does care about td
404
- if ( ! optimistic ) {
403
+ if ( optimisticOpts === undefined ) {
405
404
throw e
406
405
}
407
406
}
408
407
409
408
let dbOps : DBOp [ ] = [ ]
410
- if ( optimistic ) {
409
+ if ( optimisticOpts !== undefined ) {
411
410
dbOps = dbOps . concat ( DBSetBlockOrHeader ( item ) )
412
411
dbOps . push ( DBSetHashToNumber ( blockHash , blockNumber ) )
413
- dbOps . push ( DBOp . set ( DBTarget . OptimisticNumberToHash , blockHash , { blockNumber } ) )
412
+ if ( optimisticOpts . fcUed ) {
413
+ dbOps . push ( DBOp . set ( DBTarget . OptimisticNumberToHash , blockHash , { blockNumber } ) )
414
+ }
414
415
await this . dbManager . batch ( dbOps )
415
416
} else {
416
417
const currentTd = { header : BIGINT_0 , block : BIGINT_0 }
@@ -676,13 +677,16 @@ export class Blockchain implements BlockchainInterface {
676
677
* this will be immediately looked up, otherwise it will wait until we have
677
678
* unlocked the DB
678
679
*/
679
- async getBlock ( blockId : Uint8Array | number | bigint ) : Promise < Block > {
680
+ async getBlock (
681
+ blockId : Uint8Array | number | bigint ,
682
+ optimisticOpts ?: OptimisticOpts ,
683
+ ) : Promise < Block > {
680
684
// cannot wait for a lock here: it is used both in `validate` of `Block`
681
685
// (calls `getBlock` to get `parentHash`) it is also called from `runBlock`
682
686
// in the `VM` if we encounter a `BLOCKHASH` opcode: then a bigint is used we
683
687
// need to then read the block from the canonical chain Q: is this safe? We
684
688
// know it is OK if we call it from the iterator... (runBlock)
685
- const block = await this . dbManager . getBlock ( blockId )
689
+ const block = await this . dbManager . getBlock ( blockId , optimisticOpts )
686
690
687
691
if ( block === undefined ) {
688
692
if ( typeof blockId === 'object' ) {
0 commit comments