@@ -10,10 +10,11 @@ import io.iohk.ethereum.rlp.RLPCodec.Ops
10
10
import io .iohk .ethereum .rlp .RLPImplicits ._
11
11
import io .iohk .ethereum .rlp .RLPImplicitConversions ._
12
12
import io .iohk .ethereum .rlp .RLPImplicitDerivations ._
13
- import scodec .Codec
13
+ import scodec .{ Codec , Attempt , Err , DecodeResult }
14
14
import scodec .bits .{BitVector , ByteVector }
15
15
import java .net .InetAddress
16
16
import scala .collection .SortedMap
17
+ import scala .util .Try
17
18
18
19
/** RLP codecs based on https://github.com/ethereum/devp2p/blob/master/discv4.md */
19
20
object RLPCodecs {
@@ -50,10 +51,9 @@ object RLPCodecs {
50
51
RLPCodec .instance(
51
52
{ case EthereumNodeRecord (signature, EthereumNodeRecord .Content (seq, attrs)) =>
52
53
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
55
56
}
56
- .foldRight(RLPList ())(_ ++ _)
57
57
58
58
signature.toByteArray :: seq :: kvs
59
59
},
@@ -96,5 +96,42 @@ object RLPCodecs {
96
96
implicit val enrResponseRLPCodec : RLPCodec [Payload .ENRResponse ] =
97
97
deriveLabelledGenericRLPCodec
98
98
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
+ )
100
137
}
0 commit comments