Skip to content

Commit a7830e1

Browse files
committed
[ETCM-533] fix comments
1 parent 5020d40 commit a7830e1

File tree

6 files changed

+56
-28
lines changed

6 files changed

+56
-28
lines changed

src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package io.iohk.ethereum.txExecTest.util
22

33
import java.time.Clock
44
import java.util.concurrent.atomic.AtomicReference
5-
65
import akka.actor.ActorSystem
76
import akka.util.ByteString
87
import com.typesafe.config.ConfigFactory
@@ -15,6 +14,7 @@ import io.iohk.ethereum.db.storage.pruning.{ArchivePruning, PruningMode}
1514
import io.iohk.ethereum.db.storage.{AppStateStorage, StateStorage}
1615
import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields.HefEmpty
1716
import io.iohk.ethereum.domain.{Blockchain, UInt256, _}
17+
import io.iohk.ethereum.jsonrpc.ProofService.{StorageProof, StorageValueProof}
1818
import io.iohk.ethereum.ledger.{InMemoryWorldStateProxy, InMemoryWorldStateProxyStorage}
1919
import io.iohk.ethereum.mpt.MptNode
2020
import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo
@@ -150,7 +150,7 @@ class BlockchainMock(genesisHash: ByteString) extends Blockchain {
150150
rootHash: NodeHash,
151151
position: BigInt,
152152
ethCompatibleStorage: Boolean
153-
): (BigInt, Seq[MptNode]) = (BigInt(0), Seq.empty)
153+
): StorageProof = StorageValueProof(position)
154154

155155
override protected def getHashByBlockNumber(number: BigInt): Option[ByteString] = Some(genesisHash)
156156

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.iohk.ethereum.domain
22

33
import java.util.concurrent.atomic.AtomicReference
4-
54
import akka.util.ByteString
65
import cats.syntax.flatMap._
76
import cats.instances.option._
@@ -13,6 +12,7 @@ import io.iohk.ethereum.db.storage._
1312
import io.iohk.ethereum.db.storage.pruning.PruningMode
1413
import io.iohk.ethereum.domain
1514
import io.iohk.ethereum.domain.BlockchainImpl.BestBlockLatestCheckpointNumbers
15+
import io.iohk.ethereum.jsonrpc.ProofService.{StorageProof, StorageValueProof}
1616
import io.iohk.ethereum.ledger.{InMemoryWorldStateProxy, InMemoryWorldStateProxyStorage}
1717
import io.iohk.ethereum.mpt.{MerklePatriciaTrie, MptNode}
1818
import io.iohk.ethereum.utils.{ByteStringUtils, Logger}
@@ -105,7 +105,7 @@ trait Blockchain {
105105
rootHash: ByteString,
106106
position: BigInt,
107107
ethCompatibleStorage: Boolean
108-
): (BigInt, Seq[MptNode])
108+
): StorageProof
109109

110110
/**
111111
* Returns the receipts based on a block hash
@@ -313,16 +313,21 @@ class BlockchainImpl(
313313
rootHash: ByteString,
314314
position: BigInt,
315315
ethCompatibleStorage: Boolean
316-
): (BigInt, Seq[MptNode]) = {
317-
val defaultValue = BigInt(0)
316+
): StorageProof = {
318317
val storage: MptStorage = stateStorage.getBackingStorage(0)
319318
val mpt: MerklePatriciaTrie[BigInt, BigInt] = {
320319
if (ethCompatibleStorage) domain.EthereumUInt256Mpt.storageMpt(rootHash, storage)
321320
else domain.ArbitraryIntegerMpt.storageMpt(rootHash, storage)
322321
}
323-
val value = mpt.get(position).getOrElse(defaultValue)
324-
val proof = mpt.getProof(position).getOrElse(Seq.empty)
325-
(value, proof)
322+
val value = mpt.get(position)
323+
val proof = mpt.getProof(position)
324+
325+
(value, proof) match {
326+
case (Some(value), Some(proof)) => StorageValueProof(position, value, proof)
327+
case (None, Some(proof)) => StorageValueProof(position, proof = proof)
328+
case (Some(value), None) => StorageValueProof(position, value)
329+
case (None, None) => StorageValueProof(position)
330+
}
326331
}
327332

328333
private def persistBestBlocksData(): Unit = {

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

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,7 @@ import akka.util.ByteString
44
import cats.implicits._
55
import io.iohk.ethereum.consensus.blocks.BlockGenerator
66
import io.iohk.ethereum.domain.{Account, Address, Block, Blockchain, UInt256}
7-
import io.iohk.ethereum.jsonrpc.ProofService.{
8-
GetProofRequest,
9-
GetProofResponse,
10-
ProofAccount,
11-
StorageProof,
12-
StorageProofKey
13-
}
7+
import io.iohk.ethereum.jsonrpc.ProofService.{GetProofRequest, GetProofResponse, ProofAccount, StorageProof, StorageProofKey, StorageValueProof}
148
import io.iohk.ethereum.mpt.{MptNode, MptTraversals}
159
import monix.eval.Task
1610

@@ -30,21 +24,33 @@ object ProofService {
3024

3125
case class GetProofResponse(proofAccount: ProofAccount)
3226

33-
/** The key used to get the storage slot in its account tree */
34-
case class StorageProofKey(v: BigInt) extends AnyVal
35-
27+
trait StorageProof {
28+
val key: StorageProofKey
29+
val value: BigInt
30+
val proof: Seq[ByteString]
31+
}
3632
/**
3733
* Object proving a relationship of a storage value to an account's storageHash
3834
*
3935
* @param key storage proof key
4036
* @param value the value of the storage slot in its account tree
4137
* @param proof the set of node values needed to traverse a patricia merkle tree (from root to leaf) to retrieve a value
4238
*/
43-
case class StorageProof(
39+
case class StorageValueProof(
4440
key: StorageProofKey,
4541
value: BigInt,
46-
proof: Seq[ByteString]
47-
)
42+
proof: Seq[ByteString]) extends StorageProof
43+
44+
object StorageValueProof {
45+
def apply(key: BigInt, value: BigInt = BigInt(0), proof: => Seq[MptNode] = Seq.empty[MptNode]): StorageValueProof =
46+
new StorageValueProof(StorageProofKey(key), value, proof.map(asRlpSerializedNode))
47+
48+
def asRlpSerializedNode(node: MptNode): ByteString =
49+
ByteString(MptTraversals.encodeNode(node))
50+
}
51+
52+
/** The key used to get the storage slot in its account tree */
53+
case class StorageProofKey(v: BigInt) extends AnyVal
4854

4955
/**
5056
* The merkle proofs of the specified account connecting them to the blockhash of the block specified.
@@ -143,7 +149,7 @@ class EthProofService(blockchain: Blockchain, blockGenerator: BlockGenerator, et
143149
blockchain.getAccountProof(address, blockNumber).map(_.map(asRlpSerializedNode)),
144150
noAccountProof(address, blockNumber)
145151
)
146-
storageProof <- Either.right(getStorageProof(account, storageKeys))
152+
storageProof = getStorageProof(account, storageKeys)
147153
} yield ProofAccount(account, accountProof, storageProof, address)
148154
}
149155

@@ -158,9 +164,7 @@ class EthProofService(blockchain: Blockchain, blockGenerator: BlockGenerator, et
158164
rootHash = account.storageRoot,
159165
position = storageKey.v,
160166
ethCompatibleStorage = ethCompatibleStorage
161-
) match {
162-
case (value, proof) => StorageProof(storageKey, value, proof.map(asRlpSerializedNode))
163-
}
167+
)
164168
}
165169
}
166170

src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,24 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh
165165
}
166166
}
167167

168+
it should "return proof for non-existent account" in new EphemBlockchainTestSetup {
169+
val emptyMpt = MerklePatriciaTrie[Address, Account](
170+
storagesInstance.storages.stateStorage.getBackingStorage(0)
171+
)
172+
val mptWithAcc = emptyMpt.put(Address(42), Account.empty(UInt256(7)))
173+
174+
val headerWithAcc = Fixtures.Blocks.ValidBlock.header.copy(stateRoot = ByteString(mptWithAcc.getRootHash))
175+
176+
blockchain.storeBlockHeader(headerWithAcc).commit()
177+
178+
val wrongAddress = Address(666)
179+
val retrievedAccountProofWrong = blockchain.getAccountProof(wrongAddress, headerWithAcc.number)
180+
//the account doesn't exist, so we can't retrieve it, but we do receive a proof of non-existence with a full path of nodes that we iterated
181+
retrievedAccountProofWrong.isDefined shouldBe true
182+
retrievedAccountProofWrong.size shouldBe 1
183+
mptWithAcc.get(wrongAddress) shouldBe None
184+
}
185+
168186
it should "return correct best block number after applying and rollbacking blocks" in new TestSetup {
169187
forAll(intGen(min = 1: Int, max = maxNumberBlocksToImport)) { numberBlocksToImport =>
170188
val testSetup = newSetup()

src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import io.iohk.ethereum.jsonrpc.ProofService.{
1818
GetProofRequest,
1919
GetProofResponse,
2020
ProofAccount,
21-
StorageProof,
21+
StorageValueProof,
2222
StorageProofKey
2323
}
2424
import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.{
@@ -835,7 +835,7 @@ class JsonRpcControllerEthSpec
835835
nonce = 0,
836836
storageHash = ByteString(Hex.decode("1a2b3c")),
837837
storageProof = Seq(
838-
StorageProof(
838+
StorageValueProof(
839839
key = StorageProofKey(42),
840840
value = BigInt(2000),
841841
proof = Seq(

src/test/scala/io/iohk/ethereum/mpt/MerklePatriciaTrieSuite.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ class MerklePatriciaTrieSuite extends AnyFunSuite with ScalaCheckPropertyChecks
573573
val proof: Option[Vector[MptNode]] = trie.getProof(key4)
574574
// then
575575
assert(proof.isDefined)
576+
assert(proof.get.nonEmpty)
576577
}
577578

578579
test("getProof returns valid proof for existing key") {

0 commit comments

Comments
 (0)