Skip to content

Commit

Permalink
Change getStorageProof impl
Browse files Browse the repository at this point in the history
  • Loading branch information
AnastasiiaL authored and bsuieric committed Jan 26, 2021
1 parent f665195 commit 5df1b54
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 25 deletions.
Expand Up @@ -150,7 +150,7 @@ class BlockchainMock(genesisHash: ByteString) extends Blockchain {
rootHash: NodeHash,
position: BigInt,
ethCompatibleStorage: Boolean
): Option[(BigInt, Seq[MptNode])] = None
): (BigInt, Seq[MptNode]) = (1, Seq.empty)

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

Expand Down
18 changes: 12 additions & 6 deletions src/main/scala/io/iohk/ethereum/domain/Blockchain.scala
Expand Up @@ -95,11 +95,17 @@ trait Blockchain {
*/
def getAccountStorageAt(rootHash: ByteString, position: BigInt, ethCompatibleStorage: Boolean): ByteString

/**
* Get a storage-value and its proof being the path from the root node until the last matching node.
*
* @param rootHash storage root hash
* @param position storage position
*/
def getStorageProofAt(
rootHash: ByteString,
position: BigInt,
ethCompatibleStorage: Boolean
): Option[(BigInt, Seq[MptNode])]
): (BigInt, Seq[MptNode])

/**
* Returns the receipts based on a block hash
Expand Down Expand Up @@ -307,16 +313,16 @@ class BlockchainImpl(
rootHash: ByteString,
position: BigInt,
ethCompatibleStorage: Boolean
): Option[(BigInt, Seq[MptNode])] = {
): (BigInt, Seq[MptNode]) = {
val defaultValue = BigInt(0)
val storage: MptStorage = stateStorage.getBackingStorage(0)
val mpt: MerklePatriciaTrie[BigInt, BigInt] = {
if (ethCompatibleStorage) domain.EthereumUInt256Mpt.storageMpt(rootHash, storage)
else domain.ArbitraryIntegerMpt.storageMpt(rootHash, storage)
}
for {
value <- mpt.get(position)
proof <- mpt.getProof(position)
} yield (value, proof)
val value = mpt.get(position).getOrElse(defaultValue)
val proof = mpt.getProof(position).getOrElse(Seq.empty)
(value, proof)
}

private def persistBestBlocksData(): Unit = {
Expand Down
Expand Up @@ -4,9 +4,7 @@ import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams
import io.iohk.ethereum.jsonrpc.ProofService.{GetProofRequest, GetProofResponse, StorageProofKey}
import io.iohk.ethereum.jsonrpc.serialization.JsonEncoder
import io.iohk.ethereum.jsonrpc.serialization.JsonMethodDecoder
import org.json4s.Extraction
import org.json4s.JsonAST.{JArray, JString, JValue, _}
import org.json4s.JsonDSL._

object EthProofJsonMethodsImplicits extends JsonMethodsImplicits {
def extractStorageKeys(input: JValue): Either[JsonRpcError, Seq[StorageProofKey]] = {
Expand Down
19 changes: 7 additions & 12 deletions src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala
Expand Up @@ -143,37 +143,32 @@ class EthProofService(blockchain: Blockchain, blockGenerator: BlockGenerator, et
blockchain.getAccountProof(address, blockNumber).map(_.map(asRlpSerializedNode)),
noAccountProof(address, blockNumber)
)
storageProof <- getStorageProof(account, storageKeys)
storageProof <- Either.right(getStorageProof(account, storageKeys))
} yield ProofAccount(account, accountProof, storageProof, address)
}

def getStorageProof(
account: Account,
storageKeys: Seq[StorageProofKey]
): Either[JsonRpcError, Seq[StorageProof]] = {
): Seq[StorageProof] = {
storageKeys.toList
.map { storageKey =>
blockchain
.getStorageProofAt(
rootHash = account.storageRoot,
position = storageKey.v,
ethCompatibleStorage = ethCompatibleStorage
)
.map { case (value, proof) => StorageProof(storageKey, value, proof.map(asRlpSerializedNode)) }
.toRight(noStorageProof(account, storageKey))
) match {
case (value, proof) => StorageProof(storageKey, value, proof.map(asRlpSerializedNode))
}
}
.sequence
.map(_.toSeq)
}

private def noStorageProof(account: Account, storagekey: StorageProofKey): JsonRpcError =
JsonRpcError.LogicError(s"No storage proof for [${account.toString}] storage key [${storagekey.toString}]")

private def noAccount(address: Address, blockNumber: BigInt): JsonRpcError =
JsonRpcError.LogicError(s"No storage proof for Address [${address.toString}] blockNumber [${blockNumber.toString}]")
JsonRpcError.LogicError(s"No account found for Address [${address.toString}] blockNumber [${blockNumber.toString}]")

private def noAccountProof(address: Address, blockNumber: BigInt): JsonRpcError =
JsonRpcError.LogicError(s"No storage proof for Address [${address.toString}] blockNumber [${blockNumber.toString}]")
JsonRpcError.LogicError(s"No account proof for Address [${address.toString}] blockNumber [${blockNumber.toString}]")

private def asRlpSerializedNode(node: MptNode): ByteString =
ByteString(MptTraversals.encodeNode(node))
Expand Down
Expand Up @@ -25,7 +25,6 @@ import org.scalatest.concurrent.ScalaFutures
import org.scalatest.flatspec.AnyFlatSpecLike
import org.scalatest.matchers.should.Matchers

import scala.concurrent.duration.{DurationInt, FiniteDuration}
import io.iohk.ethereum.jsonrpc.EthUserService.GetBalanceResponse
import io.iohk.ethereum.jsonrpc.EthUserService.GetBalanceRequest
import io.iohk.ethereum.jsonrpc.EthUserService.GetTransactionCountRequest
Expand Down
Expand Up @@ -803,13 +803,15 @@ class JsonRpcControllerEthSpec
}

it should "decode and encode eth_getProof request and response" in new JsonRpcControllerFixture {
val address = "0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842"

val request: JsonRpcRequest = JsonRpcRequest(
jsonrpc = "2.0",
method = "eth_getProof",
params = Some(
JArray(
List(
JString("0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842"),
JString(address),
JArray(List(JString("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"))),
JString("latest")
)
Expand All @@ -819,14 +821,14 @@ class JsonRpcControllerEthSpec
)

val expectedDecodedRequest = GetProofRequest(
address = Address("0x7f0d15c7faae65896648c8273b6d7e43f58fa842"),
address = Address(address),
storageKeys =
List(StorageProofKey(BigInt("39309028074332508661983559455579427211983204215636056653337583610388178777121"))),
blockNumber = BlockParam.Latest
)
val expectedEncodedResponse: GetProofResponse = GetProofResponse(
ProofAccount(
address = Address("0x7f0d15c7faae65896648c8273b6d7e43f58fa842"),
address = Address(address),
accountProof = Seq(ByteString(Hex.decode("1234"))),
balance = BigInt(0x0),
codeHash = ByteString(Hex.decode("123eeaa22a")),
Expand Down

0 comments on commit 5df1b54

Please sign in to comment.