@@ -117,13 +117,17 @@ object BaseETH6XMessages {
117117
118118 implicit class NewBlockDec (val bytes : Array [Byte ]) extends AnyVal {
119119 import SignedTransactions ._
120+ import TypedTransaction ._
120121
121122 def toNewBlock : NewBlock = rawDecode(bytes) match {
122123 case RLPList (RLPList (blockHeader, transactionList : RLPList , uncleNodesList : RLPList ), totalDifficulty) =>
123124 NewBlock (
124125 Block (
125126 blockHeader.toBlockHeader,
126- BlockBody (transactionList.items.map(_.toSignedTransaction), uncleNodesList.items.map(_.toBlockHeader))
127+ BlockBody (
128+ transactionList.items.toTypedRLPEncodables.map(_.toSignedTransaction),
129+ uncleNodesList.items.map(_.toBlockHeader)
130+ )
127131 ),
128132 totalDifficulty
129133 )
@@ -154,6 +158,36 @@ object BaseETH6XMessages {
154158 override def code : Int = Codes .NewBlockCode
155159 }
156160
161+ object TypedTransaction {
162+ implicit class TypedTransactionsRLPAggregator (val encodables : Seq [RLPEncodeable ]) extends AnyVal {
163+
164+ /** Convert a Seq of RLPEncodable containing TypedTransaction informations into a Seq of
165+ * Prefixed RLPEncodable.
166+ *
167+ * PrefixedRLPEncodable(prefix, prefixedRLPEncodable) generates binary data
168+ * as prefix || RLPEncodable(prefixedRLPEncodable).
169+ *
170+ * As prefix is a byte value lower than 0x7f, it is read back as RLPValue(prefix),
171+ * thus PrefixedRLPEncodable is binary equivalent to RLPValue(prefix), RLPEncodable
172+ *
173+ * The method aggregates back the typed transaction prefix with the following heuristic:
174+ * - a RLPValue(byte) with byte < 07f + the following RLPEncodable are associated as a PrefixedRLPEncodable
175+ * - all other RLPEncodable are kept unchanged
176+ *
177+ * This is the responsibility of the RLPDecoder to insert this meaning into its RLPList, when appropriate.
178+ *
179+ * @return a Seq of TypedTransaction enriched RLPEncodable
180+ */
181+ def toTypedRLPEncodables : Seq [RLPEncodeable ] =
182+ encodables match {
183+ case Seq () => Seq ()
184+ case Seq (RLPValue (v), rlpList : RLPList , tail @ _* ) if v.length == 1 && v.head < 0x7f =>
185+ PrefixedRLPEncodable (v.head, rlpList) +: tail.toTypedRLPEncodables
186+ case Seq (head, tail @ _* ) => head +: tail.toTypedRLPEncodables
187+ }
188+ }
189+ }
190+
157191 object SignedTransactions {
158192
159193 implicit class SignedTransactionEnc (val signedTx : SignedTransaction ) extends RLPSerializable {
@@ -207,23 +241,25 @@ object BaseETH6XMessages {
207241
208242 implicit class SignedTransactionsDec (val bytes : Array [Byte ]) extends AnyVal {
209243
210- def mergeTransactionType (encodables : Seq [RLPEncodeable ]): Seq [RLPEncodeable ] =
211- encodables match {
212- case Seq () => Seq ()
213- case Seq (RLPValue (v), rlpList : RLPList , tail @ _* ) if v.length == 1 =>
214- PrefixedRLPEncodable (v.head, rlpList) +: mergeTransactionType(tail)
215- case Seq (head, tail @ _* ) => head +: mergeTransactionType(tail)
216- }
217- def toSignedTransactions : SignedTransactions =
218- rawDecode(bytes) match {
219- case rlpList : RLPList => SignedTransactions (mergeTransactionType(rlpList.items).map(_.toSignedTransaction))
220- case _ => throw new RuntimeException (" Cannot decode SignedTransactions" )
221- }
244+ import TypedTransaction ._
245+
246+ def toSignedTransactions : SignedTransactions = rawDecode(bytes) match {
247+ case rlpList : RLPList => SignedTransactions (rlpList.items.toTypedRLPEncodables.map(_.toSignedTransaction))
248+ case _ => throw new RuntimeException (" Cannot decode SignedTransactions" )
249+ }
222250 }
223251
224252 implicit class SignedTransactionRlpEncodableDec (val rlpEncodeable : RLPEncodeable ) extends AnyVal {
225253
226254 // scalastyle:off method.length
255+
256+ /** A signed transaction is either a RLPList representing a Legacy SignedTransaction
257+ * or a PrefixedRLPEncodable(transactionType, RLPList of typed transaction envelope)
258+ *
259+ * @see TypedTransaction.TypedTransactionsRLPAggregator
260+ *
261+ * @return a SignedTransaction
262+ */
227263 def toSignedTransaction : SignedTransaction = rlpEncodeable match {
228264 case PrefixedRLPEncodable (
229265 Transaction .Type01 ,
0 commit comments