diff --git a/lib/ain-rs-exports/src/evm.rs b/lib/ain-rs-exports/src/evm.rs index 46ac52b478..2fedaccd16 100644 --- a/lib/ain-rs-exports/src/evm.rs +++ b/lib/ain-rs-exports/src/evm.rs @@ -606,6 +606,15 @@ fn evm_try_get_block_number_by_hash(hash: XHash) -> Result { Ok(block_number) } +/// Return the block header for a given blockhash. +/// +/// # Arguments +/// +/// * `hash` - The hash of the block we want to get the block header. +/// +/// # Returns +/// +/// Returns the block header associated with the given blockhash. #[ffi_fallible] fn evm_try_get_block_header_by_hash(hash: XHash) -> Result { let hash = H256::from(hash); @@ -637,6 +646,20 @@ fn evm_try_get_block_header_by_hash(hash: XHash) -> Result Ok(out) } +/// Return the latest block header from storage. +/// +/// # Returns +/// +/// Returns the latest block header. +#[ffi_fallible] +fn evm_try_get_latest_block_hash() -> Result<[u8; 32]> { + let block = SERVICES + .evm + .storage + .get_latest_block()?; + Ok(block.header.hash().to_fixed_bytes()) +} + #[ffi_fallible] fn evm_try_get_tx_by_hash(tx_hash: XHash) -> Result { let tx_hash = H256::from(tx_hash); diff --git a/lib/ain-rs-exports/src/lib.rs b/lib/ain-rs-exports/src/lib.rs index 09a9fd2f23..07ff3ef055 100644 --- a/lib/ain-rs-exports/src/lib.rs +++ b/lib/ain-rs-exports/src/lib.rs @@ -292,6 +292,8 @@ pub mod ffi { hash: [u8; 32], ) -> EVMBlockHeader; + fn evm_try_get_latest_block_hash(result: &mut CrossBoundaryResult) -> [u8; 32]; + fn evm_try_get_tx_by_hash( result: &mut CrossBoundaryResult, tx_hash: [u8; 32], diff --git a/src/init.cpp b/src/init.cpp index 32435f1eb0..a9b5d8033e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1838,7 +1838,7 @@ bool AppInitMain(InitInterfaces& interfaces) fReindex = gArgs.GetBoolArg("-reindex", false); bool fReindexChainState = gArgs.GetBoolArg("-reindex-chainstate", false); while (!fLoaded && !ShutdownRequested()) { - bool fReset = (fReindex || fEvmDatabaseDirty); + bool fReset = fReindex; std::string strLoadError; uiInterface.InitMessage(_("Loading block index...").translated); @@ -1928,13 +1928,6 @@ bool AppInitMain(InitInterfaces& interfaces) // Ensure we are on latest DB version pcustomcsview->SetDbVersion(CCustomCSView::DbVersion); - // Set evm database dirty flag - fEvmDatabaseDirty = pcustomcsview->GetEvmDirtyFlag(); - if (!fReset && fEvmDatabaseDirty) { - LogPrintf("Evm database dirty, re-indexing chain state.\n"); - break; - } - // make account history db paccountHistoryDB.reset(); if (gArgs.GetBoolArg("-acindex", DEFAULT_ACINDEX)) { @@ -1973,6 +1966,20 @@ bool AppInitMain(InitInterfaces& interfaces) auto res = XResultStatusLogged(ain_rs_init_core_services(result)); if (!res) return false; + // Set evm database dirty flag + fEvmDatabaseDirty = pcustomcsview->GetEvmDirtyFlag(); + if (fEvmDatabaseDirty) { + LogPrintf("Evm database dirty, rollback chain state to latest EVM block height.\n"); + auto res = XResultValueLogged(evm_try_get_latest_block_hash(result)); + auto lastEvmBlockHash = uint256::FromByteArray(*res).GetHex(); + auto lastDvmBlockHash = pcustomcsview->GetVMDomainBlockEdge(VMDomainEdge::EVMToDVM, lastEvmBlockHash); + if (!lastDvmBlockHash.val.has_value()) { + strLoadError = _("Unable to get DVM block height from latest EVM block height. You will need to rebuild the database using -reindex-chainstate.").translated; + } + CBlockIndex *pindex = LookupBlockIndex(uint256S(*lastDvmBlockHash.val)); + uint64_t lastDvmBlockNumber = pindex->GetBlockHeader().deprecatedHeight; + } + // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate if (!ReplayBlocks(chainparams, &::ChainstateActive().CoinsDB(), pcustomcsview.get())) { strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.").translated;