Skip to content

Commit

Permalink
[ETCM-533] refactor StorageProof ADT
Browse files Browse the repository at this point in the history
  • Loading branch information
bsuieric committed Jan 26, 2021
1 parent 4ba7d45 commit 72b6a87
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 30 deletions.
Expand Up @@ -14,7 +14,7 @@ import io.iohk.ethereum.db.storage.pruning.{ArchivePruning, PruningMode}
import io.iohk.ethereum.db.storage.{AppStateStorage, StateStorage}
import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields.HefEmpty
import io.iohk.ethereum.domain.{Blockchain, UInt256, _}
import io.iohk.ethereum.jsonrpc.ProofService.{StorageProof, StorageValueProof}
import io.iohk.ethereum.jsonrpc.ProofService.{EmptyStorageValueProof, StorageProof, StorageProofKey, StorageValueProof}
import io.iohk.ethereum.ledger.{InMemoryWorldStateProxy, InMemoryWorldStateProxyStorage}
import io.iohk.ethereum.mpt.MptNode
import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo
Expand Down Expand Up @@ -150,7 +150,7 @@ class BlockchainMock(genesisHash: ByteString) extends Blockchain {
rootHash: NodeHash,
position: BigInt,
ethCompatibleStorage: Boolean
): StorageProof = StorageValueProof(position)
): StorageProof = EmptyStorageValueProof(StorageProofKey(position))

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

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/io/iohk/ethereum/domain/Blockchain.scala
Expand Up @@ -12,7 +12,7 @@ import io.iohk.ethereum.db.storage._
import io.iohk.ethereum.db.storage.pruning.PruningMode
import io.iohk.ethereum.domain
import io.iohk.ethereum.domain.BlockchainImpl.BestBlockLatestCheckpointNumbers
import io.iohk.ethereum.jsonrpc.ProofService.{StorageProof, StorageValueProof}
import io.iohk.ethereum.jsonrpc.ProofService.StorageProof
import io.iohk.ethereum.ledger.{InMemoryWorldStateProxy, InMemoryWorldStateProxyStorage}
import io.iohk.ethereum.mpt.{MerklePatriciaTrie, MptNode}
import io.iohk.ethereum.utils.{ByteStringUtils, Logger}
Expand Down Expand Up @@ -321,7 +321,7 @@ class BlockchainImpl(
}
val value: Option[BigInt] = mpt.get(position)
val proof: Option[Vector[MptNode]] = mpt.getProof(position)
StorageValueProof(position, value, proof)
StorageProof(position, value, proof)
}

private def persistBestBlocksData(): Unit = {
Expand Down
55 changes: 29 additions & 26 deletions src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala
Expand Up @@ -4,7 +4,7 @@ import akka.util.ByteString
import cats.implicits._
import io.iohk.ethereum.consensus.blocks.BlockGenerator
import io.iohk.ethereum.domain.{Account, Address, Block, Blockchain, UInt256}
import io.iohk.ethereum.jsonrpc.ProofService.StorageValueProof.asRlpSerializedNode
import io.iohk.ethereum.jsonrpc.ProofService.StorageProof.asRlpSerializedNode
import io.iohk.ethereum.jsonrpc.ProofService.{
GetProofRequest,
GetProofResponse,
Expand Down Expand Up @@ -33,42 +33,45 @@ object ProofService {
case class GetProofResponse(proofAccount: ProofAccount)

sealed trait StorageProof {
val key: StorageProofKey
val value: BigInt
val proof: Seq[ByteString]
def key: StorageProofKey
def value: BigInt
def proof: Seq[ByteString]
}

/**
* Object proving a relationship of a storage value to an account's storageHash
*
* @param key storage proof key
* @param value the value of the storage slot in its account tree
* @param proof the set of node values needed to traverse a patricia merkle tree (from root to leaf) to retrieve a value
*/
case class StorageValueProof(
key: StorageProofKey,
value: BigInt = BigInt(0),
proof: Seq[ByteString] = Seq.empty[MptNode].map(asRlpSerializedNode)
) extends StorageProof

object StorageValueProof {
def apply(position: BigInt, value: Option[BigInt], proof: Option[Vector[MptNode]]): StorageValueProof =
object StorageProof {
def apply(position: BigInt, value: Option[BigInt], proof: Option[Vector[MptNode]]): StorageProof =
(value, proof) match {
case (Some(value), Some(proof)) =>
new StorageValueProof(key = StorageProofKey(position), value = value, proof = proof.map(asRlpSerializedNode))
StorageValueProof(StorageProofKey(position), value, proof.map(asRlpSerializedNode))
case (None, Some(proof)) =>
new StorageValueProof(key = StorageProofKey(position), proof = proof.map(asRlpSerializedNode))
case (Some(value), None) => new StorageValueProof(key = StorageProofKey(position), value = value)
case (None, None) => new StorageValueProof(key = StorageProofKey(position))
EmptyStorageValue(StorageProofKey(position), proof.map(asRlpSerializedNode))
case (Some(value), None) => EmptyStorageProof(StorageProofKey(position), value)
case (None, None) => EmptyStorageValueProof(StorageProofKey(position))
}

def apply(position: BigInt): StorageValueProof =
new StorageValueProof(key = StorageProofKey(position))

def asRlpSerializedNode(node: MptNode): ByteString =
ByteString(MptTraversals.encodeNode(node))
}

/**
* Object proving a relationship of a storage value to an account's storageHash
*
* @param key storage proof key
* @param value the value of the storage slot in its account tree
* @param proof the set of node values needed to traverse a patricia merkle tree (from root to leaf) to retrieve a value
*/
case class EmptyStorageValueProof(key: StorageProofKey) extends StorageProof {
val value: BigInt = BigInt(0)
val proof: Seq[ByteString] = Seq.empty[MptNode].map(asRlpSerializedNode)
}
case class EmptyStorageValue(key: StorageProofKey, proof: Seq[ByteString]) extends StorageProof {
val value: BigInt = BigInt(0)
}
case class EmptyStorageProof(key: StorageProofKey, value: BigInt) extends StorageProof {
val proof: Seq[ByteString] = Seq.empty[MptNode].map(asRlpSerializedNode)
}
case class StorageValueProof(key: StorageProofKey, value: BigInt, proof: Seq[ByteString]) extends StorageProof

/** The key used to get the storage slot in its account tree */
case class StorageProofKey(v: BigInt) extends AnyVal

Expand Down

0 comments on commit 72b6a87

Please sign in to comment.