Skip to content

Commit 123160a

Browse files
committed
ETCM-167: Codec for Payload.
1 parent 413ec3e commit 123160a

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

src/main/scala/io/iohk/ethereum/network/discovery/codecs/RLPCodecs.scala

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import io.iohk.ethereum.rlp.RLPCodec.Ops
1010
import io.iohk.ethereum.rlp.RLPImplicits._
1111
import io.iohk.ethereum.rlp.RLPImplicitConversions._
1212
import io.iohk.ethereum.rlp.RLPImplicitDerivations._
13-
import scodec.Codec
13+
import scodec.{Codec, Attempt, Err, DecodeResult}
1414
import scodec.bits.{BitVector, ByteVector}
1515
import java.net.InetAddress
1616
import scala.collection.SortedMap
17+
import scala.util.Try
1718

1819
/** RLP codecs based on https://github.com/ethereum/devp2p/blob/master/discv4.md */
1920
object RLPCodecs {
@@ -50,10 +51,9 @@ object RLPCodecs {
5051
RLPCodec.instance(
5152
{ case EthereumNodeRecord(signature, EthereumNodeRecord.Content(seq, attrs)) =>
5253
val kvs = attrs
53-
.map { case (k, v) =>
54-
RLPList(k.toArray, v.toArray)
54+
.foldRight(RLPList()) { case ((k, v), kvs) =>
55+
k.toArray :: v.toArray :: kvs
5556
}
56-
.foldRight(RLPList())(_ ++ _)
5757

5858
signature.toByteArray :: seq :: kvs
5959
},
@@ -96,5 +96,42 @@ object RLPCodecs {
9696
implicit val enrResponseRLPCodec: RLPCodec[Payload.ENRResponse] =
9797
deriveLabelledGenericRLPCodec
9898

99-
implicit def payloadCodec: Codec[Payload] = ???
99+
implicit def payloadCodec: Codec[Payload] =
100+
Codec[Payload](
101+
(payload: Payload) => {
102+
def pt(b: Byte): Byte = b
103+
104+
val data: Array[Byte] = payload match {
105+
case x: Payload.Ping => pt(0x01) +: rlp.encode(x)
106+
case x: Payload.Pong => pt(0x02) +: rlp.encode(x)
107+
case x: Payload.FindNode => pt(0x03) +: rlp.encode(x)
108+
case x: Payload.Neighbors => pt(0x04) +: rlp.encode(x)
109+
case x: Payload.ENRRequest => pt(0x05) +: rlp.encode(x)
110+
case x: Payload.ENRResponse => pt(0x06) +: rlp.encode(x)
111+
}
112+
113+
Attempt.successful(BitVector(data))
114+
},
115+
(bits: BitVector) => {
116+
bits.consumeThen(8)(
117+
err => Attempt.failure(Err(err)),
118+
(packetType, rest) => {
119+
120+
val tryPayload: Try[Payload] = Try {
121+
packetType.toByte() match {
122+
case 0x01 => rlp.decode[Payload.Ping](rest)
123+
case 0x02 => rlp.decode[Payload.Pong](rest)
124+
case 0x03 => rlp.decode[Payload.FindNode](rest)
125+
case 0x04 => rlp.decode[Payload.Neighbors](rest)
126+
case 0x05 => rlp.decode[Payload.ENRRequest](rest)
127+
case 0x06 => rlp.decode[Payload.ENRResponse](rest)
128+
case other => throw new RuntimeException(s"Unknown packet type: ${other}")
129+
}
130+
}
131+
132+
Attempt.fromTry(tryPayload.map(DecodeResult(_, BitVector.empty)))
133+
}
134+
)
135+
}
136+
)
100137
}

0 commit comments

Comments
 (0)