diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ssz/TransactionNetworkPayload.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ssz/TransactionNetworkPayload.java index 168e570a8f..0844561c2c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ssz/TransactionNetworkPayload.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ssz/TransactionNetworkPayload.java @@ -302,7 +302,7 @@ public class TransactionNetworkPayload implements SSZReadable, SSZWritable { public static class Data implements SSZReadable, SSZWritable { public static final int MAX_CALL_DATA_SIZE = 16777216; // 2**24 - Bytes data; + Bytes data = Bytes.EMPTY; @Override public boolean isFixed() { @@ -319,7 +319,7 @@ public class TransactionNetworkPayload implements SSZReadable, SSZWritable { @Override public void writeTo(final SSZWriter writer) { - if (data != null) { + if (data != Bytes.EMPTY) { writer.writeBytes(data); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionSSZEncodingTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionSSZEncodingTest.java index db6ead143b..9c6617cbdc 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionSSZEncodingTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionSSZEncodingTest.java @@ -43,6 +43,9 @@ public class TransactionSSZEncodingTest { private static final String BLOB_TRANSACTIONS_TEST_VECTORS_JSON = "org/hyperledger/besu/ethereum/core/encoding/blob_transactions_test_vectors.json"; + private static final String BLOB_TRANSACTIONS_WITHOUT_BLOBS_TEST_VECTORS_JSON = + "org/hyperledger/besu/ethereum/core/encoding/blob_transactions_without_blobs_test_vectors.json"; + private static Collection blobTransactionsTestVectors() throws IOException { ClassLoader classLoader = TransactionSSZEncodingTest.class.getClassLoader(); @@ -63,6 +66,29 @@ public class TransactionSSZEncodingTest { .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); } + private static Collection blobTransactionsTestVectorsWithoutBlobs() throws IOException { + + ClassLoader classLoader = TransactionSSZEncodingTest.class.getClassLoader(); + InputStream inputStream = + classLoader.getResourceAsStream(BLOB_TRANSACTIONS_WITHOUT_BLOBS_TEST_VECTORS_JSON); + JsonParser parser = new JsonFactory().createParser(inputStream); + ObjectMapper mapper = + JsonMapper.builder() + .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) + .build(); + List models = mapper.readValue(parser, new TypeReference<>() {}); + + return models.stream() + .map( + model -> + new Object[] { + generateNameWithoutblobs(model.getInput()), + model.getInput(), + model.getRawEncodedTransaction() + }) + .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); + } + private static String generateName(final Input input) { return " To: " + input.getTo() @@ -76,6 +102,10 @@ public class TransactionSSZEncodingTest { + input.getNonce(); } + private static String generateNameWithoutblobs(final InputWithoutBlobs input) { + return " chainId: " + input.getChainId(); + } + @ParameterizedTest(name = "[{index}] {0}") @MethodSource("blobTransactionsTestVectors") void shouldDecodeSSZTransactions( @@ -92,6 +122,20 @@ public class TransactionSSZEncodingTest { assertThat(encodedBytes.toHexString()).isEqualTo(rawTransaction); } + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("blobTransactionsTestVectorsWithoutBlobs") + void shouldDecodeSSZTransactionsWithoutBlobs( + final String name, final InputWithoutBlobs input, final String rawTransaction) { + final Bytes bytes = Bytes.fromHexString(rawTransaction); + final Transaction transaction = TransactionDecoder.decodeOpaqueBytes(bytes); + + assertThat(transaction).isNotNull(); + assertThat(transaction.getPayload()).isNotNull(); + final Bytes encodedBytes = TransactionEncoder.encodeOpaqueBytes(transaction); + assertThat(encodedBytes).isNotNull(); + assertThat(encodedBytes.toHexString()).isEqualTo(rawTransaction); + } + public static class Model { private Input input; private String rawEncodedTransaction; @@ -113,6 +157,27 @@ public class TransactionSSZEncodingTest { } } + public static class ModelWithoutBlobs { + private InputWithoutBlobs input; + private String rawEncodedTransaction; + + public InputWithoutBlobs getInput() { + return input; + } + + public void setInput(final InputWithoutBlobs input) { + this.input = input; + } + + public String getRawEncodedTransaction() { + return rawEncodedTransaction; + } + + public void setRawEncodedTransaction(final String rawEncodedTransaction) { + this.rawEncodedTransaction = rawEncodedTransaction; + } + } + public static class Input { String privateKey; String to; @@ -196,4 +261,16 @@ public class TransactionSSZEncodingTest { this.data = data; } } + + public static class InputWithoutBlobs { + String chainId; + + public String getChainId() { + return chainId; + } + + public void setChainId(final String chainId) { + this.chainId = chainId; + } + } } diff --git a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/core/encoding/blob_transactions_without_blobs_test_vectors.json b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/core/encoding/blob_transactions_without_blobs_test_vectors.json new file mode 100644 index 0000000000..622a826601 --- /dev/null +++ b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/core/encoding/blob_transactions_without_blobs_test_vectors.json @@ -0,0 +1,8 @@ +[ + { + "Input": { + "chainId": "4844001004" + }, + "RawEncodedTransaction": "0x054500000000038c34b89390ade8350e994a5611eaab7c55b2544e70904558e649bb4f7a75f2f954b7adda21f61163b09ff39db79262ce15820b79b1fa8b039dbf2e97f4ad7dec96b920010000000000000000000000000000000000000000000000000000000000000000000000009435770000000000000000000000000000000000000000000000000000000000e876481700000000000000000000000000000000000000000000000000000040420f0000000000c00000000000000000000000000000000000000000000000000000000000000000000000d5000000d5000000005ed0b200000000000000000000000000000000000000000000000000000000d5000000010000000000000000000000000000000000000000010c30956be2a7db889757f855d3d42d4a3660a90f0c86aaef23586ac0f050b501c97b77e1fc5f69618cfbf94e0d7486ebdfab1ce1173e59c908ac5b61a12fc2" + } +] \ No newline at end of file