Skip to content

Commit

Permalink
move getAccountProof into BlockchainReader
Browse files Browse the repository at this point in the history
  • Loading branch information
Aurélien Richez committed Jul 29, 2021
1 parent 4d57db1 commit e4dfd4b
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 19 deletions.
Expand Up @@ -81,7 +81,7 @@ object FastSyncItSpecUtils {
val accountExpectedCode = ByteString(i.toByteArray)
val codeHash = kec256(accountExpectedCode)
val accountExpectedStorageAddresses = (i until i + 20).toList
val account = blockchainReader.getAccount(accountAddress, blockNumber).get
val account = blockchainReader.getAccount(blockchainReader.getBestBranch(), accountAddress, blockNumber).get
val code = evmCodeStorage.get(codeHash).get
val storedData = accountExpectedStorageAddresses.map { addr =>
ByteUtils.toBigInt(bl.getAccountStorageAt(account.storageRoot, addr, ethCompatibleStorage = true))
Expand Down
14 changes: 0 additions & 14 deletions src/main/scala/io/iohk/ethereum/domain/Blockchain.scala
Expand Up @@ -27,8 +27,6 @@ trait Blockchain {
type S <: Storage[S]
type WS <: WorldStateProxy[WS, S]

def getAccountProof(address: Address, blockNumber: BigInt): Option[Vector[MptNode]]

/** Get account storage at given position
*
* @param rootHash storage root hash
Expand Down Expand Up @@ -92,18 +90,6 @@ class BlockchainImpl(
override def getLatestCheckpointBlockNumber(): BigInt =
blockchainMetadata.bestKnownBlockAndLatestCheckpoint.get().latestCheckpointNumber

override def getAccountProof(address: Address, blockNumber: BigInt): Option[Vector[MptNode]] =
getAccountMpt(blockNumber) >>= (_.getProof(address))

private def getAccountMpt(blockNumber: BigInt): Option[MerklePatriciaTrie[Address, Account]] =
blockchainReader.getBlockHeaderByNumber(blockNumber).map { bh =>
val storage = stateStorage.getBackingStorage(blockNumber)
MerklePatriciaTrie[Address, Account](
rootHash = bh.stateRoot.toArray,
source = storage
)
}

override def getAccountStorageAt(
rootHash: ByteString,
position: BigInt,
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala
Expand Up @@ -157,6 +157,9 @@ class BlockchainReader(
case EmptyBranch => None
}

def getAccountProof(branch: Branch, address: Address, blockNumber: BigInt): Option[Vector[MptNode]] =
getAccountMpt(blockNumber).flatMap(_.getProof(address))

/** Allows to query for a block based on it's number
*
* @param number Block number
Expand Down
Expand Up @@ -172,7 +172,9 @@ class EthProofService(
noAccount(address, blockNumber)
)
accountProof <- Either.fromOption(
blockchain.getAccountProof(address, blockNumber).map(_.map(asRlpSerializedNode)),
blockchainReader
.getAccountProof(blockchainReader.getBestBranch(), address, blockNumber)
.map(_.map(asRlpSerializedNode)),
noAccountProof(address, blockNumber)
)
storageProof = getStorageProof(account, storageKeys)
Expand Down
9 changes: 6 additions & 3 deletions src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala
Expand Up @@ -174,14 +174,16 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh

//unhappy path
val wrongAddress = Address(666)
val retrievedAccountProofWrong = blockchain.getAccountProof(wrongAddress, headerWithAcc.number)
val retrievedAccountProofWrong =
blockchainReader.getAccountProof(blockchainReader.getBestBranch(), wrongAddress, headerWithAcc.number)
//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
retrievedAccountProofWrong.isDefined shouldBe true
retrievedAccountProofWrong.size shouldBe 1
mptWithAcc.get(wrongAddress) shouldBe None

//happy path
val retrievedAccountProof = blockchain.getAccountProof(address, headerWithAcc.number)
val retrievedAccountProof =
blockchainReader.getAccountProof(blockchainReader.getBestBranch(), address, headerWithAcc.number)
retrievedAccountProof.isDefined shouldBe true
retrievedAccountProof.map { proof =>
MptProofVerifier.verifyProof(mptWithAcc.getRootHash, address, proof) shouldBe ValidProof
Expand All @@ -199,7 +201,8 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh
blockchainWriter.storeBlockHeader(headerWithAcc).commit()

val wrongAddress = Address(666)
val retrievedAccountProofWrong = blockchain.getAccountProof(wrongAddress, headerWithAcc.number)
val retrievedAccountProofWrong =
blockchainReader.getAccountProof(blockchainReader.getBestBranch(), wrongAddress, headerWithAcc.number)
//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(root node) that we iterated
(retrievedAccountProofWrong.getOrElse(Vector.empty).toList match {
case _ @HashNode(_) :: Nil => true
Expand Down

0 comments on commit e4dfd4b

Please sign in to comment.