Skip to content

Commit cf30683

Browse files
author
Aurélien Richez
authored
[ETCM-964] Fix preimage cache to make vmArithmeticTest pass (#1029)
* [ETCM-964] Fix preimage cache to make vmArithmeticTest pass
1 parent e3f1c38 commit cf30683

File tree

6 files changed

+73
-25
lines changed

6 files changed

+73
-25
lines changed

src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ class TestService(
117117
consensusConfig: ConsensusConfig,
118118
testModeComponentsProvider: TestModeComponentsProvider,
119119
initialConfig: BlockchainConfig,
120-
transactionMappingStorage: TransactionMappingStorage,
121-
preimageCache: collection.concurrent.Map[ByteString, UInt256]
120+
transactionMappingStorage: TransactionMappingStorage
122121
)(implicit
123122
scheduler: Scheduler
124123
) extends Logger {
@@ -131,6 +130,8 @@ class TestService(
131130
private var currentConfig: BlockchainConfig = initialConfig
132131
private var blockTimestamp: Long = 0
133132
private var sealEngine: SealEngineType = SealEngineType.NoReward
133+
private val preimageCache: collection.concurrent.Map[ByteString, UInt256] =
134+
new collection.concurrent.TrieMap[ByteString, UInt256]()
134135

135136
def setChainParams(request: SetChainParamsRequest): ServiceResponse[SetChainParamsResponse] = {
136137
currentConfig = buildNewConfig(request.chainParams.blockchainParams)
@@ -235,7 +236,9 @@ class TestService(
235236
def mineBlock(): Task[Unit] = {
236237
getBlockForMining(blockchain.getBestBlock().get)
237238
.flatMap(blockForMining =>
238-
testModeComponentsProvider.blockImport(currentConfig, sealEngine).importBlock(blockForMining.block)
239+
testModeComponentsProvider
240+
.blockImport(currentConfig, preimageCache, sealEngine)
241+
.importBlock(blockForMining.block)
239242
)
240243
.map { res =>
241244
log.info("Block mining result: " + res)
@@ -271,7 +274,7 @@ class TestService(
271274
Task.now(Left(JsonRpcError(-1, "block validation failed!", None)))
272275
case Success(value) =>
273276
testModeComponentsProvider
274-
.blockImport(currentConfig, sealEngine)
277+
.blockImport(currentConfig, preimageCache, sealEngine)
275278
.importBlock(value)
276279
.flatMap(handleResult)
277280
}

src/main/scala/io/iohk/ethereum/ledger/BlockExecution.scala

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,7 @@ class BlockExecution(
6363
parentHeader <- blockchainReader
6464
.getBlockHeaderByHash(block.header.parentHash)
6565
.toRight(MissingParentError) // Should not never occur because validated earlier
66-
initialWorld = InMemoryWorldStateProxy(
67-
evmCodeStorage = evmCodeStorage,
68-
blockchain.getBackingMptStorage(block.header.number),
69-
(number: BigInt) => blockchainReader.getBlockHeaderByNumber(number).map(_.hash),
70-
accountStartNonce = blockchainConfig.accountStartNonce,
71-
stateRootHash = parentHeader.stateRoot,
72-
noEmptyAccounts = EvmConfig.forBlock(parentHeader.number, blockchainConfig).noEmptyAccounts,
73-
ethCompatibleStorage = blockchainConfig.ethCompatibleStorage
74-
)
66+
initialWorld = buildInitialWorld(block, parentHeader)
7567
execResult <- executeBlockTransactions(block, initialWorld)
7668
worldToPersist <- Either
7769
.catchOnly[MPTException](blockPreparator.payBlockReward(block, execResult.worldState))
@@ -81,6 +73,18 @@ class BlockExecution(
8173
} yield execResult.copy(worldState = worldPersisted)
8274
}
8375

76+
protected def buildInitialWorld(block: Block, parentHeader: BlockHeader): InMemoryWorldStateProxy = {
77+
InMemoryWorldStateProxy(
78+
evmCodeStorage = evmCodeStorage,
79+
blockchain.getBackingMptStorage(block.header.number),
80+
(number: BigInt) => blockchainReader.getBlockHeaderByNumber(number).map(_.hash),
81+
accountStartNonce = blockchainConfig.accountStartNonce,
82+
stateRootHash = parentHeader.stateRoot,
83+
noEmptyAccounts = EvmConfig.forBlock(parentHeader.number, blockchainConfig).noEmptyAccounts,
84+
ethCompatibleStorage = blockchainConfig.ethCompatibleStorage
85+
)
86+
}
87+
8488
/** This function runs transactions
8589
*
8690
* @param block the block with transactions to run
@@ -144,7 +148,8 @@ class BlockExecution(
144148
* @param blocks blocks to be executed
145149
* @param parentChainWeight parent weight
146150
*
147-
* @return a list of blocks in incremental order that were correctly executed and an optional [[BlockExecutionError]]
151+
* @return a list of blocks in incremental order that were correctly executed and an optional
152+
* [[io.iohk.ethereum.ledger.BlockExecutionError]]
148153
*/
149154
def executeAndValidateBlocks(
150155
blocks: List[Block],

src/main/scala/io/iohk/ethereum/nodebuilder/NodeBuilder.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,7 @@ trait TestServiceBuilder {
427427
consensusConfig,
428428
testModeComponentsProvider,
429429
blockchainConfig,
430-
storagesInstance.storages.transactionMappingStorage,
431-
preimages
430+
storagesInstance.storages.transactionMappingStorage
432431
)(scheduler)
433432
}
434433

src/main/scala/io/iohk/ethereum/testmode/TestBlockchainBuilder.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
package io.iohk.ethereum.testmode
22

33
import akka.util.ByteString
4-
import io.iohk.ethereum.crypto
54
import io.iohk.ethereum.domain.{BlockchainImpl, UInt256}
6-
import io.iohk.ethereum.ledger.InMemoryWorldStateProxy
75
import io.iohk.ethereum.nodebuilder.{BlockchainBuilder, StorageBuilder}
86

97
trait TestBlockchainBuilder extends BlockchainBuilder {
108
self: StorageBuilder =>
119

12-
lazy val preimages: collection.concurrent.Map[ByteString, UInt256] =
13-
new collection.concurrent.TrieMap[ByteString, UInt256]()
14-
1510
override lazy val blockchain: BlockchainImpl = {
1611
val storages = storagesInstance.storages
1712
new BlockchainImpl(
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.iohk.ethereum.testmode
2+
3+
import akka.util.ByteString
4+
import io.iohk.ethereum.crypto
5+
import io.iohk.ethereum.db.storage.EvmCodeStorage
6+
import io.iohk.ethereum.domain.{Block, BlockHeader, BlockchainImpl, BlockchainReader, UInt256}
7+
import io.iohk.ethereum.ledger.{BlockExecution, BlockPreparator, BlockValidation, InMemoryWorldStateProxy}
8+
import io.iohk.ethereum.utils.BlockchainConfig
9+
import io.iohk.ethereum.vm.EvmConfig
10+
11+
class TestModeBlockExecution(
12+
blockchain: BlockchainImpl,
13+
blockchainReader: BlockchainReader,
14+
evmCodeStorage: EvmCodeStorage,
15+
blockchainConfig: BlockchainConfig,
16+
blockPreparator: BlockPreparator,
17+
blockValidation: BlockValidation,
18+
saveStoragePreimage: (UInt256) => Unit
19+
) extends BlockExecution(
20+
blockchain,
21+
blockchainReader,
22+
evmCodeStorage,
23+
blockchainConfig,
24+
blockPreparator,
25+
blockValidation
26+
) {
27+
28+
override protected def buildInitialWorld(block: Block, parentHeader: BlockHeader): InMemoryWorldStateProxy =
29+
TestModeWorldStateProxy(
30+
evmCodeStorage = evmCodeStorage,
31+
nodesKeyValueStorage = blockchain.getBackingMptStorage(block.header.number),
32+
getBlockHashByNumber = (number: BigInt) => blockchainReader.getBlockHeaderByNumber(number).map(_.hash),
33+
accountStartNonce = blockchainConfig.accountStartNonce,
34+
stateRootHash = parentHeader.stateRoot,
35+
noEmptyAccounts = EvmConfig.forBlock(parentHeader.number, blockchainConfig).noEmptyAccounts,
36+
ethCompatibleStorage = blockchainConfig.ethCompatibleStorage,
37+
saveStoragePreimage = saveStoragePreimage
38+
)
39+
}

src/main/scala/io/iohk/ethereum/testmode/TestModeComponentsProvider.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package io.iohk.ethereum.testmode
22

3+
import akka.util.ByteString
34
import io.iohk.ethereum.consensus.difficulty.DifficultyCalculator
45
import io.iohk.ethereum.consensus.{Consensus, ConsensusConfig}
6+
import io.iohk.ethereum.crypto
57
import io.iohk.ethereum.db.storage.EvmCodeStorage
6-
import io.iohk.ethereum.domain.{BlockchainImpl, BlockchainReader}
8+
import io.iohk.ethereum.domain.{BlockchainImpl, BlockchainReader, UInt256}
79
import io.iohk.ethereum.ledger.VMImpl
810
import io.iohk.ethereum.ledger.StxLedger
911
import io.iohk.ethereum.utils.BlockchainConfig
@@ -26,18 +28,23 @@ class TestModeComponentsProvider(
2628
vm: VMImpl
2729
) {
2830

29-
def blockImport(blockchainConfig: BlockchainConfig, sealEngine: SealEngineType): BlockImport = {
31+
def blockImport(
32+
blockchainConfig: BlockchainConfig,
33+
preimageCache: collection.concurrent.Map[ByteString, UInt256],
34+
sealEngine: SealEngineType
35+
): BlockImport = {
3036
val blockQueue = BlockQueue(blockchain, syncConfig)
3137
val consensuz = consensus(blockchainConfig, sealEngine)
3238
val blockValidation = new BlockValidation(consensuz, blockchainReader, blockQueue)
3339
val blockExecution =
34-
new BlockExecution(
40+
new TestModeBlockExecution(
3541
blockchain,
3642
blockchainReader,
3743
evmCodeStorage,
3844
blockchainConfig,
3945
consensuz.blockPreparator,
40-
blockValidation
46+
blockValidation,
47+
(key: UInt256) => preimageCache.put(crypto.kec256(key.bytes), key)
4148
)
4249

4350
new BlockImport(

0 commit comments

Comments
 (0)