Skip to content

Commit a7570b9

Browse files
[ETCM-355] Introduce ETH64 message format
1 parent e631789 commit a7570b9

File tree

4 files changed

+124
-8
lines changed

4 files changed

+124
-8
lines changed

src/main/scala/io/iohk/ethereum/network/p2p/MessageDecoders.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,30 @@ object ETC64MessageDecoder extends MessageDecoder {
5656
}
5757
}
5858

59+
object ETH64MessageDecoder extends MessageDecoder {
60+
import io.iohk.ethereum.network.p2p.messages.ETH64.Status._
61+
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages.NewBlock._
62+
63+
def fromBytes(msgCode: Int, payload: Array[Byte]): Message = {
64+
msgCode match {
65+
case Codes.GetNodeDataCode => payload.toGetNodeData
66+
case Codes.NodeDataCode => payload.toNodeData
67+
case Codes.GetReceiptsCode => payload.toGetReceipts
68+
case Codes.ReceiptsCode => payload.toReceipts
69+
case Codes.NewBlockHashesCode => payload.toNewBlockHashes
70+
case Codes.GetBlockHeadersCode => payload.toGetBlockHeaders
71+
case Codes.BlockHeadersCode => payload.toBlockHeaders
72+
case Codes.GetBlockBodiesCode => payload.toGetBlockBodies
73+
case Codes.BlockBodiesCode => payload.toBlockBodies
74+
case Codes.BlockHashesFromNumberCode => payload.toBlockHashesFromNumber
75+
case Codes.StatusCode => payload.toStatus
76+
case Codes.NewBlockCode => payload.toNewBlock
77+
case Codes.SignedTransactionsCode => payload.toSignedTransactions
78+
case _ => throw new RuntimeException(s"Unknown message type: $msgCode")
79+
}
80+
}
81+
}
82+
5983
object ETH63MessageDecoder extends MessageDecoder {
6084
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages.Status._
6185
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages.NewBlock._
@@ -87,6 +111,7 @@ object EthereumMessageDecoder {
87111
protocolVersion match {
88112
case Capability.Capabilities.Etc64Capability => ETC64MessageDecoder.fromBytes
89113
case Capability.Capabilities.Eth63Capability => ETH63MessageDecoder.fromBytes
114+
case Capability.Capabilities.Eth64Capability => ETH64MessageDecoder.fromBytes
90115
case _ => throw new RuntimeException(s"Unsupported Protocol Version $protocolVersion")
91116
}
92117
}

src/main/scala/io/iohk/ethereum/network/p2p/messages/Capability.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ object Capability {
4747

4848
object Capabilities {
4949
val Eth63Capability: Capability = ProtocolVersions.ETH63
50+
val Eth64Capability: Capability = ProtocolVersions.ETH64
5051
val Etc64Capability: Capability = ProtocolVersions.ETC64
5152

52-
val All: Seq[Capability] = Seq(ProtocolVersions.ETC64, ProtocolVersions.ETH63)
53+
val All: Seq[Capability] = Seq(ProtocolVersions.ETC64, ProtocolVersions.ETH63, ProtocolVersions.ETH64)
5354
}
5455
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.iohk.ethereum.network.p2p.messages
2+
3+
import akka.util.ByteString
4+
import io.iohk.ethereum.domain._
5+
import io.iohk.ethereum.forkid.ForkId
6+
import io.iohk.ethereum.forkid.ForkId._
7+
import io.iohk.ethereum.mpt.{MptNode, MptTraversals}
8+
import io.iohk.ethereum.network.p2p.{Message, MessageSerializableImplicit}
9+
import io.iohk.ethereum.rlp.RLPImplicitConversions._
10+
import io.iohk.ethereum.rlp.RLPImplicits._
11+
import io.iohk.ethereum.rlp._
12+
import org.bouncycastle.util.encoders.Hex
13+
14+
object ETH64 {
15+
16+
case class Status(
17+
protocolVersion: Int,
18+
networkId: Int,
19+
totalDifficulty: BigInt,
20+
bestHash: ByteString,
21+
genesisHash: ByteString,
22+
forkId: ForkId
23+
) extends Message {
24+
25+
override def toString: String =
26+
s"Status { " +
27+
s"code: $code, " +
28+
s"protocolVersion: $protocolVersion, " +
29+
s"networkId: $networkId, " +
30+
s"totalDifficulty: $totalDifficulty, " +
31+
s"bestHash: ${Hex.toHexString(bestHash.toArray[Byte])}, " +
32+
s"genesisHash: ${Hex.toHexString(genesisHash.toArray[Byte])}," +
33+
s"forkId: $forkId," +
34+
s"}"
35+
36+
override def toShortString: String = toString
37+
override def code: Int = Codes.StatusCode
38+
}
39+
40+
object Status {
41+
implicit class StatusEnc(val underlyingMsg: Status)
42+
extends MessageSerializableImplicit[Status](underlyingMsg)
43+
with RLPSerializable {
44+
override def code: Int = Codes.StatusCode
45+
46+
override def toRLPEncodable: RLPEncodeable = {
47+
import msg._
48+
RLPList(protocolVersion, networkId, totalDifficulty, bestHash, genesisHash, forkId.toRLPEncodable)
49+
}
50+
}
51+
52+
implicit class StatusDec(val bytes: Array[Byte]) extends AnyVal {
53+
def toStatus: Status = rawDecode(bytes) match {
54+
case RLPList(
55+
protocolVersion,
56+
networkId,
57+
totalDifficulty,
58+
bestHash,
59+
genesisHash,
60+
forkId
61+
) =>
62+
Status(
63+
protocolVersion,
64+
networkId,
65+
totalDifficulty,
66+
bestHash,
67+
genesisHash,
68+
decode[ForkId](forkId)
69+
)
70+
71+
case _ => throw new RuntimeException("Cannot decode Status")
72+
}
73+
}
74+
}
75+
}

src/test/scala/io/iohk/ethereum/network/p2p/messages/MessagesSerializationSpec.scala

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.iohk.ethereum.network.p2p.messages
33
import akka.util.ByteString
44
import io.iohk.ethereum.Fixtures
55
import io.iohk.ethereum.domain.ChainWeight
6+
import io.iohk.ethereum.forkid.ForkId
67
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages._
78
import io.iohk.ethereum.network.p2p.messages.ETH61.BlockHashesFromNumber
89
import io.iohk.ethereum.network.p2p.messages.ETH62._
@@ -53,13 +54,6 @@ class MessagesSerializationSpec extends AnyWordSpec with ScalaCheckPropertyCheck
5354
}
5455

5556
"Common Messages" when {
56-
"encoding and decoding Status" should {
57-
"return same result for Status v63" in {
58-
val msg = Status(1, 2, 2, ByteString("HASH"), ByteString("HASH2"))
59-
verify(msg, (m: Status) => m.toBytes, Codes.StatusCode, ProtocolVersions.ETH63)
60-
}
61-
}
62-
6357
"encoding and decoding SignedTransactions" should {
6458
"return same result" in {
6559
val msg = SignedTransactions(Fixtures.Blocks.Block3125369.body.transactionList)
@@ -93,6 +87,27 @@ class MessagesSerializationSpec extends AnyWordSpec with ScalaCheckPropertyCheck
9387

9488
"ETH63" when {
9589
val version = ProtocolVersions.ETH63
90+
"encoding and decoding Status" should {
91+
"return same result for Status v63" in {
92+
val msg = Status(1, 2, 2, ByteString("HASH"), ByteString("HASH2"))
93+
verify(msg, (m: Status) => m.toBytes, Codes.StatusCode, ProtocolVersions.ETH63)
94+
}
95+
}
96+
commonEthAssertions(version)
97+
}
98+
99+
"ETH64" when {
100+
val version = ProtocolVersions.ETH64
101+
"encoding and decoding Status" should {
102+
"return same result" in {
103+
val msg = ETH64.Status(1, 2, 3, ByteString("HASH"), ByteString("HASH2"), ForkId(1L, None))
104+
verify(msg, (m: ETH64.Status) => m.toBytes, Codes.StatusCode, ProtocolVersions.ETH64)
105+
}
106+
}
107+
commonEthAssertions(version)
108+
}
109+
110+
def commonEthAssertions(version: Capability) = {
96111
"encoding and decoding ETH61.NewBlockHashes" should {
97112
"throw for unsupported message version" in {
98113
val msg = ETH61.NewBlockHashes(Seq(ByteString("23"), ByteString("10"), ByteString("36")))

0 commit comments

Comments
 (0)