Skip to content

Commit 28e9342

Browse files
Igor Grahovacdzajkowski
authored andcommitted
ETCM-697: Added separate transaction response class that includes signature fields required by retesteth
1 parent f779c60 commit 28e9342

File tree

6 files changed

+150
-16
lines changed

6 files changed

+150
-16
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ trait BaseBlockResponse {
2828
def gasLimit: BigInt
2929
def gasUsed: BigInt
3030
def timestamp: BigInt
31-
def transactions: Either[Seq[ByteString], Seq[TransactionResponse]]
31+
def transactions: Either[Seq[ByteString], Seq[BaseTransactionResponse]]
3232
def uncles: Seq[ByteString]
3333
}
3434

@@ -51,7 +51,7 @@ case class EthBlockResponse(
5151
gasLimit: BigInt,
5252
gasUsed: BigInt,
5353
timestamp: BigInt,
54-
transactions: Either[Seq[ByteString], Seq[TransactionResponse]],
54+
transactions: Either[Seq[ByteString], Seq[BaseTransactionResponse]],
5555
uncles: Seq[ByteString]
5656
) extends BaseBlockResponse
5757

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ case class JsonRpcController(
251251
handle[SetEtherbaseRequest, SetEtherbaseResponse](testService.setEtherbase, req)
252252
case req @ JsonRpcRequest(_, "debug_accountRange", _, _) =>
253253
handle[AccountsInRangeRequest, AccountsInRangeResponse](testService.getAccountsInRange, req)
254+
case req @ JsonRpcRequest(_, "debug_storageRangeAt", _, _) =>
255+
handle[StorageRangeRequest, StorageRangeResponse](testService.storageRangeAt, req)
254256
}
255257

256258
private def handleIeleRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = {

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import io.iohk.ethereum.blockchain.data.GenesisAccount
1111

1212
import scala.util.Try
1313
import io.iohk.ethereum.domain.UInt256
14+
import org.json4s.Extraction
1415

1516
object TestJsonMethodsImplicits extends JsonMethodsImplicits {
1617

@@ -60,6 +61,8 @@ object TestJsonMethodsImplicits extends JsonMethodsImplicits {
6061
blockReward <- optionalQuantity(blockchainParamsJson \ "blockReward")
6162
byzantiumForkBlock <- extractQuantity(blockchainParamsJson \ "byzantiumForkBlock")
6263
homesteadForkBlock <- extractQuantity(blockchainParamsJson \ "homesteadForkBlock")
64+
constantinopleForkBlock <- extractQuantity(blockchainParamsJson \ "constantinopleForkBlock")
65+
istanbulForkBlock <- extractQuantity(blockchainParamsJson \ "istanbulForkBlock")
6366
} yield BlockchainParams(
6467
eIP150ForkBlock,
6568
eIP158ForkBlock,
@@ -68,7 +71,9 @@ object TestJsonMethodsImplicits extends JsonMethodsImplicits {
6871
blockReward.getOrElse(0),
6972
byzantiumForkBlock,
7073
homesteadForkBlock,
71-
0
74+
0,
75+
constantinopleForkBlock,
76+
istanbulForkBlock
7277
)
7378
}
7479

@@ -187,4 +192,28 @@ object TestJsonMethodsImplicits extends JsonMethodsImplicits {
187192
"nextKey" -> encodeAsHex(t.nextKey)
188193
)
189194
}
195+
196+
implicit val debug_storageRangeAt = new JsonMethodDecoder[StorageRangeRequest]
197+
with JsonEncoder[StorageRangeResponse] {
198+
override def decodeJson(params: Option[JArray]): Either[JsonRpcError, StorageRangeRequest] =
199+
params match {
200+
case Some(JArray(blockHashOrNumber :: txIndex :: address :: begin :: maxResults :: Nil)) =>
201+
for {
202+
txIndex <- extractQuantity(txIndex)
203+
maxResults <- extractQuantity(maxResults)
204+
begin <- extractQuantity(begin)
205+
addressHash <- extractBytes(address.extract[String])
206+
blockHashOrNumberEither = extractBlockHashOrNumber(blockHashOrNumber.extract[String])
207+
} yield StorageRangeRequest(
208+
StorageRangeParams(blockHashOrNumberEither, txIndex, addressHash, begin, maxResults)
209+
)
210+
case _ => Left(InvalidParams())
211+
}
212+
213+
private def extractBlockHashOrNumber(blockHash: String): Either[BigInt, ByteString] =
214+
extractHash(blockHash)
215+
.fold(_ => Left(BigInt(blockHash)), Right(_))
216+
217+
override def encodeJson(t: StorageRangeResponse): JValue = Extraction.decompose(t)
218+
}
190219
}

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ object TestService {
4040
blockReward: BigInt,
4141
byzantiumForkBlock: BigInt,
4242
homesteadForkBlock: BigInt,
43-
maximumExtraDataSize: BigInt
43+
maximumExtraDataSize: BigInt,
44+
constantinopleForkBlock: BigInt,
45+
istanbulForkBlock: BigInt
4446
)
4547

4648
case class ChainParams(
@@ -62,6 +64,16 @@ object TestService {
6264
nextKey: ByteString
6365
)
6466

67+
case class StorageRangeParams(
68+
blockHashOrNumber: Either[BigInt, ByteString],
69+
txIndex: BigInt,
70+
address: ByteString,
71+
begin: BigInt,
72+
maxResults: BigInt
73+
)
74+
75+
case class StorageEntry(key: ByteString, value: ByteString)
76+
6577
case class SetChainParamsRequest(chainParams: ChainParams)
6678
case class SetChainParamsResponse()
6779

@@ -82,6 +94,9 @@ object TestService {
8294

8395
case class AccountsInRangeRequest(parameters: AccountsInRangeRequestParams)
8496
case class AccountsInRangeResponse(addressMap: Map[ByteString, ByteString], nextKey: ByteString)
97+
98+
case class StorageRangeRequest(parameters: StorageRangeParams)
99+
case class StorageRangeResponse(complete: Boolean, storage: Map[ByteString, StorageEntry])
85100
}
86101

87102
class TestService(
@@ -105,6 +120,9 @@ class TestService(
105120
val newBlockchainConfig = testLedgerWrapper.blockchainConfig.copy(
106121
homesteadBlockNumber = request.chainParams.blockchainParams.homesteadForkBlock,
107122
eip150BlockNumber = request.chainParams.blockchainParams.EIP150ForkBlock,
123+
byzantiumBlockNumber = request.chainParams.blockchainParams.byzantiumForkBlock,
124+
constantinopleBlockNumber = request.chainParams.blockchainParams.constantinopleForkBlock,
125+
istanbulBlockNumber = request.chainParams.blockchainParams.istanbulForkBlock,
108126
accountStartNonce = UInt256(request.chainParams.blockchainParams.accountStartNonce),
109127
networkId = 1,
110128
bootstrapNodes = Set()
@@ -123,6 +141,9 @@ class TestService(
123141
}
124142
)
125143

144+
// set coinbase for blocks that will be tried to mine
145+
etherbase = Address(genesisData.coinbase)
146+
126147
// remove current genesis (Try because it may not exist)
127148
Try(blockchain.removeBlock(blockchain.genesisHeader.hash, withState = false))
128149

@@ -251,4 +272,8 @@ class TestService(
251272
)
252273
)
253274
}
275+
276+
def storageRangeAt(request: StorageRangeRequest): ServiceResponse[StorageRangeResponse] = {
277+
Task.now(Right(StorageRangeResponse(complete = true, storage = Map())))
278+
}
254279
}

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

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

33
import akka.util.ByteString
4-
import io.iohk.ethereum.domain.{BlockHeader, SignedTransaction}
4+
import io.iohk.ethereum.domain.{BlockHeader, SignedTransaction, UInt256}
5+
6+
trait BaseTransactionResponse {
7+
def hash: ByteString
8+
def nonce: BigInt
9+
def blockHash: Option[ByteString]
10+
def blockNumber: Option[BigInt]
11+
def transactionIndex: Option[BigInt]
12+
def from: Option[ByteString]
13+
def to: Option[ByteString]
14+
def value: BigInt
15+
def gasPrice: BigInt
16+
def gas: BigInt
17+
def input: ByteString
18+
}
519

620
final case class TransactionResponse(
721
hash: ByteString,
@@ -15,7 +29,24 @@ final case class TransactionResponse(
1529
gasPrice: BigInt,
1630
gas: BigInt,
1731
input: ByteString
18-
)
32+
) extends BaseTransactionResponse
33+
34+
final case class EthTransactionResponse(
35+
hash: ByteString,
36+
nonce: BigInt,
37+
blockHash: Option[ByteString],
38+
blockNumber: Option[BigInt],
39+
transactionIndex: Option[BigInt],
40+
from: Option[ByteString],
41+
to: Option[ByteString],
42+
value: BigInt,
43+
gasPrice: BigInt,
44+
gas: BigInt,
45+
input: ByteString,
46+
r: ByteString,
47+
s: ByteString,
48+
v: ByteString
49+
) extends BaseTransactionResponse
1950

2051
final case class TransactionData(
2152
stx: SignedTransaction,
@@ -48,3 +79,31 @@ object TransactionResponse {
4879
)
4980

5081
}
82+
83+
object EthTransactionResponse {
84+
85+
def apply(tx: TransactionData): EthTransactionResponse =
86+
EthTransactionResponse(tx.stx, tx.blockHeader, tx.transactionIndex)
87+
88+
def apply(
89+
stx: SignedTransaction,
90+
blockHeader: Option[BlockHeader] = None,
91+
transactionIndex: Option[Int] = None
92+
): EthTransactionResponse =
93+
EthTransactionResponse(
94+
hash = stx.hash,
95+
nonce = stx.tx.nonce,
96+
blockHash = blockHeader.map(_.hash),
97+
blockNumber = blockHeader.map(_.number),
98+
transactionIndex = transactionIndex.map(txIndex => BigInt(txIndex)),
99+
from = SignedTransaction.getSender(stx).map(_.bytes),
100+
to = stx.tx.receivingAddress.map(_.bytes),
101+
value = stx.tx.value,
102+
gasPrice = stx.tx.gasPrice,
103+
gas = stx.tx.gasLimit,
104+
input = stx.tx.payload,
105+
r = UInt256(stx.signature.r).bytes,
106+
s = UInt256(stx.signature.s).bytes,
107+
v = ByteString(stx.signature.v)
108+
)
109+
}

src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
package io.iohk.ethereum.testmode
22

3-
import io.iohk.ethereum.domain.Blockchain
3+
import io.iohk.ethereum.domain.{Block, Blockchain}
44
import io.iohk.ethereum.jsonrpc.EthBlocksService.{BlockByBlockHashResponse, BlockByNumberResponse}
5-
import io.iohk.ethereum.jsonrpc.{BaseBlockResponse, EthBlockResponse, EthBlocksService, ServiceResponse}
5+
import io.iohk.ethereum.jsonrpc.{
6+
BaseBlockResponse,
7+
BaseTransactionResponse,
8+
EthBlockResponse,
9+
EthBlocksService,
10+
EthTransactionResponse,
11+
ServiceResponse,
12+
TransactionData
13+
}
614
import io.iohk.ethereum.ledger.Ledger
715
import io.iohk.ethereum.utils.Logger
816
import io.iohk.ethereum.consensus.Consensus
@@ -23,11 +31,12 @@ class TestEthBlockServiceWrapper(blockchain: Blockchain, ledger: Ledger, consens
2331
): ServiceResponse[EthBlocksService.BlockByBlockHashResponse] = super
2432
.getByBlockHash(request)
2533
.map(
26-
_.map(blockByBlockResponse =>
34+
_.map(blockByBlockResponse => {
35+
val fullBlock = blockchain.getBlockByNumber(blockByBlockResponse.blockResponse.get.number).get
2736
BlockByBlockHashResponse(
28-
blockByBlockResponse.blockResponse.map(response => toEthResponse(response))
37+
blockByBlockResponse.blockResponse.map(response => toEthResponse(fullBlock, response))
2938
)
30-
)
39+
})
3140
)
3241

3342
/**
@@ -41,15 +50,16 @@ class TestEthBlockServiceWrapper(blockchain: Blockchain, ledger: Ledger, consens
4150
): ServiceResponse[EthBlocksService.BlockByNumberResponse] = super
4251
.getBlockByNumber(request)
4352
.map(
44-
_.map(blockByBlockResponse =>
53+
_.map(blockByBlockResponse => {
54+
val fullBlock = blockchain.getBlockByNumber(blockByBlockResponse.blockResponse.get.number).get
4555
BlockByNumberResponse(
4656
blockByBlockResponse.blockResponse
47-
.map(response => toEthResponse(response))
57+
.map(response => toEthResponse(fullBlock, response))
4858
)
49-
)
59+
})
5060
)
5161

52-
private def toEthResponse(response: BaseBlockResponse) = EthBlockResponse(
62+
private def toEthResponse(block: Block, response: BaseBlockResponse) = EthBlockResponse(
5363
response.number,
5464
response.hash,
5565
response.mixHash,
@@ -68,7 +78,16 @@ class TestEthBlockServiceWrapper(blockchain: Blockchain, ledger: Ledger, consens
6878
response.gasLimit,
6979
response.gasUsed,
7080
response.timestamp,
71-
response.transactions,
81+
toEthTransaction(block, response.transactions),
7282
response.uncles
7383
)
84+
85+
private def toEthTransaction(
86+
block: Block,
87+
responseTransactions: Either[Seq[ByteString], Seq[BaseTransactionResponse]]
88+
): Either[Seq[ByteString], Seq[BaseTransactionResponse]] = responseTransactions.map(_ => {
89+
block.body.transactionList.zipWithIndex.map { case (stx, transactionIndex) =>
90+
EthTransactionResponse(tx = TransactionData(stx, Some(block.header), Some(transactionIndex)))
91+
}
92+
})
7493
}

0 commit comments

Comments
 (0)