@@ -25,6 +25,7 @@ import {
2525import { DBManager } from './db/manager.js'
2626import { DBTarget } from './db/operation.js'
2727
28+ import type { OptimisticOpts } from './db/operation.js'
2829import type {
2930 BlockchainEvents ,
3031 BlockchainInterface ,
@@ -272,8 +273,8 @@ export class Blockchain implements BlockchainInterface {
272273 * heads/hashes are overwritten.
273274 * @param block - The block to be added to the blockchain
274275 */
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 )
277278 }
278279
279280 /**
@@ -344,7 +345,7 @@ export class Blockchain implements BlockchainInterface {
344345 * header using the iterator method.
345346 * @hidden
346347 */
347- private async _putBlockOrHeader ( item : Block | BlockHeader , optimistic : boolean = false ) {
348+ private async _putBlockOrHeader ( item : Block | BlockHeader , optimisticOpts ?: OptimisticOpts ) {
348349 await this . runWithLock < void > ( async ( ) => {
349350 // Save the current sane state incase _putBlockOrHeader midway with some
350351 // dirty changes in head trackers
@@ -362,13 +363,13 @@ export class Blockchain implements BlockchainInterface {
362363 if ( isGenesis ) {
363364 if ( equalsBytes ( this . genesisBlock . hash ( ) , block . hash ( ) ) ) {
364365 // Try to re-put the existing genesis block, accept this
365- optimistic = false
366+ // genesis block is not optimistic
367+ optimisticOpts = undefined
366368 return
367369 }
368370 throw new Error (
369371 'Cannot put a different genesis block than current blockchain genesis: create a new Blockchain' ,
370372 )
371- // genesis block is not optimistic
372373 }
373374
374375 if ( block . common . chainId ( ) !== this . common . chainId ( ) ) {
@@ -377,12 +378,12 @@ export class Blockchain implements BlockchainInterface {
377378 )
378379 }
379380
380- if ( this . _validateBlocks && ! isGenesis && item instanceof Block ) {
381+ if ( this . _validateBlocks && ! isGenesis && item instanceof Block && optimisticOpts === undefined ) {
381382 // this calls into `getBlock`, which is why we cannot lock yet
382383 await this . validateBlock ( block )
383384 }
384385
385- if ( this . _validateConsensus ) {
386+ if ( this . _validateConsensus && optimisticOpts === undefined ) {
386387 await this . consensus ! . validateConsensus ( block )
387388 }
388389
@@ -397,20 +398,20 @@ export class Blockchain implements BlockchainInterface {
397398 if ( ! block . isGenesis ( ) ) {
398399 td += parentTd
399400 }
400- // since its linked its no more optimistic
401- optimistic = false
402401 } catch ( e ) {
403402 // opimistic insertion does care about td
404- if ( ! optimistic ) {
403+ if ( optimisticOpts === undefined ) {
405404 throw e
406405 }
407406 }
408407
409408 let dbOps : DBOp [ ] = [ ]
410- if ( optimistic ) {
409+ if ( optimisticOpts !== undefined ) {
411410 dbOps = dbOps . concat ( DBSetBlockOrHeader ( item ) )
412411 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+ }
414415 await this . dbManager . batch ( dbOps )
415416 } else {
416417 const currentTd = { header : BIGINT_0 , block : BIGINT_0 }
@@ -676,13 +677,16 @@ export class Blockchain implements BlockchainInterface {
676677 * this will be immediately looked up, otherwise it will wait until we have
677678 * unlocked the DB
678679 */
679- async getBlock ( blockId : Uint8Array | number | bigint ) : Promise < Block > {
680+ async getBlock (
681+ blockId : Uint8Array | number | bigint ,
682+ optimisticOpts ?: OptimisticOpts ,
683+ ) : Promise < Block > {
680684 // cannot wait for a lock here: it is used both in `validate` of `Block`
681685 // (calls `getBlock` to get `parentHash`) it is also called from `runBlock`
682686 // in the `VM` if we encounter a `BLOCKHASH` opcode: then a bigint is used we
683687 // need to then read the block from the canonical chain Q: is this safe? We
684688 // 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 )
686690
687691 if ( block === undefined ) {
688692 if ( typeof blockId === 'object' ) {
0 commit comments