Skip to content

Commit 2492b3d

Browse files
committed
[ETCM-533] testing the proof and value for non existing account and/or storage keys
1 parent c7bd863 commit 2492b3d

File tree

1 file changed

+107
-59
lines changed

1 file changed

+107
-59
lines changed

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

Lines changed: 107 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
package io.iohk.ethereum.jsonrpc
22

33
import akka.actor.ActorSystem
4-
import akka.testkit.{TestKit, TestProbe}
4+
import akka.testkit.TestKit
55
import akka.util.ByteString
66
import com.softwaremill.diffx.scalatest.DiffMatcher
7+
import io.iohk.ethereum._
78
import io.iohk.ethereum.blockchain.sync.EphemBlockchainTestSetup
8-
import io.iohk.ethereum.consensus._
99
import io.iohk.ethereum.consensus.ethash.blocks.EthashBlockGenerator
10-
import io.iohk.ethereum.domain.{Account, Address, Block, EthereumUInt256Mpt, UInt256}
11-
import io.iohk.ethereum.jsonrpc.server.controllers.JsonRpcBaseController.JsonRpcConfig
12-
import io.iohk.ethereum.keystore.KeyStore
13-
import io.iohk.ethereum.ledger.{Ledger, StxLedger}
10+
import io.iohk.ethereum.domain._
11+
import io.iohk.ethereum.jsonrpc.EthUserService.{GetBalanceRequest, GetBalanceResponse, GetStorageAtRequest, GetTransactionCountRequest}
12+
import io.iohk.ethereum.jsonrpc.ProofService.{GetProofRequest, StorageProofKey}
13+
import io.iohk.ethereum.ledger.Ledger
1414
import io.iohk.ethereum.mpt.MerklePatriciaTrie
1515
import io.iohk.ethereum.nodebuilder.ApisBuilder
16-
import io.iohk.ethereum.utils._
17-
import io.iohk.ethereum._
18-
import io.iohk.ethereum.jsonrpc.ProofService.{GetProofRequest, StorageProofKey}
1916
import monix.execution.Scheduler.Implicits.global
2017
import org.bouncycastle.util.encoders.Hex
2118
import org.scalactic.TypeCheckedTripleEquals
@@ -24,11 +21,7 @@ import org.scalatest.OptionValues
2421
import org.scalatest.concurrent.ScalaFutures
2522
import org.scalatest.flatspec.AnyFlatSpecLike
2623
import org.scalatest.matchers.should.Matchers
27-
28-
import io.iohk.ethereum.jsonrpc.EthUserService.GetBalanceResponse
29-
import io.iohk.ethereum.jsonrpc.EthUserService.GetBalanceRequest
30-
import io.iohk.ethereum.jsonrpc.EthUserService.GetTransactionCountRequest
31-
import io.iohk.ethereum.jsonrpc.EthUserService.GetStorageAtRequest
24+
import io.iohk.ethereum.mpt.MerklePatriciaTrie.defaultByteArraySerializable
3225

3326
class EthProofServiceSpec
3427
extends TestKit(ActorSystem("EthGetProofSpec_ActorSystem"))
@@ -43,49 +36,9 @@ class EthProofServiceSpec
4336
with DiffMatcher {
4437

4538
"EthProofService" should "handle getStorageAt request" in new TestSetup {
46-
// given
47-
val address = Address(ByteString(Hex.decode("abbb6bebfa05aa13e908eaa492bd7a8343760477")))
48-
49-
val key = 333
50-
val value = 123
51-
52-
val storageMpt = EthereumUInt256Mpt
53-
.storageMpt(
54-
ByteString(MerklePatriciaTrie.EmptyRootHash),
55-
storagesInstance.storages.stateStorage.getBackingStorage(0)
56-
)
57-
.put(UInt256(key), UInt256(value))
58-
59-
val account = Account(
60-
nonce = 0,
61-
balance = UInt256(0),
62-
storageRoot = ByteString(storageMpt.getRootHash),
63-
codeHash = ByteString("")
64-
)
65-
66-
import MerklePatriciaTrie.defaultByteArraySerializable
67-
val mpt =
68-
MerklePatriciaTrie[Array[Byte], Account](storagesInstance.storages.stateStorage.getBackingStorage(0))
69-
.put(
70-
crypto.kec256(address.bytes.toArray[Byte]),
71-
account
72-
)
73-
74-
val blockToRequest = Block(Fixtures.Blocks.Block3125369.header, Fixtures.Blocks.Block3125369.body)
75-
val newBlockHeader = blockToRequest.header.copy(stateRoot = ByteString(mpt.getRootHash))
76-
val newblock = blockToRequest.copy(header = newBlockHeader)
77-
blockchain.storeBlock(newblock).commit()
78-
blockchain.saveBestKnownBlocks(newblock.header.number)
79-
80-
val ethGetProof = new EthProofService(blockchain, blockGenerator, blockchainConfig.ethCompatibleStorage)
81-
val storageKeys = Seq(StorageProofKey(key))
82-
val blockNumber = BlockParam.Latest
8339
val request = GetProofRequest(address, storageKeys, blockNumber)
84-
85-
// when
8640
val result = ethGetProof.getProof(request)
8741

88-
// then
8942
val balanceResponse: GetBalanceResponse = ethUserService
9043
.getBalance(GetBalanceRequest(address, BlockParam.Latest))
9144
.runSyncUnsafe()
@@ -125,18 +78,113 @@ class EthProofServiceSpec
12578
}
12679

12780
"EthProofService" should "return an error when the proof is requested for non-existing account" in new TestSetup {
128-
val ethGetProof = new EthProofService(blockchain, blockGenerator, blockchainConfig.ethCompatibleStorage)
129-
val key = 999
130-
val storageKeys = Seq(StorageProofKey(key))
131-
val blockNumber = BlockParam.Latest
13281
val wrongAddress = Address(666)
13382
val request = GetProofRequest(wrongAddress, storageKeys, blockNumber)
13483
val retrievedAccountProofWrong: ServiceResponse[ProofService.GetProofResponse] = ethGetProof.getProof(request)
135-
retrievedAccountProofWrong.runSyncUnsafe().isLeft shouldBe true
84+
val result = retrievedAccountProofWrong.runSyncUnsafe()
85+
86+
result.isLeft shouldBe true
87+
result.fold(l => l.message should include("No account found for Address"), r => r)
88+
}
89+
90+
"EthProofService" should "return the proof with empty value for non-existing storage key" in new TestSetup {
91+
val wrongStorageKey = Seq(StorageProofKey(321))
92+
val request = GetProofRequest(address, wrongStorageKey, blockNumber)
93+
val retrievedAccountProofWrong: ServiceResponse[ProofService.GetProofResponse] = ethGetProof.getProof(request)
94+
val result = retrievedAccountProofWrong.runSyncUnsafe()
95+
result.isRight shouldBe true
96+
result.fold(l => l, r => r.proofAccount.storageProof.map(v => {
97+
v.proof.nonEmpty shouldBe true
98+
v.value shouldBe BigInt(0)
99+
}))
100+
}
101+
102+
"EthProofService" should "return the proof and value for existing storage key" in new TestSetup {
103+
val storageKey = Seq(StorageProofKey(key))
104+
val request = GetProofRequest(address, storageKey, blockNumber)
105+
val retrievedAccountProofWrong: ServiceResponse[ProofService.GetProofResponse] = ethGetProof.getProof(request)
106+
val result = retrievedAccountProofWrong.runSyncUnsafe()
107+
result.isRight shouldBe true
108+
result.fold(l => l, r => r.proofAccount.storageProof.map(v => {
109+
v.proof.nonEmpty shouldBe true
110+
v.value shouldBe BigInt(value)
111+
}))
112+
}
113+
114+
"EthProofService" should "return the proof and value for multiple existing storage keys" in new TestSetup {
115+
val storageKey = Seq(StorageProofKey(key), StorageProofKey(key2))
116+
val expectedValueStorageKey = Seq(BigInt(value), BigInt(value2))
117+
val request = GetProofRequest(address, storageKey, blockNumber)
118+
val retrievedAccountProofWrong: ServiceResponse[ProofService.GetProofResponse] = ethGetProof.getProof(request)
119+
val result = retrievedAccountProofWrong.runSyncUnsafe()
120+
result.isRight shouldBe true
121+
result.fold(l => l, r => {
122+
r.proofAccount.storageProof.size shouldBe 2
123+
r.proofAccount.storageProof.map(v => {
124+
v.proof.nonEmpty shouldBe true
125+
expectedValueStorageKey should contain(v.value)
126+
})
127+
})
128+
}
129+
130+
"EthProofService" should "return the proof for all storage keys provided, but value should be returned only for the existing ones" in new TestSetup {
131+
val wrongStorageKey = StorageProofKey(321)
132+
val storageKey = Seq(StorageProofKey(key), StorageProofKey(key2)) :+ wrongStorageKey
133+
val expectedValueStorageKey = Seq(BigInt(value), BigInt(value2), BigInt(0))
134+
val request = GetProofRequest(address, storageKey, blockNumber)
135+
val retrievedAccountProofWrong: ServiceResponse[ProofService.GetProofResponse] = ethGetProof.getProof(request)
136+
val result = retrievedAccountProofWrong.runSyncUnsafe()
137+
result.isRight shouldBe true
138+
result.fold(l => l, r => {
139+
r.proofAccount.storageProof.size shouldBe 3
140+
expectedValueStorageKey.forall(r.proofAccount.storageProof.map(_.value).contains) shouldBe true
141+
})
136142
}
137143

138144
class TestSetup(implicit system: ActorSystem) extends MockFactory with EphemBlockchainTestSetup with ApisBuilder {
145+
139146
val blockGenerator = mock[EthashBlockGenerator]
147+
val address = Address(ByteString(Hex.decode("abbb6bebfa05aa13e908eaa492bd7a8343760477")))
148+
149+
val key = 333
150+
val value = 123
151+
val key1 = 334
152+
val value1 = 124
153+
val key2 = 335
154+
val value2 = 125
155+
156+
val storageMpt = EthereumUInt256Mpt
157+
.storageMpt(
158+
ByteString(MerklePatriciaTrie.EmptyRootHash),
159+
storagesInstance.storages.stateStorage.getBackingStorage(0)
160+
)
161+
.put(UInt256(key), UInt256(value))
162+
.put(UInt256(key1), UInt256(value1))
163+
.put(UInt256(key2), UInt256(value2))
164+
165+
val account = Account(
166+
nonce = 0,
167+
balance = UInt256(0),
168+
storageRoot = ByteString(storageMpt.getRootHash)
169+
)
170+
171+
val mpt =
172+
MerklePatriciaTrie[Array[Byte], Account](storagesInstance.storages.stateStorage.getBackingStorage(0))
173+
.put(
174+
crypto.kec256(address.bytes.toArray[Byte]),
175+
account
176+
)
177+
178+
val blockToRequest = Block(Fixtures.Blocks.Block3125369.header, Fixtures.Blocks.Block3125369.body)
179+
val newBlockHeader = blockToRequest.header.copy(stateRoot = ByteString(mpt.getRootHash))
180+
val newblock = blockToRequest.copy(header = newBlockHeader)
181+
blockchain.storeBlock(newblock).commit()
182+
blockchain.saveBestKnownBlocks(newblock.header.number)
183+
184+
val ethGetProof = new EthProofService(blockchain, blockGenerator, blockchainConfig.ethCompatibleStorage)
185+
186+
val storageKeys = Seq(StorageProofKey(key))
187+
val blockNumber = BlockParam.Latest
140188

141189
override lazy val ledger = mock[Ledger]
142190

0 commit comments

Comments
 (0)