Skip to content

Commit 2fb06c0

Browse files
author
Michał Mrożek
authored
Merge pull request #741 from input-output-hk/etcm-212-fix-tx-mining
[ECTM-212] Fix block preparation (taking into account EIP-161)
2 parents f52c940 + 1425ac4 commit 2fb06c0

File tree

6 files changed

+486
-348
lines changed

6 files changed

+486
-348
lines changed

src/main/scala/io/iohk/ethereum/domain/Blockchain.scala

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,21 @@ trait Blockchain {
178178

179179
def genesisBlock: Block = getBlockByNumber(0).get
180180

181-
def getWorldStateProxy(blockNumber: BigInt,
182-
accountStartNonce: UInt256,
183-
stateRootHash: Option[ByteString],
184-
noEmptyAccounts: Boolean,
185-
ethCompatibleStorage: Boolean): WS
186-
187-
def getReadOnlyWorldStateProxy(blockNumber: Option[BigInt],
188-
accountStartNonce: UInt256,
189-
stateRootHash: Option[ByteString],
190-
noEmptyAccounts: Boolean,
191-
ethCompatibleStorage: Boolean): WS
181+
def getWorldStateProxy(
182+
blockNumber: BigInt,
183+
accountStartNonce: UInt256,
184+
stateRootHash: Option[ByteString],
185+
noEmptyAccounts: Boolean,
186+
ethCompatibleStorage: Boolean
187+
): WS
188+
189+
def getReadOnlyWorldStateProxy(
190+
blockNumber: Option[BigInt],
191+
accountStartNonce: UInt256,
192+
stateRootHash: Option[ByteString],
193+
noEmptyAccounts: Boolean,
194+
ethCompatibleStorage: Boolean
195+
): WS
192196

193197
def getStateStorage: StateStorage
194198
}
@@ -259,7 +263,11 @@ class BlockchainImpl(
259263
mpt.get(address)
260264
}
261265

262-
override def getAccountStorageAt(rootHash: ByteString, position: BigInt, ethCompatibleStorage: Boolean): ByteString = {
266+
override def getAccountStorageAt(
267+
rootHash: ByteString,
268+
position: BigInt,
269+
ethCompatibleStorage: Boolean
270+
): ByteString = {
263271
val storage = stateStorage.getBackingStorage(0)
264272
val mpt =
265273
if (ethCompatibleStorage) domain.EthereumUInt256Mpt.storageMpt(rootHash, storage)
@@ -268,7 +276,8 @@ class BlockchainImpl(
268276
}
269277

270278
private def persistBestBlocksData(): Unit = {
271-
appStateStorage.putBestBlockNumber(getBestBlockNumber())
279+
appStateStorage
280+
.putBestBlockNumber(getBestBlockNumber())
272281
.and(appStateStorage.putLatestCheckpointBlockNumber(getLatestCheckpointBlockNumber()))
273282
.commit()
274283
}
@@ -298,7 +307,8 @@ class BlockchainImpl(
298307
override def getMptNodeByHash(hash: ByteString): Option[MptNode] =
299308
stateStorage.getNode(hash)
300309

301-
override def getTransactionLocation(txHash: ByteString): Option[TransactionLocation] = transactionMappingStorage.get(txHash)
310+
override def getTransactionLocation(txHash: ByteString): Option[TransactionLocation] =
311+
transactionMappingStorage.get(txHash)
302312

303313
override def storeBlockBody(blockHash: ByteString, blockBody: BlockBody): DataSourceBatchUpdate = {
304314
blockBodiesStorage.put(blockHash, blockBody).and(saveTxsLocations(blockHash, blockBody))
@@ -351,14 +361,15 @@ class BlockchainImpl(
351361
val bestBlocks = bestKnownBlockAndLatestCheckpoint.get()
352362
// as we are decreasing block numbers in memory more often than in storage,
353363
// we can't use here getBestBlockNumber / getLatestCheckpointBlockNumber
354-
val bestBlockNumber = if(bestBlocks.bestBlockNumber != 0) bestBlocks.bestBlockNumber else appStateStorage.getBestBlockNumber()
364+
val bestBlockNumber =
365+
if (bestBlocks.bestBlockNumber != 0) bestBlocks.bestBlockNumber else appStateStorage.getBestBlockNumber()
355366
val latestCheckpointNumber = {
356-
if(bestBlocks.latestCheckpointNumber != 0) bestBlocks.latestCheckpointNumber
367+
if (bestBlocks.latestCheckpointNumber != 0) bestBlocks.latestCheckpointNumber
357368
else appStateStorage.getLatestCheckpointBlockNumber()
358369
}
359370

360371
val blockNumberMappingUpdates = {
361-
maybeBlockHeader.fold(blockNumberMappingStorage.emptyBatchUpdate)( h =>
372+
maybeBlockHeader.fold(blockNumberMappingStorage.emptyBatchUpdate)(h =>
362373
if (getHashByBlockNumber(h.number).contains(blockHash))
363374
removeBlockNumberMapping(h.number)
364375
else blockNumberMappingStorage.emptyBatchUpdate
@@ -369,19 +380,22 @@ class BlockchainImpl(
369380
case Some(header) =>
370381
if (header.hasCheckpoint && header.number == latestCheckpointNumber) {
371382
val prev = findPreviousCheckpointBlockNumber(header.number, header.number)
372-
prev.map { num =>
373-
(appStateStorage.putLatestCheckpointBlockNumber(num), Some(num))
374-
}.getOrElse {
375-
(appStateStorage.removeLatestCheckpointBlockNumber(), Some(0))
376-
}
383+
prev
384+
.map { num =>
385+
(appStateStorage.putLatestCheckpointBlockNumber(num), Some(num))
386+
}
387+
.getOrElse {
388+
(appStateStorage.removeLatestCheckpointBlockNumber(), Some(0))
389+
}
377390
} else (appStateStorage.emptyBatchUpdate, None)
378391
case None =>
379392
(appStateStorage.emptyBatchUpdate, None)
380393
}
381394

382-
val newBestBlockNumber: BigInt = if(bestBlockNumber >= 1) bestBlockNumber - 1 else 0
395+
val newBestBlockNumber: BigInt = if (bestBlockNumber >= 1) bestBlockNumber - 1 else 0
383396

384-
blockHeadersStorage.remove(blockHash)
397+
blockHeadersStorage
398+
.remove(blockHash)
385399
.and(blockBodiesStorage.remove(blockHash))
386400
.and(totalDifficultyStorage.remove(blockHash))
387401
.and(receiptStorage.remove(blockHash))
@@ -394,7 +408,8 @@ class BlockchainImpl(
394408

395409
maybeBlockHeader.foreach { h =>
396410
if (withState) {
397-
val bestBlocksUpdates = appStateStorage.putBestBlockNumber(newBestBlockNumber)
411+
val bestBlocksUpdates = appStateStorage
412+
.putBestBlockNumber(newBestBlockNumber)
398413
.and(checkpointUpdates)
399414
stateStorage.onBlockRollback(h.number, bestBlockNumber)(() => bestBlocksUpdates.commit())
400415
}
@@ -408,8 +423,8 @@ class BlockchainImpl(
408423
*/
409424
@tailrec
410425
private def findPreviousCheckpointBlockNumber(
411-
blockNumberToCheck: BigInt,
412-
latestCheckpointBlockNumber: BigInt
426+
blockNumberToCheck: BigInt,
427+
latestCheckpointBlockNumber: BigInt
413428
): Option[BigInt] = {
414429
if (blockNumberToCheck > 0) {
415430
val maybePreviousCheckpointBlockNumber = for {
@@ -432,19 +447,21 @@ class BlockchainImpl(
432447
}
433448

434449
private def removeTxsLocations(stxs: Seq[SignedTransaction]): DataSourceBatchUpdate = {
435-
stxs.map(_.hash).foldLeft(transactionMappingStorage.emptyBatchUpdate) {
436-
case (updates, hash) => updates.and(transactionMappingStorage.remove(hash))
450+
stxs.map(_.hash).foldLeft(transactionMappingStorage.emptyBatchUpdate) { case (updates, hash) =>
451+
updates.and(transactionMappingStorage.remove(hash))
437452
}
438453
}
439454

440455
override type S = InMemoryWorldStateProxyStorage
441456
override type WS = InMemoryWorldStateProxy
442457

443-
override def getWorldStateProxy(blockNumber: BigInt,
444-
accountStartNonce: UInt256,
445-
stateRootHash: Option[ByteString],
446-
noEmptyAccounts: Boolean,
447-
ethCompatibleStorage: Boolean): InMemoryWorldStateProxy =
458+
override def getWorldStateProxy(
459+
blockNumber: BigInt,
460+
accountStartNonce: UInt256,
461+
stateRootHash: Option[ByteString],
462+
noEmptyAccounts: Boolean,
463+
ethCompatibleStorage: Boolean
464+
): InMemoryWorldStateProxy =
448465
InMemoryWorldStateProxy(
449466
evmCodeStorage,
450467
stateStorage.getBackingStorage(blockNumber),
@@ -456,18 +473,20 @@ class BlockchainImpl(
456473
)
457474

458475
//FIXME Maybe we can use this one in regular execution too and persist underlying storage when block execution is successful
459-
override def getReadOnlyWorldStateProxy(blockNumber: Option[BigInt],
460-
accountStartNonce: UInt256,
461-
stateRootHash: Option[ByteString],
462-
noEmptyAccounts: Boolean,
463-
ethCompatibleStorage: Boolean): InMemoryWorldStateProxy =
476+
override def getReadOnlyWorldStateProxy(
477+
blockNumber: Option[BigInt],
478+
accountStartNonce: UInt256,
479+
stateRootHash: Option[ByteString],
480+
noEmptyAccounts: Boolean,
481+
ethCompatibleStorage: Boolean
482+
): InMemoryWorldStateProxy =
464483
InMemoryWorldStateProxy(
465484
evmCodeStorage,
466485
stateStorage.getReadOnlyStorage,
467486
accountStartNonce,
468487
(number: BigInt) => getBlockHeaderByNumber(number).map(_.hash),
469488
stateRootHash,
470-
noEmptyAccounts = false,
489+
noEmptyAccounts = noEmptyAccounts,
471490
ethCompatibleStorage = ethCompatibleStorage
472491
)
473492

0 commit comments

Comments
 (0)