Skip to content

Commit

Permalink
[ETCM-355] Introduce ETH64 message format
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasz-golebiewski committed Jun 29, 2021
1 parent e3f1c38 commit e72902b
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 8 deletions.
25 changes: 25 additions & 0 deletions src/main/scala/io/iohk/ethereum/network/p2p/MessageDecoders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ object ETC64MessageDecoder extends MessageDecoder {
}
}

object ETH64MessageDecoder extends MessageDecoder {
import io.iohk.ethereum.network.p2p.messages.ETH64.Status._
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages.NewBlock._

def fromBytes(msgCode: Int, payload: Array[Byte]): Message = {
msgCode match {
case Codes.GetNodeDataCode => payload.toGetNodeData
case Codes.NodeDataCode => payload.toNodeData
case Codes.GetReceiptsCode => payload.toGetReceipts
case Codes.ReceiptsCode => payload.toReceipts
case Codes.NewBlockHashesCode => payload.toNewBlockHashes
case Codes.GetBlockHeadersCode => payload.toGetBlockHeaders
case Codes.BlockHeadersCode => payload.toBlockHeaders
case Codes.GetBlockBodiesCode => payload.toGetBlockBodies
case Codes.BlockBodiesCode => payload.toBlockBodies
case Codes.BlockHashesFromNumberCode => payload.toBlockHashesFromNumber
case Codes.StatusCode => payload.toStatus
case Codes.NewBlockCode => payload.toNewBlock
case Codes.SignedTransactionsCode => payload.toSignedTransactions
case _ => throw new RuntimeException(s"Unknown message type: $msgCode")
}
}
}

object ETH63MessageDecoder extends MessageDecoder {
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages.Status._
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages.NewBlock._
Expand Down Expand Up @@ -87,6 +111,7 @@ object EthereumMessageDecoder {
protocolVersion match {
case Capability.Capabilities.Etc64Capability => ETC64MessageDecoder.fromBytes
case Capability.Capabilities.Eth63Capability => ETH63MessageDecoder.fromBytes
case Capability.Capabilities.Eth64Capability => ETH64MessageDecoder.fromBytes
case _ => throw new RuntimeException(s"Unsupported Protocol Version $protocolVersion")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ object Capability {

object Capabilities {
val Eth63Capability: Capability = ProtocolVersions.ETH63
val Eth64Capability: Capability = ProtocolVersions.ETH64
val Etc64Capability: Capability = ProtocolVersions.ETC64

val All: Seq[Capability] = Seq(ProtocolVersions.ETC64, ProtocolVersions.ETH63)
val All: Seq[Capability] = Seq(ProtocolVersions.ETC64, ProtocolVersions.ETH63, ProtocolVersions.ETH64)
}
}
75 changes: 75 additions & 0 deletions src/main/scala/io/iohk/ethereum/network/p2p/messages/ETH64.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package io.iohk.ethereum.network.p2p.messages

import akka.util.ByteString
import io.iohk.ethereum.domain._
import io.iohk.ethereum.forkid.ForkId
import io.iohk.ethereum.forkid.ForkId._
import io.iohk.ethereum.mpt.{MptNode, MptTraversals}
import io.iohk.ethereum.network.p2p.{Message, MessageSerializableImplicit}
import io.iohk.ethereum.rlp.RLPImplicitConversions._
import io.iohk.ethereum.rlp.RLPImplicits._
import io.iohk.ethereum.rlp._
import org.bouncycastle.util.encoders.Hex

object ETH64 {

case class Status(
protocolVersion: Int,
networkId: Int,
totalDifficulty: BigInt,
bestHash: ByteString,
genesisHash: ByteString,
forkId: ForkId
) extends Message {

override def toString: String =
s"Status { " +
s"code: $code, " +
s"protocolVersion: $protocolVersion, " +
s"networkId: $networkId, " +
s"totalDifficulty: $totalDifficulty, " +
s"bestHash: ${Hex.toHexString(bestHash.toArray[Byte])}, " +
s"genesisHash: ${Hex.toHexString(genesisHash.toArray[Byte])}," +
s"forkId: $forkId," +
s"}"

override def toShortString: String = toString
override def code: Int = Codes.StatusCode
}

object Status {
implicit class StatusEnc(val underlyingMsg: Status)
extends MessageSerializableImplicit[Status](underlyingMsg)
with RLPSerializable {
override def code: Int = Codes.StatusCode

override def toRLPEncodable: RLPEncodeable = {
import msg._
RLPList(protocolVersion, networkId, totalDifficulty, bestHash, genesisHash, forkId.toRLPEncodable)
}
}

implicit class StatusDec(val bytes: Array[Byte]) extends AnyVal {
def toStatus: Status = rawDecode(bytes) match {
case RLPList(
protocolVersion,
networkId,
totalDifficulty,
bestHash,
genesisHash,
forkId
) =>
Status(
protocolVersion,
networkId,
totalDifficulty,
bestHash,
genesisHash,
decode[ForkId](forkId)
)

case _ => throw new RuntimeException("Cannot decode Status")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.iohk.ethereum.network.p2p.messages
import akka.util.ByteString
import io.iohk.ethereum.Fixtures
import io.iohk.ethereum.domain.ChainWeight
import io.iohk.ethereum.forkid.ForkId
import io.iohk.ethereum.network.p2p.messages.BaseETH6XMessages._
import io.iohk.ethereum.network.p2p.messages.ETH61.BlockHashesFromNumber
import io.iohk.ethereum.network.p2p.messages.ETH62._
Expand Down Expand Up @@ -53,13 +54,6 @@ class MessagesSerializationSpec extends AnyWordSpec with ScalaCheckPropertyCheck
}

"Common Messages" when {
"encoding and decoding Status" should {
"return same result for Status v63" in {
val msg = Status(1, 2, 2, ByteString("HASH"), ByteString("HASH2"))
verify(msg, (m: Status) => m.toBytes, Codes.StatusCode, ProtocolVersions.ETH63)
}
}

"encoding and decoding SignedTransactions" should {
"return same result" in {
val msg = SignedTransactions(Fixtures.Blocks.Block3125369.body.transactionList)
Expand Down Expand Up @@ -93,6 +87,27 @@ class MessagesSerializationSpec extends AnyWordSpec with ScalaCheckPropertyCheck

"ETH63" when {
val version = ProtocolVersions.ETH63
"encoding and decoding Status" should {
"return same result for Status v63" in {
val msg = Status(1, 2, 2, ByteString("HASH"), ByteString("HASH2"))
verify(msg, (m: Status) => m.toBytes, Codes.StatusCode, ProtocolVersions.ETH63)
}
}
commonEthAssertions(version)
}

"ETH64" when {
val version = ProtocolVersions.ETH64
"encoding and decoding Status" should {
"return same result" in {
val msg = ETH64.Status(1, 2, 3, ByteString("HASH"), ByteString("HASH2"), ForkId(1L, None))
verify(msg, (m: ETH64.Status) => m.toBytes, Codes.StatusCode, ProtocolVersions.ETH64)
}
}
commonEthAssertions(version)
}

def commonEthAssertions(version: Capability) = {
"encoding and decoding ETH61.NewBlockHashes" should {
"throw for unsupported message version" in {
val msg = ETH61.NewBlockHashes(Seq(ByteString("23"), ByteString("10"), ByteString("36")))
Expand Down

0 comments on commit e72902b

Please sign in to comment.