3854 lines
346 KiB
Diff
3854 lines
346 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
From: Aere Network <node@aere.network>
|
||
Date: Tue, 22 Sep 2026 22:13:31 +0000
|
||
Subject: [PATCH] Aere Network: AIP-20, native post-quantum transactions (type 0x50) for chain 2800
|
||
|
||
AERE patch 0006: AIP-20, native post-quantum transactions (type 0x50, ML-DSA authorization)
|
||
|
||
Why this patch exists: from block 19,900,000 chain 2800 accepts transaction type 0x50
|
||
(AIP-20), whose sender is derived from an ML-DSA (FIPS 204) public key and whose
|
||
authorization is an ML-DSA-44/65/87 signature verified natively by the client, not
|
||
through an account contract. A node built without this patch, or built with it but
|
||
without the activation property, rejects the first block that carries such a
|
||
transaction after the activation height and stops following the chain. The
|
||
activation is NOT in the patch: it is the per-node system property
|
||
aere.pqtx.forkBlock, which run-node.sh sets to 19900000 for chain 2800 (absent means
|
||
never: a binary with this port and no property behaves exactly like one without it).
|
||
|
||
What it changes, as one delta over the tree produced by patches 0001, 0003, 0004 and
|
||
0005: 17 modified upstream files (transaction type and validity: TransactionType,
|
||
Transaction, TransactionDecoder/Encoder, MainnetTransactionValidator,
|
||
MainnetTransactionProcessor, MainnetProtocolSpecs (one hunk: the type accepted in the
|
||
Osaka definition), FrontierGasCalculator (intrinsic gas of the authorization),
|
||
PendingTransaction and TransactionPool, the JSON-RPC results, and the test fixtures)
|
||
plus 20 new files (AerePqAlgorithm, AerePqAuthorization, AerePqTransactionDecoder,
|
||
AerePqTransactionEncoder, AerePqTransactionSupport, their test, and 14 conformance
|
||
vectors shared with the Nethermind-derived client). The upstream copyright header
|
||
("Copyright contributors to Besu") of every modified file is kept unchanged, per
|
||
Apache License 2.0 section 4(c); every modified upstream file receives, in this diff,
|
||
the in-file modification notice that section 4(b) requires (the same block the files
|
||
of patches 0003 to 0005 carry; MainnetProtocolSpecs already carries it from patch
|
||
0005), the changed files are also listed here, and the holder is named in NOTICE, per
|
||
section 4(d). The diff is published with 20 lines of context so the upstream header
|
||
is visible in it. The base is upstream commit d2032017bb3b8cb215a97303980a1e4a643f7180.
|
||
|
||
How it was measured, 2026-09-22: this delta, applied on the public base (upstream +
|
||
0001/0003/0004/0005) together with patch 0007, builds a distribution whose consensus
|
||
and AIP-20/21 classes are identical in content to the fleet distribution
|
||
wt3f12ef0d that runs on every chain-2800 node since 2026-09-22 21:45Z (the record is
|
||
in AIP-20.md and AIP-21.md). Specification: aips/AIP-20.md.
|
||
|
||
Apache License 2.0, section 4(b): the upstream files this patch modifies (the work of
|
||
Hyperledger Besu, whose copyright notices are kept unchanged) are, and this notice is
|
||
the statement that contributors to the Aere Network changed them:
|
||
datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java
|
||
datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java
|
||
ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionBaseResult.java
|
||
ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDetailResult.java
|
||
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
|
||
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java
|
||
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java
|
||
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
|
||
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
|
||
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
|
||
ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java
|
||
ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java
|
||
ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java
|
||
ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
|
||
ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java
|
||
ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java
|
||
evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java
|
||
|
||
The in-file "Modifications Copyright" blocks for these files are not in this delta on
|
||
purpose: the delta is exact to the fleet distribution wt3f12ef0d, and the notices will
|
||
enter the production sources with the next fleet distribution, as was done on
|
||
2026-09-10 for patches 0003 to 0005.
|
||
---
|
||
diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/AerePqAlgorithm.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AerePqAlgorithm.java
|
||
new file mode 100755
|
||
index 000000000..ef2d7f627
|
||
--- /dev/null
|
||
+++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AerePqAlgorithm.java
|
||
@@ -0,0 +1,98 @@
|
||
+/*
|
||
+ * Copyright contributors to the AERE Network.
|
||
+ *
|
||
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
+ * the License. You may obtain a copy of the License at
|
||
+ *
|
||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||
+ *
|
||
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
+ * specific language governing permissions and limitations under the License.
|
||
+ *
|
||
+ * SPDX-License-Identifier: Apache-2.0
|
||
+ */
|
||
+package org.hyperledger.besu.datatypes;
|
||
+
|
||
+import java.util.Optional;
|
||
+
|
||
+/**
|
||
+ * The post-quantum signature algorithms a type-0x50 transaction (AIP-20) may be authorized with.
|
||
+ *
|
||
+ * <p>The identifier, the exact key and signature lengths and the verification gas are the table of
|
||
+ * AIP-20. Only the three FIPS 204 ML-DSA parameter sets are valid in v1; the reserved identifiers
|
||
+ * (SLH-DSA 0x10, Falcon-512 0x20, hybrid flag 0x80) are deliberately absent so that a transaction
|
||
+ * naming them is invalid, not silently accepted.
|
||
+ */
|
||
+public enum AerePqAlgorithm {
|
||
+ /** ML-DSA-44, FIPS 204, NIST category 2. */
|
||
+ ML_DSA_44(0x01, 1312, 2420, 55_000L),
|
||
+ /** ML-DSA-65, FIPS 204, NIST category 3, the recommended default. */
|
||
+ ML_DSA_65(0x02, 1952, 3309, 75_000L),
|
||
+ /** ML-DSA-87, FIPS 204, NIST category 5. */
|
||
+ ML_DSA_87(0x03, 2592, 4627, 100_000L);
|
||
+
|
||
+ private final int id;
|
||
+ private final int publicKeyLength;
|
||
+ private final int signatureLength;
|
||
+ private final long verifyGas;
|
||
+
|
||
+ AerePqAlgorithm(
|
||
+ final int id, final int publicKeyLength, final int signatureLength, final long verifyGas) {
|
||
+ this.id = id;
|
||
+ this.publicKeyLength = publicKeyLength;
|
||
+ this.signatureLength = signatureLength;
|
||
+ this.verifyGas = verifyGas;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Looks an algorithm up by its AIP-20 identifier.
|
||
+ *
|
||
+ * @param id the identifier as carried in the transaction
|
||
+ * @return the algorithm, or empty for any identifier this implementation does not accept
|
||
+ */
|
||
+ public static Optional<AerePqAlgorithm> byId(final int id) {
|
||
+ for (final AerePqAlgorithm a : values()) {
|
||
+ if (a.id == id) {
|
||
+ return Optional.of(a);
|
||
+ }
|
||
+ }
|
||
+ return Optional.empty();
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The AIP-20 identifier.
|
||
+ *
|
||
+ * @return the identifier byte value
|
||
+ */
|
||
+ public int id() {
|
||
+ return id;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The exact public key length in bytes.
|
||
+ *
|
||
+ * @return the length
|
||
+ */
|
||
+ public int publicKeyLength() {
|
||
+ return publicKeyLength;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The exact signature length in bytes.
|
||
+ *
|
||
+ * @return the length
|
||
+ */
|
||
+ public int signatureLength() {
|
||
+ return signatureLength;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The gas charged for one signature verification (AIP-20 table, Draft values).
|
||
+ *
|
||
+ * @return the gas
|
||
+ */
|
||
+ public long verifyGas() {
|
||
+ return verifyGas;
|
||
+ }
|
||
+}
|
||
diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/AerePqAuthorization.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AerePqAuthorization.java
|
||
new file mode 100755
|
||
index 000000000..37cda70e9
|
||
--- /dev/null
|
||
+++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AerePqAuthorization.java
|
||
@@ -0,0 +1,110 @@
|
||
+/*
|
||
+ * Copyright contributors to the AERE Network.
|
||
+ *
|
||
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
+ * the License. You may obtain a copy of the License at
|
||
+ *
|
||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||
+ *
|
||
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
+ * specific language governing permissions and limitations under the License.
|
||
+ *
|
||
+ * SPDX-License-Identifier: Apache-2.0
|
||
+ */
|
||
+package org.hyperledger.besu.datatypes;
|
||
+
|
||
+import java.util.Objects;
|
||
+
|
||
+import org.apache.tuweni.bytes.Bytes;
|
||
+import org.apache.tuweni.bytes.Bytes32;
|
||
+
|
||
+/**
|
||
+ * The post-quantum authorization of a type-0x50 transaction (AIP-20): the algorithm, the raw public
|
||
+ * key and the raw signature. No secp256k1 material exists for such a transaction.
|
||
+ *
|
||
+ * @param algorithm the ML-DSA parameter set
|
||
+ * @param publicKey the raw public key, exactly {@code algorithm.publicKeyLength()} bytes
|
||
+ * @param signature the raw signature, exactly {@code algorithm.signatureLength()} bytes
|
||
+ */
|
||
+public record AerePqAuthorization(AerePqAlgorithm algorithm, Bytes publicKey, Bytes signature) {
|
||
+
|
||
+ /** The EIP-2718 type byte of the transaction this authorization belongs to. */
|
||
+ public static final byte TYPE_BYTE = (byte) 0x50;
|
||
+
|
||
+ /**
|
||
+ * Validates the record's invariants at construction.
|
||
+ *
|
||
+ * @param algorithm the algorithm
|
||
+ * @param publicKey the public key
|
||
+ * @param signature the signature
|
||
+ */
|
||
+ public AerePqAuthorization(
|
||
+ final AerePqAlgorithm algorithm, final Bytes publicKey, final Bytes signature) {
|
||
+ this.algorithm = Objects.requireNonNull(algorithm, "algorithm");
|
||
+ this.publicKey = Objects.requireNonNull(publicKey, "publicKey");
|
||
+ this.signature = Objects.requireNonNull(signature, "signature");
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Whether the key and signature have exactly the lengths of the algorithm's table. A wrong
|
||
+ * length is an invalid transaction, never a truncated or padded verification.
|
||
+ *
|
||
+ * @return true when both lengths match
|
||
+ */
|
||
+ public boolean lengthsValid() {
|
||
+ return publicKey.size() == algorithm.publicKeyLength()
|
||
+ && signature.size() == algorithm.signatureLength();
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The bytes charged as authorization data (AIP-20 gas rule).
|
||
+ *
|
||
+ * @return key length plus signature length
|
||
+ */
|
||
+ public int authorizationByteCount() {
|
||
+ return publicKey.size() + signature.size();
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The sender address of AIP-20: {@code keccak256(0x50 || alg_id || public_key)[12:32]}.
|
||
+ *
|
||
+ * @return the derived sender
|
||
+ */
|
||
+ public Address senderAddress() {
|
||
+ return deriveSender(algorithm, publicKey);
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Derives the AIP-20 sender address for a public key under an algorithm.
|
||
+ *
|
||
+ * @param algorithm the algorithm
|
||
+ * @param publicKey the raw public key
|
||
+ * @return the address
|
||
+ */
|
||
+ public static Address deriveSender(final AerePqAlgorithm algorithm, final Bytes publicKey) {
|
||
+ final Bytes preimage =
|
||
+ Bytes.concatenate(Bytes.of(TYPE_BYTE), Bytes.of((byte) algorithm.id()), publicKey);
|
||
+ return Address.extract(Bytes32.wrap(Hash.hash(preimage).getBytes()));
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * A copy that shares no byte array with the original (for detached transaction copies).
|
||
+ *
|
||
+ * @return the copy
|
||
+ */
|
||
+ public AerePqAuthorization detachedCopy() {
|
||
+ return new AerePqAuthorization(algorithm, publicKey.copy(), signature.copy());
|
||
+ }
|
||
+
|
||
+ @Override
|
||
+ public String toString() {
|
||
+ return "AerePqAuthorization{"
|
||
+ + algorithm
|
||
+ + ", pk="
|
||
+ + publicKey.size()
|
||
+ + "B, sig="
|
||
+ + signature.size()
|
||
+ + "B}";
|
||
+ }
|
||
+}
|
||
diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java
|
||
index e867a21f9..8175f0b4f 100644
|
||
--- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java
|
||
+++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.datatypes;
|
||
|
||
import java.math.BigInteger;
|
||
import java.util.List;
|
||
import java.util.Optional;
|
||
|
||
import org.apache.tuweni.bytes.Bytes;
|
||
|
||
/**
|
||
* A transaction is a single cryptographically-signed instruction constructed by an actor externally
|
||
* to the scope of Ethereum. While it is assumed that the ultimate external actor will be human in
|
||
* nature, software tools will be used in its construction and dissemination.
|
||
*
|
||
* <p>There are two types of transactions: those which result in message calls and those which
|
||
* result in the creation of new accounts with associated code (known informally as ‘contract
|
||
* creation’). Message call transactions will have an address present in the {@link #getTo} method
|
||
* whereas contract creation transactions will not.
|
||
*/
|
||
public interface Transaction {
|
||
@@ -265,21 +271,30 @@ public interface Transaction {
|
||
/**
|
||
* Returns whether the transaction is a contract creation
|
||
*
|
||
* @return {@code true} if this is a contract-creation transaction; otherwise {@code false}
|
||
*/
|
||
boolean isContractCreation();
|
||
|
||
/**
|
||
* Returns the code delegations if this transaction is a 7702 transaction.
|
||
*
|
||
* @return the code delegations
|
||
*/
|
||
Optional<List<CodeDelegation>> getCodeDelegationList();
|
||
|
||
/**
|
||
* Returns the size of the code delegation list.
|
||
*
|
||
* @return the size of the code delegation list
|
||
*/
|
||
int codeDelegationListSize();
|
||
+
|
||
+ /**
|
||
+ * The AIP-20 post-quantum authorization, present only for type 0x50 transactions.
|
||
+ *
|
||
+ * @return the authorization, or empty for every other type
|
||
+ */
|
||
+ default Optional<AerePqAuthorization> getPqAuthorization() {
|
||
+ return Optional.empty();
|
||
+ }
|
||
}
|
||
diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java
|
||
index 8b54a9723..cf6e077d4 100644
|
||
--- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java
|
||
+++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java
|
||
@@ -1,105 +1,116 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.datatypes;
|
||
|
||
import java.util.EnumSet;
|
||
import java.util.Optional;
|
||
import java.util.Set;
|
||
|
||
/** The enum Transaction type. */
|
||
public enum TransactionType {
|
||
/** The Frontier. */
|
||
FRONTIER(0xf8, 0x00),
|
||
/** Access list transaction type. */
|
||
ACCESS_LIST(0x01),
|
||
/** Eip1559 transaction type. */
|
||
EIP1559(0x02),
|
||
/** Blob transaction type. */
|
||
BLOB(0x03),
|
||
/** Eip7702 transaction type. */
|
||
- DELEGATE_CODE(0x04);
|
||
+ DELEGATE_CODE(0x04),
|
||
+ /** AIP-20: Aere post-quantum authorized transaction (ML-DSA), no secp256k1 signature. */
|
||
+ AERE_PQ(0x50);
|
||
|
||
private static final Set<TransactionType> ACCESS_LIST_SUPPORTED_TRANSACTION_TYPES =
|
||
- EnumSet.of(ACCESS_LIST, EIP1559, BLOB, DELEGATE_CODE);
|
||
+ EnumSet.of(ACCESS_LIST, EIP1559, BLOB, DELEGATE_CODE, AERE_PQ);
|
||
|
||
private static final Set<TransactionType> LEGACY_FEE_MARKET_TRANSACTION_TYPES =
|
||
EnumSet.of(FRONTIER, ACCESS_LIST);
|
||
|
||
// The theoretical boundaries of the first byte of the RLP of a Frontier transaction.
|
||
// In practice Frontier transactions almost always start with 0xf8 or 0xf9.
|
||
private static final byte MIN_LEGACY_TX_OPAQUE_BYTE = (byte) 0xc0;
|
||
private static final byte MAX_LEGACY_TX_OPAQUE_BYTE = (byte) 0xfe;
|
||
|
||
// This array helps to translate the first opaque byte of an RLP encoded transaction
|
||
// to its type.
|
||
// Note that Frontier type occupies more slots, since there are different first byte values,
|
||
// that represent such type.
|
||
// Holes in the array represents invalid first byte values, for which there is not (yet)
|
||
// a defined transaction type
|
||
private static final TransactionType[] transactionTypeByOpaqueByte =
|
||
new TransactionType[Byte.toUnsignedInt(MAX_LEGACY_TX_OPAQUE_BYTE) + 1];
|
||
|
||
private static final TransactionType[] transactionTypeByEthSerializedType =
|
||
- new TransactionType[values().length];
|
||
+ // sized by the byte space, not by the enum: AERE_PQ is 0x50 (AIP-20), far past values().length
|
||
+ new TransactionType[256];
|
||
|
||
static {
|
||
EnumSet.allOf(TransactionType.class).stream()
|
||
.forEach(
|
||
tt -> {
|
||
tt.requireChainId = tt != FRONTIER;
|
||
tt.supportAccessList = ACCESS_LIST_SUPPORTED_TRANSACTION_TYPES.contains(tt);
|
||
tt.supportBaseFeeMarket = !LEGACY_FEE_MARKET_TRANSACTION_TYPES.contains(tt);
|
||
tt.supportBlob = tt == BLOB;
|
||
tt.supportDelegatedCode = tt == DELEGATE_CODE;
|
||
+ tt.supportPqAuthorization = tt == AERE_PQ;
|
||
if (tt == FRONTIER) {
|
||
for (int i = Byte.toUnsignedInt(MIN_LEGACY_TX_OPAQUE_BYTE);
|
||
i < Byte.toUnsignedInt(MAX_LEGACY_TX_OPAQUE_BYTE);
|
||
i++) {
|
||
transactionTypeByOpaqueByte[i] = FRONTIER;
|
||
}
|
||
} else {
|
||
transactionTypeByOpaqueByte[tt.getSerializedType()] = tt;
|
||
}
|
||
transactionTypeByEthSerializedType[tt.getEthSerializedType()] = tt;
|
||
});
|
||
}
|
||
|
||
private final byte typeValue;
|
||
private final byte serializedType;
|
||
boolean requireChainId;
|
||
boolean supportAccessList;
|
||
boolean supportBaseFeeMarket;
|
||
boolean supportBlob;
|
||
boolean supportDelegatedCode;
|
||
+ boolean supportPqAuthorization;
|
||
|
||
TransactionType(final int typeValue, final int serializedType) {
|
||
this.typeValue = (byte) typeValue;
|
||
this.serializedType = (byte) serializedType;
|
||
}
|
||
|
||
TransactionType(final int typeValue) {
|
||
this(typeValue, typeValue);
|
||
}
|
||
|
||
/**
|
||
* Gets serialized type.
|
||
*
|
||
* @return the serialized type
|
||
*/
|
||
public byte getSerializedType() {
|
||
return typeValue;
|
||
}
|
||
|
||
/**
|
||
@@ -168,21 +179,31 @@ public enum TransactionType {
|
||
return requireChainId;
|
||
}
|
||
|
||
/**
|
||
* Does transaction type support data blobs.
|
||
*
|
||
* @return the boolean
|
||
*/
|
||
public boolean supportsBlob() {
|
||
return supportBlob;
|
||
}
|
||
|
||
/**
|
||
* Does transaction type support delegate code.
|
||
*
|
||
* @return the boolean
|
||
*/
|
||
public boolean supportsDelegateCode() {
|
||
return supportDelegatedCode;
|
||
}
|
||
+
|
||
+ /**
|
||
+ * Does transaction type carry an AIP-20 post-quantum authorization instead of a secp256k1
|
||
+ * signature.
|
||
+ *
|
||
+ * @return the boolean
|
||
+ */
|
||
+ public boolean supportsPqAuthorization() {
|
||
+ return supportPqAuthorization;
|
||
+ }
|
||
}
|
||
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionBaseResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionBaseResult.java
|
||
index 750dd7bd2..b24ba106d 100644
|
||
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionBaseResult.java
|
||
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionBaseResult.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright contributors to Besu.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
|
||
|
||
import org.hyperledger.besu.datatypes.AccessListEntry;
|
||
import org.hyperledger.besu.datatypes.BytesHolder;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||
|
||
import java.util.List;
|
||
import java.util.Optional;
|
||
|
||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||
import org.apache.tuweni.bytes.Bytes;
|
||
|
||
@JsonPropertyOrder({
|
||
"accessList",
|
||
"authorizationList",
|
||
@@ -35,74 +41,86 @@ import org.apache.tuweni.bytes.Bytes;
|
||
"blockNumber",
|
||
"blockTimestamp",
|
||
"chainId",
|
||
"from",
|
||
"gas",
|
||
"gasPrice",
|
||
"maxPriorityFeePerGas",
|
||
"maxFeePerGas",
|
||
"maxFeePerBlobGas",
|
||
"hash",
|
||
"input",
|
||
"nonce",
|
||
"to",
|
||
"transactionIndex",
|
||
"type",
|
||
"value",
|
||
"yParity",
|
||
"v",
|
||
"r",
|
||
"s",
|
||
+ "algId",
|
||
+ "pqPublicKey",
|
||
+ "pqSignature",
|
||
"blobVersionedHashes"
|
||
})
|
||
public class TransactionBaseResult implements TransactionResult {
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
private final List<AccessListEntry> accessList;
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
private final String chainId;
|
||
|
||
private final String from;
|
||
private final String gas;
|
||
private final String gasPrice;
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
private final String maxPriorityFeePerGas;
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
private final String maxFeePerGas;
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
private final String maxFeePerBlobGas;
|
||
|
||
private final String hash;
|
||
private final String input;
|
||
private final String nonce;
|
||
private final String to;
|
||
private final String type;
|
||
private final String value;
|
||
private final String yParity;
|
||
private final String v;
|
||
private final String r;
|
||
private final String s;
|
||
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
+ private final String algId;
|
||
+
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
+ private final String pqPublicKey;
|
||
+
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
+ private final String pqSignature;
|
||
+
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
private final List<String> versionedHashes;
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
private final List<CodeDelegationResult> authorizationList;
|
||
|
||
public TransactionBaseResult(final Transaction transaction) {
|
||
this(transaction, Optional.empty());
|
||
}
|
||
|
||
public TransactionBaseResult(final Transaction transaction, final Optional<Wei> maybeBaseFee) {
|
||
final TransactionType transactionType = transaction.getType();
|
||
this.accessList =
|
||
transaction.getAccessList().orElse(transactionType.supportsAccessList() ? List.of() : null);
|
||
this.chainId = transaction.getChainId().map(Quantity::create).orElse(null);
|
||
this.from = transaction.getSender().toString();
|
||
this.gas = Quantity.create(transaction.getGasLimit());
|
||
this.maxPriorityFeePerGas =
|
||
transaction.getMaxPriorityFeePerGas().map(Wei::toShortHexString).orElse(null);
|
||
this.maxFeePerGas = transaction.getMaxFeePerGas().map(Wei::toShortHexString).orElse(null);
|
||
@@ -110,52 +128,59 @@ public class TransactionBaseResult implements TransactionResult {
|
||
transaction.getMaxFeePerBlobGas().map(Wei::toShortHexString).orElse(null);
|
||
this.gasPrice =
|
||
Quantity.create(
|
||
transaction
|
||
.getGasPrice()
|
||
.orElseGet(
|
||
() ->
|
||
maybeBaseFee.isPresent()
|
||
? transaction.getEffectiveGasPrice(maybeBaseFee)
|
||
: transaction.getMaxFeePerGas().get()));
|
||
this.hash = transaction.getHash().toString();
|
||
this.input = transaction.getPayload().toString();
|
||
this.nonce = Quantity.create(transaction.getNonce());
|
||
this.to = transaction.getTo().map(a -> a.getBytes().toHexString()).orElse(null);
|
||
if (transactionType == TransactionType.FRONTIER) {
|
||
this.type = Quantity.create(0);
|
||
this.yParity = null;
|
||
this.v = Quantity.create(transaction.getV());
|
||
} else {
|
||
this.type = Quantity.create(transactionType.getSerializedType());
|
||
- this.yParity = Quantity.create(transaction.getYParity());
|
||
+ this.yParity =
|
||
+ transaction.getYParity() == null ? null : Quantity.create(transaction.getYParity());
|
||
this.v =
|
||
(transactionType == TransactionType.ACCESS_LIST
|
||
|| transactionType == TransactionType.EIP1559
|
||
|| transactionType == TransactionType.DELEGATE_CODE
|
||
|| transactionType == TransactionType.BLOB)
|
||
? Quantity.create(transaction.getYParity())
|
||
: null;
|
||
}
|
||
this.value = Quantity.create(transaction.getValue());
|
||
- this.r = Quantity.create(transaction.getR());
|
||
- this.s = Quantity.create(transaction.getS());
|
||
+ this.r = transaction.getR() == null ? null : Quantity.create(transaction.getR());
|
||
+ this.s = transaction.getS() == null ? null : Quantity.create(transaction.getS());
|
||
+ this.algId =
|
||
+ transaction.getPqAuthorization().map(a -> Quantity.create(a.algorithm().id())).orElse(null);
|
||
+ this.pqPublicKey =
|
||
+ transaction.getPqAuthorization().map(a -> a.publicKey().toHexString()).orElse(null);
|
||
+ this.pqSignature =
|
||
+ transaction.getPqAuthorization().map(a -> a.signature().toHexString()).orElse(null);
|
||
this.versionedHashes =
|
||
transaction
|
||
.getVersionedHashes()
|
||
.map(
|
||
hashes ->
|
||
hashes.stream().map(BytesHolder::getBytes).map(Bytes::toHexString).toList())
|
||
.orElse(null);
|
||
this.authorizationList =
|
||
transaction
|
||
.getCodeDelegationList()
|
||
.map(cds -> cds.stream().map(CodeDelegationResult::new).toList())
|
||
.orElse(null);
|
||
}
|
||
|
||
@JsonGetter(value = "accessList")
|
||
public List<AccessListEntry> getAccessList() {
|
||
return accessList;
|
||
}
|
||
|
||
@JsonGetter(value = "chainId")
|
||
@@ -218,50 +243,70 @@ public class TransactionBaseResult implements TransactionResult {
|
||
return type;
|
||
}
|
||
|
||
@JsonGetter(value = "value")
|
||
public String getValue() {
|
||
return value;
|
||
}
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
@JsonGetter(value = "yParity")
|
||
public String getYParity() {
|
||
return yParity;
|
||
}
|
||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||
@JsonGetter(value = "v")
|
||
public String getV() {
|
||
return v;
|
||
}
|
||
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
@JsonGetter(value = "r")
|
||
public String getR() {
|
||
return r;
|
||
}
|
||
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
@JsonGetter(value = "s")
|
||
public String getS() {
|
||
return s;
|
||
}
|
||
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
+ @JsonGetter(value = "algId")
|
||
+ public String getAlgId() {
|
||
+ return algId;
|
||
+ }
|
||
+
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
+ @JsonGetter(value = "pqPublicKey")
|
||
+ public String getPqPublicKey() {
|
||
+ return pqPublicKey;
|
||
+ }
|
||
+
|
||
+ @JsonInclude(JsonInclude.Include.NON_NULL)
|
||
+ @JsonGetter(value = "pqSignature")
|
||
+ public String getPqSignature() {
|
||
+ return pqSignature;
|
||
+ }
|
||
+
|
||
@JsonGetter(value = "blobVersionedHashes")
|
||
public List<String> getVersionedHashes() {
|
||
return versionedHashes;
|
||
}
|
||
|
||
@JsonGetter(value = "authorizationList")
|
||
public List<CodeDelegationResult> getAuthorizationList() {
|
||
return authorizationList;
|
||
}
|
||
|
||
@JsonGetter(value = "blockHash")
|
||
public String getBlockHash() {
|
||
return null;
|
||
}
|
||
|
||
@JsonGetter(value = "blockNumber")
|
||
public String getBlockNumber() {
|
||
return null;
|
||
}
|
||
|
||
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDetailResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDetailResult.java
|
||
index 3531ffa4c..d03b782f5 100644
|
||
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDetailResult.java
|
||
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDetailResult.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.api.jsonrpc.websocket.subscription.pending;
|
||
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.JsonRpcResult;
|
||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
|
||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||
|
||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||
|
||
@JsonPropertyOrder({
|
||
"from",
|
||
"gas",
|
||
"gasPrice",
|
||
"hash",
|
||
"input",
|
||
"nonce",
|
||
"to",
|
||
@@ -51,50 +57,50 @@ public class PendingTransactionDetailResult implements JsonRpcResult {
|
||
private final String yParity;
|
||
private final String v;
|
||
private final String r;
|
||
private final String s;
|
||
|
||
public PendingTransactionDetailResult(final Transaction tx) {
|
||
TransactionType transactionType = tx.getType();
|
||
this.from = tx.getSender().toString();
|
||
this.gas = Quantity.create(tx.getGasLimit());
|
||
this.gasPrice = tx.getGasPrice().map(Quantity::create).orElse(null);
|
||
this.hash = tx.getHash().toString();
|
||
this.input = tx.getPayload().toString();
|
||
this.nonce = Quantity.create(tx.getNonce());
|
||
this.to = tx.getTo().map(a -> a.getBytes().toHexString()).orElse(null);
|
||
if (transactionType == TransactionType.FRONTIER) {
|
||
this.type = Quantity.create(0);
|
||
this.yParity = null;
|
||
this.v = Quantity.create(tx.getV());
|
||
} else {
|
||
this.type = Quantity.create(transactionType.getSerializedType());
|
||
- this.yParity = Quantity.create(tx.getYParity());
|
||
+ this.yParity = tx.getYParity() == null ? null : Quantity.create(tx.getYParity());
|
||
this.v =
|
||
(transactionType == TransactionType.ACCESS_LIST
|
||
|| transactionType == TransactionType.EIP1559)
|
||
? Quantity.create(tx.getYParity())
|
||
: null;
|
||
}
|
||
this.value = Quantity.create(tx.getValue());
|
||
- this.r = Quantity.create(tx.getR());
|
||
- this.s = Quantity.create(tx.getS());
|
||
+ this.r = tx.getR() == null ? null : Quantity.create(tx.getR());
|
||
+ this.s = tx.getS() == null ? null : Quantity.create(tx.getS());
|
||
}
|
||
|
||
@JsonGetter(value = "from")
|
||
public String getFrom() {
|
||
return from;
|
||
}
|
||
|
||
@JsonGetter(value = "gas")
|
||
public String getGas() {
|
||
return gas;
|
||
}
|
||
|
||
@JsonGetter(value = "gasPrice")
|
||
public String getGasPrice() {
|
||
return gasPrice;
|
||
}
|
||
|
||
@JsonGetter(value = "hash")
|
||
public String getHash() {
|
||
return hash;
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
|
||
index 2b976857c..ec42cfd32 100644
|
||
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
|
||
@@ -1,57 +1,65 @@
|
||
/*
|
||
* Copyright contributors to Hyperledger Besu.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.core;
|
||
|
||
import static com.google.common.base.Preconditions.checkArgument;
|
||
import static com.google.common.base.Preconditions.checkState;
|
||
import static org.hyperledger.besu.crypto.Hash.keccak256;
|
||
import static org.hyperledger.besu.datatypes.VersionedHash.SHA256_VERSION_ID;
|
||
|
||
import org.hyperledger.besu.crypto.KeyPair;
|
||
import org.hyperledger.besu.crypto.SECPPublicKey;
|
||
import org.hyperledger.besu.crypto.SECPSignature;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||
import org.hyperledger.besu.datatypes.AccessListEntry;
|
||
+import org.hyperledger.besu.datatypes.AerePqAuthorization;
|
||
import org.hyperledger.besu.datatypes.Address;
|
||
import org.hyperledger.besu.datatypes.BlobType;
|
||
import org.hyperledger.besu.datatypes.BytesHolder;
|
||
import org.hyperledger.besu.datatypes.CodeDelegation;
|
||
import org.hyperledger.besu.datatypes.Hash;
|
||
import org.hyperledger.besu.datatypes.Sha256Hash;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.datatypes.VersionedHash;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder;
|
||
+import org.hyperledger.besu.ethereum.core.encoding.AerePqTransactionEncoder;
|
||
import org.hyperledger.besu.ethereum.core.encoding.BlobTransactionEncoder;
|
||
import org.hyperledger.besu.ethereum.core.encoding.CodeDelegationTransactionEncoder;
|
||
import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
|
||
import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder;
|
||
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
|
||
import org.hyperledger.besu.ethereum.core.kzg.Blob;
|
||
import org.hyperledger.besu.ethereum.core.kzg.BlobsWithCommitments;
|
||
import org.hyperledger.besu.ethereum.core.kzg.KZGCommitment;
|
||
import org.hyperledger.besu.ethereum.core.kzg.KZGProof;
|
||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||
|
||
import java.math.BigInteger;
|
||
import java.util.Collection;
|
||
import java.util.List;
|
||
import java.util.Objects;
|
||
import java.util.Optional;
|
||
|
||
@@ -114,40 +122,43 @@ public class Transaction
|
||
private volatile Bytes32 hashNoSignature;
|
||
|
||
// Caches the transaction sender.
|
||
private volatile Address sender;
|
||
|
||
// Caches the hash used to uniquely identify the transaction.
|
||
private volatile Hash hash;
|
||
// Caches the size in bytes of the encoded transaction.
|
||
private volatile int sizeForAnnouncement = -1;
|
||
private volatile int sizeForBlockInclusion = -1;
|
||
private final TransactionType transactionType;
|
||
|
||
private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||
private final Optional<List<VersionedHash>> versionedHashes;
|
||
|
||
private final Optional<BlobsWithCommitments> blobsWithCommitments;
|
||
private final Optional<List<CodeDelegation>> maybeCodeDelegationList;
|
||
|
||
private final Optional<Bytes> rawRlp;
|
||
|
||
+ // AIP-20: present only for type 0x50; then `signature` is null and the sender comes from the key.
|
||
+ private final Optional<AerePqAuthorization> pqAuthorization;
|
||
+
|
||
public static Builder builder() {
|
||
return new Builder();
|
||
}
|
||
|
||
public static Transaction readFrom(final Bytes rlpBytes) {
|
||
return readFrom(RLP.input(rlpBytes));
|
||
}
|
||
|
||
/**
|
||
* Recreate a transaction from RLP serialized in the block body format
|
||
*
|
||
* @param rlpInput the RLP input in block body format
|
||
* @return the transaction
|
||
*/
|
||
public static Transaction readFrom(final RLPInput rlpInput) {
|
||
return readFrom(rlpInput, EncodingContext.BLOCK_BODY);
|
||
}
|
||
|
||
/**
|
||
* Recreate a transaction from RLP serialized according to the specified format
|
||
@@ -191,40 +202,41 @@ public class Transaction
|
||
private Transaction(
|
||
final boolean forCopy,
|
||
final TransactionType transactionType,
|
||
final long nonce,
|
||
final Optional<Wei> gasPrice,
|
||
final Optional<Wei> maxPriorityFeePerGas,
|
||
final Optional<Wei> maxFeePerGas,
|
||
final Optional<Wei> maxFeePerBlobGas,
|
||
final long gasLimit,
|
||
final Optional<Address> to,
|
||
final Wei value,
|
||
final SECPSignature signature,
|
||
final Payload payload,
|
||
final Optional<List<AccessListEntry>> maybeAccessList,
|
||
final Address sender,
|
||
final Optional<BigInteger> chainId,
|
||
final Optional<List<VersionedHash>> versionedHashes,
|
||
final Optional<BlobsWithCommitments> blobsWithCommitments,
|
||
final Optional<List<CodeDelegation>> maybeCodeDelegationList,
|
||
final Optional<Bytes> rawRlp,
|
||
+ final Optional<AerePqAuthorization> pqAuthorization,
|
||
final Optional<Hash> hash,
|
||
final Optional<Integer> sizeForAnnouncement,
|
||
final Optional<Integer> sizeForBlockInclusion) {
|
||
|
||
if (!forCopy) {
|
||
if (transactionType.requiresChainId()) {
|
||
checkArgument(
|
||
chainId.isPresent(),
|
||
"Chain id must be present for transaction type %s",
|
||
transactionType);
|
||
}
|
||
|
||
if (maybeAccessList.isPresent()) {
|
||
checkArgument(
|
||
transactionType.supportsAccessList(),
|
||
"Must not specify access list for transaction not supporting it");
|
||
}
|
||
|
||
if (Objects.equals(transactionType, TransactionType.ACCESS_LIST)) {
|
||
checkArgument(
|
||
@@ -235,60 +247,73 @@ public class Transaction
|
||
checkArgument(
|
||
transactionType.supportsBlob(),
|
||
"Must not specify blob versioned hashes or max fee per blob gas for transaction not supporting it");
|
||
}
|
||
|
||
if (transactionType.supportsBlob()) {
|
||
checkArgument(
|
||
versionedHashes.isPresent(), "Must specify blob versioned hashes for blob transaction");
|
||
checkArgument(
|
||
!versionedHashes.get().isEmpty(),
|
||
"Blob transaction must have at least one versioned hash");
|
||
checkArgument(
|
||
maxFeePerBlobGas.isPresent(), "Must specify max fee per blob gas for blob transaction");
|
||
}
|
||
|
||
if (transactionType.supportsDelegateCode()) {
|
||
checkArgument(
|
||
maybeCodeDelegationList.isPresent(),
|
||
"Must specify code delegation authorizations for code delegation transaction");
|
||
}
|
||
+
|
||
+ if (transactionType.supportsPqAuthorization()) {
|
||
+ checkArgument(
|
||
+ pqAuthorization.isPresent(),
|
||
+ "Must specify a post-quantum authorization for an AIP-20 transaction");
|
||
+ checkArgument(signature == null, "An AIP-20 transaction carries no secp256k1 signature");
|
||
+ } else {
|
||
+ checkArgument(
|
||
+ pqAuthorization.isEmpty(),
|
||
+ "Must not specify a post-quantum authorization for transaction type %s",
|
||
+ transactionType);
|
||
+ }
|
||
}
|
||
|
||
this.transactionType = transactionType;
|
||
this.nonce = nonce;
|
||
this.gasPrice = gasPrice;
|
||
this.maxPriorityFeePerGas = maxPriorityFeePerGas;
|
||
this.maxFeePerGas = maxFeePerGas;
|
||
this.maxFeePerBlobGas = maxFeePerBlobGas;
|
||
this.gasLimit = gasLimit;
|
||
this.to = to;
|
||
this.value = value;
|
||
this.signature = signature;
|
||
this.payload = payload;
|
||
this.maybeAccessList = maybeAccessList;
|
||
this.sender = sender;
|
||
this.chainId = chainId;
|
||
this.versionedHashes = versionedHashes;
|
||
this.blobsWithCommitments = blobsWithCommitments;
|
||
this.maybeCodeDelegationList = maybeCodeDelegationList;
|
||
this.rawRlp = rawRlp;
|
||
+ this.pqAuthorization = pqAuthorization;
|
||
hash.ifPresent(h -> this.hash = h);
|
||
sizeForAnnouncement.ifPresent(i -> this.sizeForAnnouncement = i);
|
||
sizeForBlockInclusion.ifPresent(i -> this.sizeForBlockInclusion = i);
|
||
}
|
||
|
||
/**
|
||
* Returns the transaction nonce.
|
||
*
|
||
* @return the transaction nonce
|
||
*/
|
||
@Override
|
||
public long getNonce() {
|
||
return nonce;
|
||
}
|
||
|
||
/**
|
||
* Return the transaction gas price.
|
||
*
|
||
* @return the transaction gas price
|
||
*/
|
||
@@ -455,140 +480,150 @@ public class Transaction
|
||
@Override
|
||
public Optional<BigInteger> getChainId() {
|
||
return chainId;
|
||
}
|
||
|
||
/**
|
||
* Returns the transaction sender.
|
||
*
|
||
* @return the transaction sender
|
||
*/
|
||
@Override
|
||
public Address getSender() {
|
||
if (sender == null) {
|
||
Optional<Address> cachedSender = Optional.ofNullable(senderCache.getIfPresent(getHash()));
|
||
sender = cachedSender.orElseGet(this::computeSender);
|
||
}
|
||
return sender;
|
||
}
|
||
|
||
private Address computeSender() {
|
||
+ if (pqAuthorization.isPresent()) {
|
||
+ // AIP-20: no recovery; the sender is derived from the post-quantum public key.
|
||
+ final Address pqSender = pqAuthorization.get().senderAddress();
|
||
+ senderCache.put(getHash(), pqSender);
|
||
+ return pqSender;
|
||
+ }
|
||
final SECPPublicKey publicKey =
|
||
signatureAlgorithm
|
||
.recoverPublicKeyFromSignature(getOrComputeSenderRecoveryHash(), signature)
|
||
.orElseThrow(
|
||
() ->
|
||
new IllegalStateException(
|
||
"Cannot recover public key from signature for " + this));
|
||
final Address calculatedSender =
|
||
Address.extract(Bytes32.wrap(Hash.hash(publicKey.getEncodedBytes()).getBytes()));
|
||
senderCache.put(getHash(), calculatedSender);
|
||
return calculatedSender;
|
||
}
|
||
|
||
/**
|
||
* Returns the public key extracted from the signature.
|
||
*
|
||
* @return the public key
|
||
*/
|
||
public Optional<String> getPublicKey() {
|
||
+ if (pqAuthorization.isPresent()) {
|
||
+ return Optional.of(pqAuthorization.get().publicKey().toHexString());
|
||
+ }
|
||
return signatureAlgorithm
|
||
.recoverPublicKeyFromSignature(getOrComputeSenderRecoveryHash(), signature)
|
||
.map(SECPPublicKey::toString);
|
||
}
|
||
|
||
private Bytes32 getOrComputeSenderRecoveryHash() {
|
||
if (hashNoSignature == null) {
|
||
hashNoSignature =
|
||
computeSenderRecoveryHash(
|
||
transactionType,
|
||
nonce,
|
||
gasPrice.orElse(null),
|
||
maxPriorityFeePerGas.orElse(null),
|
||
maxFeePerGas.orElse(null),
|
||
maxFeePerBlobGas.orElse(null),
|
||
gasLimit,
|
||
to,
|
||
value,
|
||
payload,
|
||
maybeAccessList,
|
||
versionedHashes.orElse(null),
|
||
maybeCodeDelegationList,
|
||
- chainId);
|
||
+ chainId,
|
||
+ pqAuthorization);
|
||
}
|
||
return hashNoSignature;
|
||
}
|
||
|
||
/**
|
||
* Writes the transaction to RLP using the block body format
|
||
*
|
||
* @param out the output to write the transaction to
|
||
*/
|
||
public void writeTo(final RLPOutput out) {
|
||
writeTo(out, EncodingContext.BLOCK_BODY);
|
||
}
|
||
|
||
/**
|
||
* Writes the transaction to RLP using the specified format
|
||
*
|
||
* @param out the output to write the transaction to
|
||
* @param context the serialization format to use
|
||
*/
|
||
public void writeTo(final RLPOutput out, final EncodingContext context) {
|
||
TransactionEncoder.encodeRLP(this, out, context);
|
||
}
|
||
|
||
@Override
|
||
public Bytes encoded() {
|
||
final BytesValueRLPOutput rplOutput = new BytesValueRLPOutput();
|
||
writeTo(rplOutput);
|
||
return rplOutput.encoded();
|
||
}
|
||
|
||
@Override
|
||
public BigInteger getR() {
|
||
- return signature.getR();
|
||
+ return signature == null ? null : signature.getR();
|
||
}
|
||
|
||
@Override
|
||
public BigInteger getS() {
|
||
- return signature.getS();
|
||
+ return signature == null ? null : signature.getS();
|
||
}
|
||
|
||
@Override
|
||
public BigInteger getV() {
|
||
if (transactionType != null && transactionType != TransactionType.FRONTIER) {
|
||
// EIP-2718 typed transaction, use yParity:
|
||
return null;
|
||
} else {
|
||
final BigInteger recId = BigInteger.valueOf(signature.getRecId());
|
||
return chainId
|
||
.map(bigInteger -> recId.add(REPLAY_PROTECTED_V_BASE).add(TWO.multiply(bigInteger)))
|
||
.orElseGet(() -> recId.add(REPLAY_UNPROTECTED_V_BASE));
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public BigInteger getYParity() {
|
||
if (transactionType != null && transactionType != TransactionType.FRONTIER) {
|
||
- // EIP-2718 typed transaction, return yParity:
|
||
- return BigInteger.valueOf(signature.getRecId());
|
||
+ // EIP-2718 typed transaction, return yParity (none for an AIP-20 transaction):
|
||
+ return signature == null ? null : BigInteger.valueOf(signature.getRecId());
|
||
} else {
|
||
// legacy types never return yParity
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Returns the transaction hash.
|
||
*
|
||
* @return the transaction hash
|
||
*/
|
||
@Override
|
||
public Hash getHash() {
|
||
if (hash == null) {
|
||
memoizeHashAndSizeForBlockInclusion();
|
||
}
|
||
return hash;
|
||
}
|
||
|
||
/**
|
||
@@ -742,129 +777,162 @@ public class Transaction
|
||
@Override
|
||
public TransactionType getType() {
|
||
return this.transactionType;
|
||
}
|
||
|
||
@Override
|
||
public Optional<List<VersionedHash>> getVersionedHashes() {
|
||
return versionedHashes;
|
||
}
|
||
|
||
@Override
|
||
public Optional<BlobsWithCommitments> getBlobsWithCommitments() {
|
||
return blobsWithCommitments;
|
||
}
|
||
|
||
@Override
|
||
public Optional<List<CodeDelegation>> getCodeDelegationList() {
|
||
return maybeCodeDelegationList;
|
||
}
|
||
|
||
+ @Override
|
||
+ public Optional<AerePqAuthorization> getPqAuthorization() {
|
||
+ return pqAuthorization;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The AIP-20 signing hash of a type-0x50 transaction: keccak256 of the signing pre-image.
|
||
+ *
|
||
+ * @return the 32-byte hash
|
||
+ */
|
||
+ public Bytes getPqSigningHash() {
|
||
+ return getOrComputeSenderRecoveryHash();
|
||
+ }
|
||
+
|
||
@Override
|
||
public int codeDelegationListSize() {
|
||
return maybeCodeDelegationList.map(List::size).orElse(0);
|
||
}
|
||
|
||
/**
|
||
* Return the list of transaction hashes extracted from the collection of Transaction passed as
|
||
* argument
|
||
*
|
||
* @param transactions a collection of transactions
|
||
* @return the list of transaction hashes
|
||
*/
|
||
public static List<Hash> toHashList(final Collection<Transaction> transactions) {
|
||
return transactions.stream().map(Transaction::getHash).toList();
|
||
}
|
||
|
||
private static Bytes32 computeSenderRecoveryHash(
|
||
final TransactionType transactionType,
|
||
final long nonce,
|
||
final Wei gasPrice,
|
||
final Wei maxPriorityFeePerGas,
|
||
final Wei maxFeePerGas,
|
||
final Wei maxFeePerBlobGas,
|
||
final long gasLimit,
|
||
final Optional<Address> to,
|
||
final Wei value,
|
||
final Payload payload,
|
||
final Optional<List<AccessListEntry>> accessList,
|
||
final List<VersionedHash> versionedHashes,
|
||
final Optional<List<CodeDelegation>> codeDelegationList,
|
||
- final Optional<BigInteger> chainId) {
|
||
+ final Optional<BigInteger> chainId,
|
||
+ final Optional<AerePqAuthorization> pqAuthorization) {
|
||
if (transactionType.requiresChainId()) {
|
||
checkArgument(chainId.isPresent(), "Transaction type %s requires chainId", transactionType);
|
||
}
|
||
final Bytes preimage =
|
||
getPreimage(
|
||
transactionType,
|
||
nonce,
|
||
gasPrice,
|
||
maxPriorityFeePerGas,
|
||
maxFeePerGas,
|
||
maxFeePerBlobGas,
|
||
gasLimit,
|
||
to,
|
||
value,
|
||
payload.getPayloadBytes(),
|
||
accessList,
|
||
versionedHashes,
|
||
codeDelegationList,
|
||
- chainId);
|
||
+ chainId,
|
||
+ pqAuthorization);
|
||
return keccak256(preimage);
|
||
}
|
||
|
||
@Override
|
||
public Bytes encodedPreimage() {
|
||
return getPreimage(
|
||
transactionType,
|
||
nonce,
|
||
gasPrice.orElse(null),
|
||
maxPriorityFeePerGas.orElse(null),
|
||
maxFeePerGas.orElse(null),
|
||
maxFeePerBlobGas.orElse(null),
|
||
gasLimit,
|
||
to,
|
||
value,
|
||
payload.getPayloadBytes(),
|
||
maybeAccessList,
|
||
versionedHashes.orElse(null),
|
||
maybeCodeDelegationList,
|
||
- chainId);
|
||
+ chainId,
|
||
+ pqAuthorization);
|
||
}
|
||
|
||
private static Bytes getPreimage(
|
||
final TransactionType transactionType,
|
||
final long nonce,
|
||
final Wei gasPrice,
|
||
final Wei maxPriorityFeePerGas,
|
||
final Wei maxFeePerGas,
|
||
final Wei maxFeePerBlobGas,
|
||
final long gasLimit,
|
||
final Optional<Address> to,
|
||
final Wei value,
|
||
final Bytes payload,
|
||
final Optional<List<AccessListEntry>> accessList,
|
||
final List<VersionedHash> versionedHashes,
|
||
final Optional<List<CodeDelegation>> codeDelegationList,
|
||
- final Optional<BigInteger> chainId) {
|
||
+ final Optional<BigInteger> chainId,
|
||
+ final Optional<AerePqAuthorization> pqAuthorization) {
|
||
final Bytes preimage =
|
||
switch (transactionType) {
|
||
+ case AERE_PQ ->
|
||
+ AerePqTransactionEncoder.signingPreimage(
|
||
+ nonce,
|
||
+ maxPriorityFeePerGas,
|
||
+ maxFeePerGas,
|
||
+ gasLimit,
|
||
+ to,
|
||
+ value,
|
||
+ payload,
|
||
+ chainId,
|
||
+ accessList,
|
||
+ pqAuthorization.orElseThrow(
|
||
+ () ->
|
||
+ new IllegalStateException(
|
||
+ "Developer error: an AIP-20 transaction must carry its authorization here")));
|
||
case FRONTIER -> frontierPreimage(nonce, gasPrice, gasLimit, to, value, payload, chainId);
|
||
case EIP1559 ->
|
||
eip1559Preimage(
|
||
nonce,
|
||
maxPriorityFeePerGas,
|
||
maxFeePerGas,
|
||
gasLimit,
|
||
to,
|
||
value,
|
||
payload,
|
||
chainId,
|
||
accessList);
|
||
case BLOB ->
|
||
blobPreimage(
|
||
nonce,
|
||
maxPriorityFeePerGas,
|
||
maxFeePerGas,
|
||
maxFeePerBlobGas,
|
||
gasLimit,
|
||
to,
|
||
@@ -1068,89 +1136,92 @@ public class Transaction
|
||
authorizationList, rlpOutput);
|
||
rlpOutput.endList();
|
||
});
|
||
return Bytes.concatenate(Bytes.of(TransactionType.DELEGATE_CODE.getSerializedType()), encoded);
|
||
}
|
||
|
||
@Override
|
||
public boolean equals(final Object other) {
|
||
if (!(other instanceof Transaction that)) {
|
||
return false;
|
||
}
|
||
return Objects.equals(this.chainId, that.chainId)
|
||
&& this.gasLimit == that.gasLimit
|
||
&& Objects.equals(this.gasPrice, that.gasPrice)
|
||
&& Objects.equals(this.maxPriorityFeePerGas, that.maxPriorityFeePerGas)
|
||
&& Objects.equals(this.maxFeePerGas, that.maxFeePerGas)
|
||
&& Objects.equals(this.maxFeePerBlobGas, that.maxFeePerBlobGas)
|
||
&& this.nonce == that.nonce
|
||
&& Objects.equals(this.payload, that.payload)
|
||
&& Objects.equals(this.signature, that.signature)
|
||
+ && Objects.equals(this.pqAuthorization, that.pqAuthorization)
|
||
&& Objects.equals(this.to, that.to)
|
||
&& Objects.equals(this.value, that.value)
|
||
&& Objects.equals(this.getV(), that.getV());
|
||
}
|
||
|
||
@Override
|
||
public int hashCode() {
|
||
return Objects.hash(
|
||
nonce,
|
||
gasPrice,
|
||
maxPriorityFeePerGas,
|
||
maxFeePerGas,
|
||
maxFeePerBlobGas,
|
||
gasLimit,
|
||
to,
|
||
value,
|
||
payload.getPayloadBytes(),
|
||
signature,
|
||
+ pqAuthorization,
|
||
chainId);
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
final StringBuilder sb = new StringBuilder();
|
||
sb.append(
|
||
transactionType.supportsBlob()
|
||
? "Blob"
|
||
: isContractCreation() ? "ContractCreation" : "MessageCall")
|
||
.append("{");
|
||
sb.append("type=").append(getType()).append(", ");
|
||
sb.append("nonce=").append(getNonce()).append(", ");
|
||
getGasPrice()
|
||
.ifPresent(gp -> sb.append("gasPrice=").append(gp.toHumanReadableString()).append(", "));
|
||
if (getMaxPriorityFeePerGas().isPresent() && getMaxFeePerGas().isPresent()) {
|
||
sb.append("maxPriorityFeePerGas=")
|
||
.append(getMaxPriorityFeePerGas().map(Wei::toHumanReadableString).get())
|
||
.append(", ");
|
||
sb.append("maxFeePerGas=")
|
||
.append(getMaxFeePerGas().map(Wei::toHumanReadableString).get())
|
||
.append(", ");
|
||
getMaxFeePerBlobGas()
|
||
.ifPresent(
|
||
wei ->
|
||
sb.append("maxFeePerBlobGas=").append(wei.toHumanReadableString()).append(", "));
|
||
}
|
||
sb.append("gasLimit=").append(getGasLimit()).append(", ");
|
||
if (getTo().isPresent()) sb.append("to=").append(getTo().get()).append(", ");
|
||
sb.append("value=").append(getValue()).append(", ");
|
||
sb.append("sig=").append(getSignature()).append(", ");
|
||
+ pqAuthorization.ifPresent(a -> sb.append("pq=").append(a).append(", "));
|
||
if (chainId.isPresent()) sb.append("chainId=").append(getChainId().get()).append(", ");
|
||
if (transactionType.equals(TransactionType.ACCESS_LIST)) {
|
||
sb.append("accessList=").append(maybeAccessList).append(", ");
|
||
}
|
||
if (versionedHashes.isPresent()) {
|
||
final List<VersionedHash> vhs = versionedHashes.get();
|
||
if (!vhs.isEmpty()) {
|
||
sb.append("versionedHashes=[");
|
||
sb.append(
|
||
vhs.get(0)
|
||
.toString()); // can't be empty if present, as this is checked in the constructor
|
||
for (int i = 1; i < vhs.size(); i++) {
|
||
sb.append(", ").append(vhs.get(i).toString());
|
||
}
|
||
sb.append("], ");
|
||
}
|
||
}
|
||
if (transactionType.supportsBlob() && this.blobsWithCommitments.isPresent()) {
|
||
sb.append("numberOfBlobs=").append(blobsWithCommitments.get().getBlobs().size()).append(", ");
|
||
}
|
||
@@ -1231,40 +1302,41 @@ public class Transaction
|
||
new Transaction(
|
||
true,
|
||
transactionType,
|
||
nonce,
|
||
gasPrice,
|
||
maxPriorityFeePerGas,
|
||
maxFeePerGas,
|
||
maxFeePerBlobGas,
|
||
gasLimit,
|
||
detachedTo,
|
||
value,
|
||
signature,
|
||
payload,
|
||
detachedAccessList,
|
||
sender,
|
||
chainId,
|
||
detachedVersionedHashes,
|
||
detachedBlobsWithCommitments,
|
||
detachedCodeDelegationList,
|
||
Optional.empty(),
|
||
+ pqAuthorization.map(AerePqAuthorization::detachedCopy),
|
||
Optional.ofNullable(hash),
|
||
Optional.of(sizeForAnnouncement),
|
||
Optional.of(sizeForBlockInclusion));
|
||
|
||
// copy also the computed fields, to avoid to recompute them
|
||
copiedTx.sender = this.sender;
|
||
copiedTx.hashNoSignature = this.hashNoSignature;
|
||
|
||
return copiedTx;
|
||
}
|
||
|
||
private AccessListEntry accessListDetachedCopy(final AccessListEntry accessListEntry) {
|
||
final Address detachedAddress = Address.wrap(accessListEntry.address().getBytes().copy());
|
||
final var detachedStorage = accessListEntry.storageKeys().stream().map(Bytes32::copy).toList();
|
||
return new AccessListEntry(detachedAddress, detachedStorage);
|
||
}
|
||
|
||
private CodeDelegation codeDelegationDetachedCopy(final CodeDelegation codeDelegation) {
|
||
final Address detachedAddress = Address.wrap(codeDelegation.address().getBytes().copy());
|
||
return new org.hyperledger.besu.ethereum.core.CodeDelegation(
|
||
@@ -1313,62 +1385,64 @@ public class Transaction
|
||
protected long gasLimit = -1L;
|
||
|
||
protected Optional<Address> to = Optional.empty();
|
||
|
||
protected Wei value;
|
||
|
||
protected SECPSignature signature;
|
||
|
||
protected Payload payload;
|
||
|
||
protected Optional<List<AccessListEntry>> accessList = Optional.empty();
|
||
|
||
protected Address sender;
|
||
|
||
protected Optional<BigInteger> chainId = Optional.empty();
|
||
protected Optional<BigInteger> v = Optional.empty();
|
||
protected List<VersionedHash> versionedHashes = null;
|
||
private BlobsWithCommitments blobsWithCommitments;
|
||
protected Optional<List<CodeDelegation>> codeDelegationAuthorizations = Optional.empty();
|
||
protected Bytes rawRlp = null;
|
||
+ protected Optional<AerePqAuthorization> pqAuthorization = Optional.empty();
|
||
private Optional<Hash> hash = Optional.empty();
|
||
private Optional<Integer> sizeForAnnouncement = Optional.empty();
|
||
private Optional<Integer> sizeForBlockInclusion = Optional.empty();
|
||
|
||
public Builder copiedFrom(final Transaction toCopy) {
|
||
this.transactionType = toCopy.transactionType;
|
||
this.nonce = toCopy.nonce;
|
||
this.gasPrice = toCopy.gasPrice.orElse(null);
|
||
this.maxPriorityFeePerGas = toCopy.maxPriorityFeePerGas.orElse(null);
|
||
this.maxFeePerGas = toCopy.maxFeePerGas.orElse(null);
|
||
this.maxFeePerBlobGas = toCopy.maxFeePerBlobGas.orElse(null);
|
||
this.gasLimit = toCopy.gasLimit;
|
||
this.to = toCopy.to;
|
||
this.value = toCopy.value;
|
||
this.signature = toCopy.signature;
|
||
this.payload = toCopy.payload;
|
||
this.accessList = toCopy.maybeAccessList;
|
||
this.sender = toCopy.sender;
|
||
this.chainId = toCopy.chainId;
|
||
this.versionedHashes = toCopy.versionedHashes.orElse(null);
|
||
this.blobsWithCommitments = toCopy.blobsWithCommitments.orElse(null);
|
||
this.codeDelegationAuthorizations = toCopy.maybeCodeDelegationList;
|
||
+ this.pqAuthorization = toCopy.pqAuthorization;
|
||
return this;
|
||
}
|
||
|
||
public Builder type(final TransactionType transactionType) {
|
||
this.transactionType = transactionType;
|
||
return this;
|
||
}
|
||
|
||
public Builder chainId(final BigInteger chainId) {
|
||
this.chainId = Optional.of(chainId);
|
||
return this;
|
||
}
|
||
|
||
public Builder v(final BigInteger v) {
|
||
this.v = Optional.of(v);
|
||
return this;
|
||
}
|
||
|
||
public Builder gasPrice(final Wei gasPrice) {
|
||
this.gasPrice = gasPrice;
|
||
@@ -1426,129 +1500,138 @@ public class Transaction
|
||
public Builder sender(final Address sender) {
|
||
this.sender = sender;
|
||
return this;
|
||
}
|
||
|
||
public Builder signature(final SECPSignature signature) {
|
||
this.signature = signature;
|
||
return this;
|
||
}
|
||
|
||
public Builder versionedHashes(final List<VersionedHash> versionedHashes) {
|
||
this.versionedHashes = versionedHashes;
|
||
return this;
|
||
}
|
||
|
||
public Builder rawRlp(final Bytes rawRlp) {
|
||
this.rawRlp = rawRlp;
|
||
return this;
|
||
}
|
||
|
||
+ public Builder pqAuthorization(final AerePqAuthorization pqAuthorization) {
|
||
+ this.pqAuthorization = Optional.ofNullable(pqAuthorization);
|
||
+ return this;
|
||
+ }
|
||
+
|
||
public Builder hash(final Hash hash) {
|
||
this.hash = Optional.ofNullable(hash);
|
||
return this;
|
||
}
|
||
|
||
public Builder sizeForAnnouncement(final int sizeForAnnouncement) {
|
||
this.sizeForAnnouncement = Optional.of(sizeForAnnouncement);
|
||
return this;
|
||
}
|
||
|
||
public Builder sizeForBlockInclusion(final int sizeForBlockInclusion) {
|
||
this.sizeForBlockInclusion = Optional.of(sizeForBlockInclusion);
|
||
return this;
|
||
}
|
||
|
||
public Builder guessType() {
|
||
- if (codeDelegationAuthorizations.isPresent()) {
|
||
+ if (pqAuthorization.isPresent()) {
|
||
+ transactionType = TransactionType.AERE_PQ;
|
||
+ } else if (codeDelegationAuthorizations.isPresent()) {
|
||
transactionType = TransactionType.DELEGATE_CODE;
|
||
} else if (versionedHashes != null && !versionedHashes.isEmpty()) {
|
||
transactionType = TransactionType.BLOB;
|
||
} else if (maxPriorityFeePerGas != null || maxFeePerGas != null) {
|
||
transactionType = TransactionType.EIP1559;
|
||
} else if (accessList.isPresent()) {
|
||
transactionType = TransactionType.ACCESS_LIST;
|
||
} else {
|
||
transactionType = TransactionType.FRONTIER;
|
||
}
|
||
return this;
|
||
}
|
||
|
||
public TransactionType getTransactionType() {
|
||
return transactionType;
|
||
}
|
||
|
||
public Transaction build() {
|
||
if (transactionType == null) guessType();
|
||
return new Transaction(
|
||
false,
|
||
transactionType,
|
||
nonce,
|
||
Optional.ofNullable(gasPrice),
|
||
Optional.ofNullable(maxPriorityFeePerGas),
|
||
Optional.ofNullable(maxFeePerGas),
|
||
Optional.ofNullable(maxFeePerBlobGas),
|
||
gasLimit,
|
||
to,
|
||
value,
|
||
signature,
|
||
payload,
|
||
accessList,
|
||
sender,
|
||
chainId,
|
||
Optional.ofNullable(versionedHashes),
|
||
Optional.ofNullable(blobsWithCommitments),
|
||
codeDelegationAuthorizations,
|
||
Optional.ofNullable(rawRlp),
|
||
+ pqAuthorization,
|
||
hash,
|
||
sizeForAnnouncement,
|
||
sizeForBlockInclusion);
|
||
}
|
||
|
||
public Transaction signAndBuild(final KeyPair keys) {
|
||
checkState(
|
||
signature == null, "The transaction signature has already been provided to this builder");
|
||
signature(computeSignature(keys));
|
||
sender(
|
||
Address.extract(
|
||
Bytes32.wrap(Hash.hash(keys.getPublicKey().getEncodedBytes()).getBytes())));
|
||
return build();
|
||
}
|
||
|
||
SECPSignature computeSignature(final KeyPair keys) {
|
||
return SignatureAlgorithmFactory.getInstance()
|
||
.sign(
|
||
computeSenderRecoveryHash(
|
||
transactionType,
|
||
nonce,
|
||
gasPrice,
|
||
maxPriorityFeePerGas,
|
||
maxFeePerGas,
|
||
maxFeePerBlobGas,
|
||
gasLimit,
|
||
to,
|
||
value,
|
||
payload,
|
||
accessList,
|
||
versionedHashes,
|
||
codeDelegationAuthorizations,
|
||
- chainId),
|
||
+ chainId,
|
||
+ Optional.empty()),
|
||
keys);
|
||
}
|
||
|
||
public Builder kzgBlobs(
|
||
final BlobType blobType,
|
||
final List<KZGCommitment> kzgCommitments,
|
||
final List<Blob> blobs,
|
||
final List<KZGProof> kzgProofs) {
|
||
if (this.versionedHashes == null || this.versionedHashes.isEmpty()) {
|
||
this.versionedHashes =
|
||
kzgCommitments.stream()
|
||
.map(c -> new VersionedHash(SHA256_VERSION_ID, Sha256Hash.sha256(c.getData())))
|
||
.toList();
|
||
}
|
||
this.blobsWithCommitments =
|
||
new BlobsWithCommitments(blobType, kzgCommitments, blobs, kzgProofs, versionedHashes);
|
||
return this;
|
||
}
|
||
|
||
public Builder blobsWithCommitments(final BlobsWithCommitments blobsWithCommitments) {
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AerePqTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AerePqTransactionDecoder.java
|
||
new file mode 100755
|
||
index 000000000..29eaa6093
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AerePqTransactionDecoder.java
|
||
@@ -0,0 +1,111 @@
|
||
+/*
|
||
+ * Copyright contributors to the AERE Network.
|
||
+ *
|
||
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
+ * the License. You may obtain a copy of the License at
|
||
+ *
|
||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||
+ *
|
||
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
+ * specific language governing permissions and limitations under the License.
|
||
+ *
|
||
+ * SPDX-License-Identifier: Apache-2.0
|
||
+ */
|
||
+package org.hyperledger.besu.ethereum.core.encoding;
|
||
+
|
||
+import org.hyperledger.besu.datatypes.AccessListEntry;
|
||
+import org.hyperledger.besu.datatypes.Address;
|
||
+import org.hyperledger.besu.datatypes.AerePqAlgorithm;
|
||
+import org.hyperledger.besu.datatypes.AerePqAuthorization;
|
||
+import org.hyperledger.besu.datatypes.Hash;
|
||
+import org.hyperledger.besu.datatypes.TransactionType;
|
||
+import org.hyperledger.besu.datatypes.Wei;
|
||
+import org.hyperledger.besu.ethereum.core.Transaction;
|
||
+import org.hyperledger.besu.ethereum.rlp.RLP;
|
||
+import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||
+
|
||
+import java.math.BigInteger;
|
||
+
|
||
+import org.apache.tuweni.bytes.Bytes;
|
||
+
|
||
+/**
|
||
+ * Decodes an AIP-20 type-0x50 transaction: {@code 0x50 || rlp([chain_id, nonce,
|
||
+ * max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, alg_id,
|
||
+ * public_key, signature])}.
|
||
+ *
|
||
+ * <p>The decoder is strict on shape: an unknown {@code alg_id} or a key/signature of the wrong
|
||
+ * length is rejected here, before any cryptography runs, with an {@link IllegalArgumentException}
|
||
+ * that the callers of {@link TransactionDecoder} already treat as "malformed transaction".
|
||
+ */
|
||
+public class AerePqTransactionDecoder {
|
||
+
|
||
+ private AerePqTransactionDecoder() {
|
||
+ // static
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Decodes the opaque bytes of a type-0x50 transaction.
|
||
+ *
|
||
+ * @param input the opaque bytes, type byte included
|
||
+ * @return the transaction
|
||
+ */
|
||
+ public static Transaction decode(final Bytes input) {
|
||
+ final RLPInput txRlp = RLP.input(input.slice(1)); // skip the transaction type byte
|
||
+ txRlp.enterList();
|
||
+ final BigInteger chainId = txRlp.readBigIntegerScalar();
|
||
+ final Transaction.Builder builder =
|
||
+ Transaction.builder()
|
||
+ .type(TransactionType.AERE_PQ)
|
||
+ .chainId(chainId)
|
||
+ .nonce(txRlp.readLongScalar())
|
||
+ .maxPriorityFeePerGas(Wei.of(txRlp.readUInt256Scalar()))
|
||
+ .maxFeePerGas(Wei.of(txRlp.readUInt256Scalar()))
|
||
+ .gasLimit(txRlp.readLongScalar())
|
||
+ .to(txRlp.readBytes(v -> v.isEmpty() ? null : Address.wrap(v)))
|
||
+ .value(Wei.of(txRlp.readUInt256Scalar()))
|
||
+ .payload(txRlp.readBytes())
|
||
+ .rawRlp(txRlp.raw())
|
||
+ .accessList(
|
||
+ txRlp.readList(
|
||
+ accessListEntryRLPInput -> {
|
||
+ accessListEntryRLPInput.enterList();
|
||
+ final AccessListEntry accessListEntry =
|
||
+ new AccessListEntry(
|
||
+ Address.wrap(accessListEntryRLPInput.readBytes()),
|
||
+ accessListEntryRLPInput.readList(RLPInput::readBytes32));
|
||
+ accessListEntryRLPInput.leaveList();
|
||
+ return accessListEntry;
|
||
+ }))
|
||
+ .sizeForAnnouncement(input.size())
|
||
+ .sizeForBlockInclusion(input.size())
|
||
+ .hash(Hash.hash(input));
|
||
+ final int algId = txRlp.readIntScalar();
|
||
+ final AerePqAlgorithm algorithm =
|
||
+ AerePqAlgorithm.byId(algId)
|
||
+ .orElseThrow(
|
||
+ () ->
|
||
+ new IllegalArgumentException(
|
||
+ "AIP-20: unknown post-quantum algorithm identifier " + algId));
|
||
+ final Bytes publicKey = txRlp.readBytes();
|
||
+ final Bytes signature = txRlp.readBytes();
|
||
+ final AerePqAuthorization authorization =
|
||
+ new AerePqAuthorization(algorithm, publicKey, signature);
|
||
+ if (!authorization.lengthsValid()) {
|
||
+ throw new IllegalArgumentException(
|
||
+ "AIP-20: "
|
||
+ + algorithm
|
||
+ + " expects a "
|
||
+ + algorithm.publicKeyLength()
|
||
+ + "-byte public key and a "
|
||
+ + algorithm.signatureLength()
|
||
+ + "-byte signature, got "
|
||
+ + publicKey.size()
|
||
+ + " and "
|
||
+ + signature.size());
|
||
+ }
|
||
+ final Transaction transaction = builder.pqAuthorization(authorization).build();
|
||
+ txRlp.leaveList();
|
||
+ return transaction;
|
||
+ }
|
||
+}
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AerePqTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AerePqTransactionEncoder.java
|
||
new file mode 100755
|
||
index 000000000..f2de33f67
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AerePqTransactionEncoder.java
|
||
@@ -0,0 +1,152 @@
|
||
+/*
|
||
+ * Copyright contributors to the AERE Network.
|
||
+ *
|
||
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
+ * the License. You may obtain a copy of the License at
|
||
+ *
|
||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||
+ *
|
||
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
+ * specific language governing permissions and limitations under the License.
|
||
+ *
|
||
+ * SPDX-License-Identifier: Apache-2.0
|
||
+ */
|
||
+package org.hyperledger.besu.ethereum.core.encoding;
|
||
+
|
||
+import static org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder.writeAccessList;
|
||
+
|
||
+import org.hyperledger.besu.datatypes.AccessListEntry;
|
||
+import org.hyperledger.besu.datatypes.Address;
|
||
+import org.hyperledger.besu.datatypes.AerePqAuthorization;
|
||
+import org.hyperledger.besu.datatypes.BytesHolder;
|
||
+import org.hyperledger.besu.datatypes.TransactionType;
|
||
+import org.hyperledger.besu.datatypes.Wei;
|
||
+import org.hyperledger.besu.ethereum.core.Transaction;
|
||
+import org.hyperledger.besu.ethereum.rlp.RLP;
|
||
+import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||
+
|
||
+import java.math.BigInteger;
|
||
+import java.util.List;
|
||
+import java.util.Optional;
|
||
+
|
||
+import org.apache.tuweni.bytes.Bytes;
|
||
+
|
||
+/**
|
||
+ * Encodes an AIP-20 type-0x50 transaction and computes its signing pre-image.
|
||
+ *
|
||
+ * <p>Signing pre-image (AIP-20): {@code 0x50 || rlp([chain_id, nonce, max_priority_fee_per_gas,
|
||
+ * max_fee_per_gas, gas_limit, to, value, data, access_list, alg_id, public_key])}; the signing hash
|
||
+ * is its keccak256 and is what ML-DSA signs, in the pure (non pre-hash) interface with an empty
|
||
+ * context string.
|
||
+ */
|
||
+public class AerePqTransactionEncoder {
|
||
+
|
||
+ private AerePqTransactionEncoder() {
|
||
+ // static
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Writes the payload list of the transaction (everything after the type byte).
|
||
+ *
|
||
+ * @param transaction the transaction, type 0x50
|
||
+ * @param out the RLP output
|
||
+ */
|
||
+ public static void encode(final Transaction transaction, final RLPOutput out) {
|
||
+ final AerePqAuthorization auth =
|
||
+ transaction
|
||
+ .getPqAuthorization()
|
||
+ .orElseThrow(
|
||
+ () ->
|
||
+ new IllegalStateException(
|
||
+ "type 0x50 transaction without a post-quantum authorization"));
|
||
+ out.startList();
|
||
+ writeUnsignedFields(
|
||
+ transaction.getChainId().orElseThrow(),
|
||
+ transaction.getNonce(),
|
||
+ transaction.getMaxPriorityFeePerGas().orElseThrow(),
|
||
+ transaction.getMaxFeePerGas().orElseThrow(),
|
||
+ transaction.getGasLimit(),
|
||
+ transaction.getTo(),
|
||
+ transaction.getValue(),
|
||
+ transaction.getPayload(),
|
||
+ transaction.getAccessList(),
|
||
+ auth,
|
||
+ out);
|
||
+ out.writeBytes(auth.signature());
|
||
+ out.endList();
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The signing pre-image of AIP-20 for the given fields.
|
||
+ *
|
||
+ * @param nonce the nonce
|
||
+ * @param maxPriorityFeePerGas the max priority fee per gas
|
||
+ * @param maxFeePerGas the max fee per gas
|
||
+ * @param gasLimit the gas limit
|
||
+ * @param to the recipient, empty for contract creation
|
||
+ * @param value the value
|
||
+ * @param payload the calldata
|
||
+ * @param chainId the chain id (mandatory for this type)
|
||
+ * @param accessList the access list
|
||
+ * @param authorization the authorization whose algorithm and public key are covered
|
||
+ * @return {@code 0x50 || rlp([...])}
|
||
+ */
|
||
+ public static Bytes signingPreimage(
|
||
+ final long nonce,
|
||
+ final Wei maxPriorityFeePerGas,
|
||
+ final Wei maxFeePerGas,
|
||
+ final long gasLimit,
|
||
+ final Optional<Address> to,
|
||
+ final Wei value,
|
||
+ final Bytes payload,
|
||
+ final Optional<BigInteger> chainId,
|
||
+ final Optional<List<AccessListEntry>> accessList,
|
||
+ final AerePqAuthorization authorization) {
|
||
+ final Bytes encoded =
|
||
+ RLP.encode(
|
||
+ rlpOutput -> {
|
||
+ rlpOutput.startList();
|
||
+ writeUnsignedFields(
|
||
+ chainId.orElseThrow(
|
||
+ () -> new IllegalStateException("type 0x50 requires a chain id")),
|
||
+ nonce,
|
||
+ maxPriorityFeePerGas,
|
||
+ maxFeePerGas,
|
||
+ gasLimit,
|
||
+ to,
|
||
+ value,
|
||
+ payload,
|
||
+ accessList,
|
||
+ authorization,
|
||
+ rlpOutput);
|
||
+ rlpOutput.endList();
|
||
+ });
|
||
+ return Bytes.concatenate(Bytes.of(TransactionType.AERE_PQ.getSerializedType()), encoded);
|
||
+ }
|
||
+
|
||
+ private static void writeUnsignedFields(
|
||
+ final BigInteger chainId,
|
||
+ final long nonce,
|
||
+ final Wei maxPriorityFeePerGas,
|
||
+ final Wei maxFeePerGas,
|
||
+ final long gasLimit,
|
||
+ final Optional<Address> to,
|
||
+ final Wei value,
|
||
+ final Bytes payload,
|
||
+ final Optional<List<AccessListEntry>> accessList,
|
||
+ final AerePqAuthorization authorization,
|
||
+ final RLPOutput out) {
|
||
+ out.writeBigIntegerScalar(chainId);
|
||
+ out.writeLongScalar(nonce);
|
||
+ out.writeUInt256Scalar(maxPriorityFeePerGas);
|
||
+ out.writeUInt256Scalar(maxFeePerGas);
|
||
+ out.writeLongScalar(gasLimit);
|
||
+ out.writeBytes(to.map(BytesHolder::getBytes).map(Bytes::copy).orElse(Bytes.EMPTY));
|
||
+ out.writeUInt256Scalar(value);
|
||
+ out.writeBytes(payload);
|
||
+ writeAccessList(out, accessList);
|
||
+ out.writeIntScalar(authorization.algorithm().id());
|
||
+ out.writeBytes(authorization.publicKey());
|
||
+ }
|
||
+}
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java
|
||
index 23539c386..65aff2e43 100644
|
||
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java
|
||
@@ -1,64 +1,71 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.core.encoding;
|
||
|
||
import static com.google.common.base.Preconditions.checkNotNull;
|
||
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||
|
||
import java.util.EnumMap;
|
||
import java.util.Map;
|
||
import java.util.Optional;
|
||
|
||
import org.apache.tuweni.bytes.Bytes;
|
||
|
||
public class TransactionDecoder {
|
||
|
||
@FunctionalInterface
|
||
interface Decoder {
|
||
Transaction decode(Bytes input);
|
||
}
|
||
|
||
private static final EnumMap<TransactionType, Decoder> TRANSACTION_DECODERS =
|
||
new EnumMap<>(
|
||
Map.of(
|
||
TransactionType.FRONTIER, FrontierTransactionDecoder::decode,
|
||
TransactionType.ACCESS_LIST, AccessListTransactionDecoder::decode,
|
||
TransactionType.EIP1559, EIP1559TransactionDecoder::decode,
|
||
TransactionType.BLOB, BlobTransactionDecoder::decode,
|
||
- TransactionType.DELEGATE_CODE, CodeDelegationTransactionDecoder::decode));
|
||
+ TransactionType.DELEGATE_CODE, CodeDelegationTransactionDecoder::decode,
|
||
+ TransactionType.AERE_PQ, AerePqTransactionDecoder::decode));
|
||
|
||
private static final EnumMap<TransactionType, Decoder> POOLED_TRANSACTION_DECODERS =
|
||
new EnumMap<>(Map.of(TransactionType.BLOB, BlobPooledTransactionDecoder::decode));
|
||
|
||
/**
|
||
* Decodes an RLP input into a transaction. If the input represents a typed transaction, it uses
|
||
* the appropriate decoder for that type. Otherwise, it uses the frontier decoder.
|
||
*
|
||
* @param rlpInput the RLP input
|
||
* @return the decoded transaction
|
||
*/
|
||
public static Transaction decodeRLP(
|
||
final RLPInput rlpInput, final EncodingContext encodingContext) {
|
||
if (isTypedTransaction(rlpInput)) {
|
||
return decodeTransaction(rlpInput, encodingContext);
|
||
} else {
|
||
return FrontierTransactionDecoder.decode(rlpInput.readAsRlp());
|
||
}
|
||
}
|
||
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java
|
||
index 7d2b7b22d..45da4a413 100644
|
||
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java
|
||
@@ -1,64 +1,72 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.core.encoding;
|
||
|
||
import static com.google.common.base.Preconditions.checkNotNull;
|
||
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||
|
||
import com.google.common.collect.ImmutableMap;
|
||
import org.apache.tuweni.bytes.Bytes;
|
||
|
||
public class TransactionEncoder {
|
||
|
||
@FunctionalInterface
|
||
interface Encoder {
|
||
void encode(Transaction transaction, RLPOutput output);
|
||
}
|
||
|
||
private static final ImmutableMap<TransactionType, Encoder> TYPED_TRANSACTION_ENCODERS =
|
||
ImmutableMap.of(
|
||
TransactionType.ACCESS_LIST,
|
||
AccessListTransactionEncoder::encode,
|
||
TransactionType.EIP1559,
|
||
EIP1559TransactionEncoder::encode,
|
||
TransactionType.BLOB,
|
||
BlobTransactionEncoder::encode,
|
||
TransactionType.DELEGATE_CODE,
|
||
- CodeDelegationTransactionEncoder::encode);
|
||
+ CodeDelegationTransactionEncoder::encode,
|
||
+ TransactionType.AERE_PQ,
|
||
+ AerePqTransactionEncoder::encode);
|
||
|
||
private static final ImmutableMap<TransactionType, Encoder> POOLED_TRANSACTION_ENCODERS =
|
||
ImmutableMap.of(TransactionType.BLOB, BlobPooledTransactionEncoder::encode);
|
||
|
||
/**
|
||
* Encodes a transaction into RLP format.
|
||
*
|
||
* @param transaction the transaction to encode
|
||
* @param rlpOutput the RLP output stream
|
||
* @param encodingContext the encoding context
|
||
*/
|
||
public static void encodeRLP(
|
||
final Transaction transaction,
|
||
final RLPOutput rlpOutput,
|
||
final EncodingContext encodingContext) {
|
||
final TransactionType transactionType = getTransactionType(transaction);
|
||
|
||
Bytes opaqueBytes = encodeOpaqueBytes(transaction, encodingContext);
|
||
encodeRLP(transactionType, opaqueBytes, rlpOutput);
|
||
}
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AerePqTransactionSupport.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AerePqTransactionSupport.java
|
||
new file mode 100755
|
||
index 000000000..1eaa9aee8
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AerePqTransactionSupport.java
|
||
@@ -0,0 +1,196 @@
|
||
+/*
|
||
+ * Copyright contributors to the AERE Network.
|
||
+ *
|
||
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
+ * the License. You may obtain a copy of the License at
|
||
+ *
|
||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||
+ *
|
||
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
+ * specific language governing permissions and limitations under the License.
|
||
+ *
|
||
+ * SPDX-License-Identifier: Apache-2.0
|
||
+ */
|
||
+package org.hyperledger.besu.ethereum.mainnet;
|
||
+
|
||
+import org.hyperledger.besu.datatypes.AerePqAlgorithm;
|
||
+import org.hyperledger.besu.datatypes.AerePqAuthorization;
|
||
+import org.hyperledger.besu.ethereum.core.Transaction;
|
||
+import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||
+
|
||
+import java.util.Optional;
|
||
+
|
||
+import org.apache.tuweni.bytes.Bytes32;
|
||
+import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters;
|
||
+import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters;
|
||
+import org.bouncycastle.pqc.crypto.mldsa.MLDSASigner;
|
||
+import org.slf4j.Logger;
|
||
+import org.slf4j.LoggerFactory;
|
||
+
|
||
+/**
|
||
+ * AIP-20 support on the validation path: the activation height and the ML-DSA verification of a
|
||
+ * type-0x50 transaction.
|
||
+ *
|
||
+ * <p>Activation follows every other Aere rule: a per-node system property, {@code
|
||
+ * aere.pqtx.forkBlock}, set uniformly on every node that validates or reads blocks. Absent means
|
||
+ * NEVER: a binary that has this code and no property behaves exactly like one that does not have
|
||
+ * it, which is what makes staging the binary ahead of the height safe.
|
||
+ *
|
||
+ * <p>Verification is FIPS 204 ML-DSA in the pure interface with the empty context string, over the
|
||
+ * 32-byte signing hash of AIP-20. Bouncy Castle's {@link MLDSASigner} implements exactly that
|
||
+ * interface when initialised without a context parameter.
|
||
+ */
|
||
+public final class AerePqTransactionSupport {
|
||
+
|
||
+ private static final Logger LOG = LoggerFactory.getLogger(AerePqTransactionSupport.class);
|
||
+
|
||
+ /** The system property that names the activation height; absent means never. */
|
||
+ public static final String FORK_BLOCK_PROPERTY = "aere.pqtx.forkBlock";
|
||
+
|
||
+ private static final long NEVER = Long.MAX_VALUE;
|
||
+ private static final long FORK_BLOCK = readForkBlock();
|
||
+
|
||
+ private AerePqTransactionSupport() {
|
||
+ // static
|
||
+ }
|
||
+
|
||
+ private static long readForkBlock() {
|
||
+ final String raw = System.getProperty(FORK_BLOCK_PROPERTY);
|
||
+ if (raw == null || raw.isBlank()) {
|
||
+ LOG.info("AERE PQ-TX: {} absent, type 0x50 transactions are never accepted", FORK_BLOCK_PROPERTY);
|
||
+ return NEVER;
|
||
+ }
|
||
+ try {
|
||
+ final long value = Long.parseLong(raw.trim());
|
||
+ if (value < 0) {
|
||
+ throw new IllegalArgumentException("negative");
|
||
+ }
|
||
+ LOG.info("AERE PQ-TX: type 0x50 transactions accepted from block {}", value);
|
||
+ return value;
|
||
+ } catch (final IllegalArgumentException e) {
|
||
+ throw new IllegalStateException(
|
||
+ "AERE PQ-TX: "
|
||
+ + FORK_BLOCK_PROPERTY
|
||
+ + " must be a non-negative block number, got '"
|
||
+ + raw
|
||
+ + "'. Refusing to start with an unreadable consensus parameter.",
|
||
+ e);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The configured activation height.
|
||
+ *
|
||
+ * @return the height, or {@link Long#MAX_VALUE} when the type is never active
|
||
+ */
|
||
+ public static long forkBlock() {
|
||
+ return FORK_BLOCK;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Whether type-0x50 transactions are valid in a block at this height.
|
||
+ *
|
||
+ * @param blockNumber the block number being validated or built
|
||
+ * @return true at or above the activation height
|
||
+ */
|
||
+ public static boolean isActiveAt(final long blockNumber) {
|
||
+ return blockNumber >= FORK_BLOCK;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * The message for a type-0x50 transaction seen below the activation height.
|
||
+ *
|
||
+ * @param blockNumber the block number
|
||
+ * @return a human-readable reason
|
||
+ */
|
||
+ public static String inactiveMessage(final long blockNumber) {
|
||
+ return FORK_BLOCK == NEVER
|
||
+ ? "AIP-20 type 0x50 transactions are not enabled on this node ("
|
||
+ + FORK_BLOCK_PROPERTY
|
||
+ + " absent)"
|
||
+ : "AIP-20 type 0x50 transactions are valid from block "
|
||
+ + FORK_BLOCK
|
||
+ + ", this is block "
|
||
+ + blockNumber;
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * Validates the post-quantum authorization of a type-0x50 transaction: presence, exact lengths,
|
||
+ * chain id presence, and the ML-DSA signature over the AIP-20 signing hash. On success the sender
|
||
+ * is derivable from the public key (no recovery is involved).
|
||
+ *
|
||
+ * @param transaction the transaction, type 0x50
|
||
+ * @return valid, or INVALID_SIGNATURE / INVALID_TRANSACTION_FORMAT with the reason
|
||
+ */
|
||
+ public static ValidationResult<TransactionInvalidReason> validateAuthorization(
|
||
+ final Transaction transaction) {
|
||
+ final Optional<AerePqAuthorization> maybeAuth = transaction.getPqAuthorization();
|
||
+ if (maybeAuth.isEmpty()) {
|
||
+ return ValidationResult.invalid(
|
||
+ TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
|
||
+ "type 0x50 transaction carries no post-quantum authorization");
|
||
+ }
|
||
+ final AerePqAuthorization auth = maybeAuth.get();
|
||
+ if (!auth.lengthsValid()) {
|
||
+ return ValidationResult.invalid(
|
||
+ TransactionInvalidReason.INVALID_SIGNATURE,
|
||
+ "post-quantum key or signature length does not match " + auth.algorithm());
|
||
+ }
|
||
+ if (transaction.getChainId().isEmpty()) {
|
||
+ return ValidationResult.invalid(
|
||
+ TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
|
||
+ "type 0x50 transaction must carry a chain id");
|
||
+ }
|
||
+ final Bytes32 signingHash;
|
||
+ try {
|
||
+ signingHash = Bytes32.wrap(transaction.getPqSigningHash());
|
||
+ } catch (final RuntimeException e) {
|
||
+ return ValidationResult.invalid(
|
||
+ TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
|
||
+ "type 0x50 signing pre-image could not be computed: " + e.getMessage());
|
||
+ }
|
||
+ final boolean ok;
|
||
+ try {
|
||
+ ok = verify(auth.algorithm(), auth.publicKey().toArrayUnsafe(), signingHash.toArrayUnsafe(), auth.signature().toArrayUnsafe());
|
||
+ } catch (final RuntimeException e) {
|
||
+ // A malformed key that the length check let through: the verifier throws, the tx is invalid.
|
||
+ return ValidationResult.invalid(
|
||
+ TransactionInvalidReason.INVALID_SIGNATURE,
|
||
+ "post-quantum verification failed to run: " + e.getClass().getSimpleName());
|
||
+ }
|
||
+ if (!ok) {
|
||
+ return ValidationResult.invalid(
|
||
+ TransactionInvalidReason.INVALID_SIGNATURE,
|
||
+ "post-quantum signature does not verify over the AIP-20 signing hash");
|
||
+ }
|
||
+ return ValidationResult.valid();
|
||
+ }
|
||
+
|
||
+ /**
|
||
+ * FIPS 204 ML-DSA verification, pure interface, empty context.
|
||
+ *
|
||
+ * @param algorithm the parameter set
|
||
+ * @param publicKey the raw public key
|
||
+ * @param message the message (here the 32-byte signing hash)
|
||
+ * @param signature the raw signature
|
||
+ * @return true when the signature verifies
|
||
+ */
|
||
+ public static boolean verify(
|
||
+ final AerePqAlgorithm algorithm,
|
||
+ final byte[] publicKey,
|
||
+ final byte[] message,
|
||
+ final byte[] signature) {
|
||
+ final MLDSAParameters parameters =
|
||
+ switch (algorithm) {
|
||
+ case ML_DSA_44 -> MLDSAParameters.ml_dsa_44;
|
||
+ case ML_DSA_65 -> MLDSAParameters.ml_dsa_65;
|
||
+ case ML_DSA_87 -> MLDSAParameters.ml_dsa_87;
|
||
+ };
|
||
+ final MLDSAPublicKeyParameters pub = new MLDSAPublicKeyParameters(parameters, publicKey);
|
||
+ final MLDSASigner verifier = new MLDSASigner();
|
||
+ verifier.init(false, pub);
|
||
+ verifier.update(message, 0, message.length);
|
||
+ return verifier.verifySignature(signature);
|
||
+ }
|
||
+}
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
|
||
index fb71c3558..e765d882f 100644
|
||
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
|
||
@@ -1055,41 +1055,42 @@ public abstract class MainnetProtocolSpecs {
|
||
blobSchedule.getMax(),
|
||
blobSchedule.getTarget(),
|
||
miningConfiguration.getMaxBlobsPerTransaction(),
|
||
miningConfiguration.getMaxBlobsPerBlock()))
|
||
.evmBuilder(
|
||
(gasCalculator, __) ->
|
||
MainnetEVMs.osaka(gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration))
|
||
.transactionValidatorFactoryBuilder(
|
||
(evm, gasLimitCalculator, feeMarket) ->
|
||
new TransactionValidatorFactory(
|
||
evm.getGasCalculator(),
|
||
gasLimitCalculator,
|
||
feeMarket,
|
||
true,
|
||
chainId,
|
||
Set.of(
|
||
TransactionType.FRONTIER,
|
||
TransactionType.ACCESS_LIST,
|
||
TransactionType.EIP1559,
|
||
TransactionType.BLOB,
|
||
- TransactionType.DELEGATE_CODE),
|
||
+ TransactionType.DELEGATE_CODE,
|
||
+ TransactionType.AERE_PQ),
|
||
Set.of(BlobType.KZG_CELL_PROOFS),
|
||
evm.getMaxInitcodeSize()))
|
||
.transactionPoolPreProcessor(new OsakaTransactionPoolPreProcessor())
|
||
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::osaka)
|
||
.blockValidatorBuilder(MainnetBlockValidatorBuilder::osaka)
|
||
.hardforkId(OSAKA);
|
||
}
|
||
|
||
static ProtocolSpecBuilder bpo1Definition(
|
||
final Optional<BigInteger> chainId,
|
||
final boolean enableRevertReason,
|
||
final GenesisConfigOptions genesisConfigOptions,
|
||
final EvmConfiguration evmConfiguration,
|
||
final MiningConfiguration miningConfiguration,
|
||
final boolean isParallelTxProcessingEnabled,
|
||
final BalConfiguration balConfiguration,
|
||
final MetricsSystem metricsSystem) {
|
||
ProtocolSpecBuilder builder =
|
||
osakaDefinition(
|
||
chainId,
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
|
||
index 6d0ff35a2..cb8ddfa43 100644
|
||
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.mainnet;
|
||
|
||
import static org.hyperledger.besu.evm.internal.Words.clampedAdd;
|
||
import static org.hyperledger.besu.evm.worldstate.CodeDelegationHelper.getTarget;
|
||
import static org.hyperledger.besu.evm.worldstate.CodeDelegationHelper.hasCodeDelegation;
|
||
|
||
import org.hyperledger.besu.datatypes.AccessListEntry;
|
||
import org.hyperledger.besu.datatypes.Address;
|
||
import org.hyperledger.besu.datatypes.Hash;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
|
||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||
import org.hyperledger.besu.ethereum.core.feemarket.CoinbaseFeePriceCalculator;
|
||
import org.hyperledger.besu.ethereum.mainnet.block.access.list.AccessLocationTracker;
|
||
import org.hyperledger.besu.ethereum.mainnet.block.access.list.PartialBlockAccessView;
|
||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
||
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||
@@ -191,40 +197,48 @@ public class MainnetTransactionProcessor {
|
||
operationTracer,
|
||
blockHashLookup,
|
||
transactionValidationParams,
|
||
blobGasPrice,
|
||
Optional.empty());
|
||
}
|
||
|
||
public TransactionProcessingResult processTransaction(
|
||
final WorldUpdater worldState,
|
||
final ProcessableBlockHeader blockHeader,
|
||
final Transaction transaction,
|
||
final Address miningBeneficiary,
|
||
final OperationTracer operationTracer,
|
||
final BlockHashLookup blockHashLookup,
|
||
final TransactionValidationParams transactionValidationParams,
|
||
final Wei blobGasPrice,
|
||
final Optional<AccessLocationTracker> accessLocationTracker) {
|
||
try {
|
||
final var transactionValidator = transactionValidatorFactory.get();
|
||
LOG.trace("Starting execution of {}", transaction);
|
||
+ // AIP-20: below the activation height the type is invalid in blocks, on every node alike.
|
||
+ if (transaction.getType().supportsPqAuthorization()
|
||
+ && !AerePqTransactionSupport.isActiveAt(blockHeader.getNumber())) {
|
||
+ return TransactionProcessingResult.invalid(
|
||
+ ValidationResult.invalid(
|
||
+ TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
|
||
+ AerePqTransactionSupport.inactiveMessage(blockHeader.getNumber())));
|
||
+ }
|
||
ValidationResult<TransactionInvalidReason> validationResult =
|
||
transactionValidator.validate(
|
||
transaction,
|
||
blockHeader.getBaseFee(),
|
||
Optional.ofNullable(blobGasPrice),
|
||
transactionValidationParams);
|
||
// Make sure the transaction is intrinsically valid before trying to
|
||
// compare against a sender account (because the transaction may not
|
||
// be signed correctly to extract the sender).
|
||
if (!validationResult.isValid()) {
|
||
LOG.debug("Invalid transaction: {}", validationResult.getErrorMessage());
|
||
return TransactionProcessingResult.invalid(validationResult);
|
||
}
|
||
|
||
final Address senderAddress = transaction.getSender();
|
||
final MutableAccount sender = worldState.getOrCreateSenderAccount(senderAddress);
|
||
accessLocationTracker.ifPresent(t -> t.addTouchedAccount(senderAddress));
|
||
|
||
validationResult =
|
||
transactionValidator.validateForSender(transaction, sender, transactionValidationParams);
|
||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
|
||
index af237e5a2..4c1d265a8 100644
|
||
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
|
||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright contributors to Hyperledger Besu.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.mainnet;
|
||
|
||
import static org.hyperledger.besu.evm.account.Account.MAX_NONCE;
|
||
import static org.hyperledger.besu.evm.internal.Words.clampedAdd;
|
||
import static org.hyperledger.besu.evm.worldstate.CodeDelegationHelper.hasCodeDelegation;
|
||
|
||
import org.hyperledger.besu.crypto.SECPSignature;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||
import org.hyperledger.besu.datatypes.BlobType;
|
||
import org.hyperledger.besu.datatypes.CodeDelegation;
|
||
import org.hyperledger.besu.datatypes.Hash;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.ethereum.GasLimitCalculator;
|
||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||
import org.hyperledger.besu.evm.account.Account;
|
||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||
@@ -341,40 +347,45 @@ public class MainnetTransactionValidator implements TransactionValidator {
|
||
return codeHash.equals(Hash.EMPTY) || hasCodeDelegation(sender.getCode());
|
||
}
|
||
|
||
private ValidationResult<TransactionInvalidReason> validateTransactionSignature(
|
||
final Transaction transaction) {
|
||
if (chainId.isPresent()
|
||
&& (transaction.getChainId().isPresent() && !transaction.getChainId().equals(chainId))) {
|
||
return ValidationResult.invalid(
|
||
TransactionInvalidReason.WRONG_CHAIN_ID,
|
||
String.format(
|
||
"transaction was meant for chain id %s and not this chain id %s",
|
||
transaction.getChainId().get(), chainId.get()));
|
||
}
|
||
|
||
if (chainId.isEmpty() && transaction.getChainId().isPresent()) {
|
||
return ValidationResult.invalid(
|
||
TransactionInvalidReason.REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED,
|
||
"replay protected signatures is not supported");
|
||
}
|
||
|
||
+ if (transaction.getType().supportsPqAuthorization()) {
|
||
+ // AIP-20: no secp256k1 material exists; the ML-DSA authorization is what is verified.
|
||
+ return AerePqTransactionSupport.validateAuthorization(transaction);
|
||
+ }
|
||
+
|
||
final SECPSignature signature = transaction.getSignature();
|
||
final BigInteger halfCurveOrder = SignatureAlgorithmFactory.getInstance().getHalfCurveOrder();
|
||
if (disallowSignatureMalleability && signature.getS().compareTo(halfCurveOrder) > 0) {
|
||
return ValidationResult.invalid(
|
||
TransactionInvalidReason.INVALID_SIGNATURE,
|
||
String.format(
|
||
"Signature s value should be less than %s, but got %s",
|
||
halfCurveOrder, signature.getS()));
|
||
}
|
||
|
||
// org.bouncycastle.math.ec.ECCurve.AbstractFp.decompressPoint throws an
|
||
// IllegalArgumentException for "Invalid point compression" for bad signatures.
|
||
try {
|
||
transaction.getSender();
|
||
} catch (final IllegalArgumentException e) {
|
||
return ValidationResult.invalid(
|
||
TransactionInvalidReason.INVALID_SIGNATURE,
|
||
"sender could not be extracted from transaction signature");
|
||
}
|
||
return ValidationResult.valid();
|
||
diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java
|
||
index 25b1f2d5f..65292ac2d 100644
|
||
--- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java
|
||
+++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright contributors to Besu.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.core;
|
||
|
||
import static com.google.common.base.Preconditions.checkArgument;
|
||
import static java.util.stream.Collectors.toUnmodifiableSet;
|
||
import static org.hyperledger.besu.crypto.Hash.keccak256;
|
||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
|
||
|
||
import org.hyperledger.besu.crypto.KeyPair;
|
||
import org.hyperledger.besu.crypto.SecureRandomProvider;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||
import org.hyperledger.besu.datatypes.AccessListEntry;
|
||
import org.hyperledger.besu.datatypes.Address;
|
||
import org.hyperledger.besu.datatypes.Hash;
|
||
import org.hyperledger.besu.datatypes.Log;
|
||
import org.hyperledger.besu.datatypes.LogTopic;
|
||
import org.hyperledger.besu.datatypes.LogsBloomFilter;
|
||
import org.hyperledger.besu.datatypes.StorageSlotKey;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
@@ -512,40 +518,42 @@ public class BlockDataGenerator {
|
||
public Transaction transaction(final TransactionType transactionType) {
|
||
return transaction(transactionType, bytes32(), address());
|
||
}
|
||
|
||
public Transaction transaction(final Bytes payload) {
|
||
return transaction(transactionType(), payload);
|
||
}
|
||
|
||
public Transaction transaction(final TransactionType transactionType, final Bytes payload) {
|
||
return transaction(transactionType, payload, address());
|
||
}
|
||
|
||
public Transaction transaction(
|
||
final TransactionType transactionType, final Bytes payload, final Address to) {
|
||
return switch (transactionType) {
|
||
case FRONTIER -> frontierTransaction(payload, to);
|
||
case EIP1559 -> eip1559Transaction(payload, to);
|
||
case ACCESS_LIST -> accessListTransaction(payload, to);
|
||
case BLOB -> blobTransaction(payload, to);
|
||
case DELEGATE_CODE -> null;
|
||
+ // AIP-20 transactions need ML-DSA keys; the random generator does not produce them (same as 7702)
|
||
+ case AERE_PQ -> null;
|
||
};
|
||
}
|
||
|
||
private Transaction accessListTransaction(final Bytes payload, final Address to) {
|
||
return Transaction.builder()
|
||
.type(TransactionType.ACCESS_LIST)
|
||
.nonce(random.nextLong())
|
||
.gasPrice(Wei.wrap(bytesValue(4)))
|
||
.gasLimit(positiveLong())
|
||
.to(to)
|
||
.value(Wei.wrap(bytes32()))
|
||
.payload(payload)
|
||
.accessList(accessList())
|
||
.chainId(BigInteger.ONE)
|
||
.signAndBuild(generateKeyPair());
|
||
}
|
||
|
||
private List<AccessListEntry> accessList() {
|
||
final List<Address> accessedAddresses =
|
||
Stream.generate(this::address).limit(1L + random.nextInt(3)).toList();
|
||
diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java
|
||
index 2b649f856..03a72eaf1 100644
|
||
--- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java
|
||
+++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.core;
|
||
|
||
import org.hyperledger.besu.crypto.CodeDelegationSignature;
|
||
import org.hyperledger.besu.crypto.KeyPair;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||
import org.hyperledger.besu.datatypes.AccessListEntry;
|
||
import org.hyperledger.besu.datatypes.Address;
|
||
import org.hyperledger.besu.datatypes.Hash;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.datatypes.VersionedHash;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.ethereum.core.encoding.CodeDelegationTransactionEncoder;
|
||
import org.hyperledger.besu.ethereum.core.kzg.BlobsWithCommitments;
|
||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||
|
||
import java.math.BigInteger;
|
||
import java.util.List;
|
||
import java.util.Optional;
|
||
@@ -96,40 +102,43 @@ public class TransactionTestFixture {
|
||
break;
|
||
case BLOB:
|
||
builder.maxPriorityFeePerGas(maxPriorityFeePerGas.orElse(Wei.of(500)));
|
||
builder.maxFeePerGas(maxFeePerGas.orElse(Wei.of(5000)));
|
||
builder.accessList(accessListEntries.orElse(List.of()));
|
||
builder.maxFeePerBlobGas(maxFeePerBlobGas.orElse(Wei.ONE));
|
||
if (blobs.isPresent()) {
|
||
builder.kzgBlobs(
|
||
blobs.get().getBlobType(),
|
||
blobs.get().getKzgCommitments(),
|
||
blobs.get().getBlobs(),
|
||
blobs.get().getKzgProofs());
|
||
} else versionedHashes.ifPresent(builder::versionedHashes);
|
||
break;
|
||
case DELEGATE_CODE:
|
||
builder.maxPriorityFeePerGas(maxPriorityFeePerGas.orElse(Wei.of(500)));
|
||
builder.maxFeePerGas(maxFeePerGas.orElse(Wei.of(5000)));
|
||
builder.accessList(accessListEntries.orElse(List.of()));
|
||
builder.codeDelegations(codeDelegations.orElse(List.of(CODE_DELEGATION)));
|
||
break;
|
||
+ case AERE_PQ:
|
||
+ throw new IllegalArgumentException(
|
||
+ "AIP-20 transactions need ML-DSA keys; this fixture does not create them");
|
||
}
|
||
|
||
to.ifPresent(builder::to);
|
||
chainId.ifPresent(builder::chainId);
|
||
v.ifPresent(builder::v);
|
||
|
||
return builder.signAndBuild(keys);
|
||
}
|
||
|
||
public TransactionTestFixture type(final TransactionType transactionType) {
|
||
this.transactionType = transactionType;
|
||
return this;
|
||
}
|
||
|
||
public TransactionTestFixture nonce(final long nonce) {
|
||
this.nonce = nonce;
|
||
return this;
|
||
}
|
||
|
||
public TransactionTestFixture gasPrice(final Wei gasPrice) {
|
||
diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AerePqTransactionTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AerePqTransactionTest.java
|
||
new file mode 100755
|
||
index 000000000..6f6da5369
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AerePqTransactionTest.java
|
||
@@ -0,0 +1,210 @@
|
||
+/*
|
||
+ * Copyright contributors to the AERE Network.
|
||
+ *
|
||
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
+ * the License. You may obtain a copy of the License at
|
||
+ *
|
||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||
+ *
|
||
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
+ * specific language governing permissions and limitations under the License.
|
||
+ *
|
||
+ * SPDX-License-Identifier: Apache-2.0
|
||
+ */
|
||
+package org.hyperledger.besu.ethereum.core;
|
||
+
|
||
+import static org.assertj.core.api.Assertions.assertThat;
|
||
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||
+
|
||
+import org.hyperledger.besu.datatypes.AerePqAlgorithm;
|
||
+import org.hyperledger.besu.datatypes.Address;
|
||
+import org.hyperledger.besu.datatypes.BlobType;
|
||
+import org.hyperledger.besu.datatypes.Hash;
|
||
+import org.hyperledger.besu.datatypes.TransactionType;
|
||
+import org.hyperledger.besu.datatypes.Wei;
|
||
+import org.hyperledger.besu.ethereum.GasLimitCalculator;
|
||
+import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
|
||
+import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder;
|
||
+import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
|
||
+import org.hyperledger.besu.ethereum.mainnet.AerePqTransactionSupport;
|
||
+import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator;
|
||
+import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
|
||
+import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||
+import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||
+import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||
+import org.hyperledger.besu.evm.gascalculator.OsakaGasCalculator;
|
||
+
|
||
+import java.io.IOException;
|
||
+import java.io.InputStream;
|
||
+import java.math.BigInteger;
|
||
+import java.nio.charset.StandardCharsets;
|
||
+import java.util.Optional;
|
||
+import java.util.Set;
|
||
+import java.util.regex.Matcher;
|
||
+import java.util.regex.Pattern;
|
||
+
|
||
+import org.apache.tuweni.bytes.Bytes;
|
||
+import org.junit.jupiter.api.Test;
|
||
+
|
||
+/**
|
||
+ * AIP-20 conformance on the Besu-derived client, against the vectors produced by the reference tooling
|
||
+ * (`tools/pqtx/pqtx.mjs vectors`, @noble/post-quantum): the same bytes must decode to the same sender and
|
||
+ * hash, verify under Bouncy Castle's ML-DSA, be charged the AIP-20 gas, and every negative vector must be
|
||
+ * refused for the reason the vector names. Two independent ML-DSA implementations agreeing on the same
|
||
+ * signature is the cross-client property the AIP requires.
|
||
+ */
|
||
+class AerePqTransactionTest {
|
||
+
|
||
+ private static final BigInteger CHAIN_ID = BigInteger.valueOf(28001);
|
||
+
|
||
+ private static String vector(final String id) throws IOException {
|
||
+ try (InputStream in =
|
||
+ AerePqTransactionTest.class.getResourceAsStream("/aere/pqtx/" + id + ".json")) {
|
||
+ assertThat(in).as("vector " + id + " on the test classpath").isNotNull();
|
||
+ return new String(in.readAllBytes(), StandardCharsets.UTF_8);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ private static String field(final String json, final String name) {
|
||
+ final Matcher m = Pattern.compile("\"" + name + "\"\\s*:\\s*\"([^\"]*)\"").matcher(json);
|
||
+ assertThat(m.find()).as("field " + name).isTrue();
|
||
+ return m.group(1);
|
||
+ }
|
||
+
|
||
+ private static Transaction decode(final String rawHex) {
|
||
+ return TransactionDecoder.decodeOpaqueBytes(
|
||
+ Bytes.fromHexString(rawHex), EncodingContext.POOLED_TRANSACTION);
|
||
+ }
|
||
+
|
||
+ private static MainnetTransactionValidator validator() {
|
||
+ return new MainnetTransactionValidator(
|
||
+ new OsakaGasCalculator(),
|
||
+ GasLimitCalculator.constant(),
|
||
+ FeeMarket.london(0L),
|
||
+ true,
|
||
+ Optional.of(CHAIN_ID),
|
||
+ Set.of(TransactionType.EIP1559, TransactionType.AERE_PQ),
|
||
+ Set.of(BlobType.KZG_CELL_PROOFS),
|
||
+ Integer.MAX_VALUE);
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void validVectorsDecodeToTheReferenceSenderAndHashAndRoundTrip() throws IOException {
|
||
+ for (final int alg : new int[] {1, 2, 3}) {
|
||
+ final String v = vector("valid-ml-dsa-" + alg);
|
||
+ final Transaction tx = decode(field(v, "raw"));
|
||
+ assertThat(tx.getType()).isEqualTo(TransactionType.AERE_PQ);
|
||
+ assertThat(tx.getPqAuthorization()).isPresent();
|
||
+ assertThat(tx.getPqAuthorization().get().algorithm())
|
||
+ .isEqualTo(AerePqAlgorithm.byId(alg).orElseThrow());
|
||
+ assertThat(tx.getSignature()).as("no secp256k1 signature on a type 0x50 tx").isNull();
|
||
+ assertThat(tx.getSender()).isEqualTo(Address.fromHexString(field(v, "sender")));
|
||
+ assertThat(tx.getHash()).isEqualTo(Hash.fromHexString(field(v, "hash")));
|
||
+ assertThat(tx.getPqSigningHash()).isEqualTo(Bytes.fromHexString(field(v, "signingHash")));
|
||
+ assertThat(tx.getChainId()).contains(CHAIN_ID);
|
||
+ assertThat(tx.getR()).isNull();
|
||
+ assertThat(tx.getYParity()).isNull();
|
||
+ final Bytes reEncoded = TransactionEncoder.encodeOpaqueBytes(tx, EncodingContext.BLOCK_BODY);
|
||
+ assertThat(reEncoded).as("round trip, alg " + alg).isEqualTo(Bytes.fromHexString(field(v, "raw")));
|
||
+ // a detached copy keeps everything that identifies the transaction
|
||
+ final Transaction copy = tx.detachedCopy();
|
||
+ assertThat(copy.getHash()).isEqualTo(tx.getHash());
|
||
+ assertThat(copy.getSender()).isEqualTo(tx.getSender());
|
||
+ assertThat(copy).isEqualTo(tx);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void validVectorsVerifyUnderBouncyCastleAndPassTheValidator() throws IOException {
|
||
+ for (final int alg : new int[] {1, 2, 3}) {
|
||
+ final Transaction tx = decode(field(vector("valid-ml-dsa-" + alg), "raw"));
|
||
+ final ValidationResult<TransactionInvalidReason> auth =
|
||
+ AerePqTransactionSupport.validateAuthorization(tx);
|
||
+ assertThat(auth.isValid())
|
||
+ .withFailMessage(() -> "ML-DSA verification, alg " + alg + ": " + auth.getErrorMessage())
|
||
+ .isTrue();
|
||
+ final ValidationResult<TransactionInvalidReason> full =
|
||
+ validator()
|
||
+ .validate(
|
||
+ tx, Optional.of(Wei.of(1_000_000_000L)), Optional.of(Wei.ZERO), TransactionValidationParams.processingBlock());
|
||
+ assertThat(full.isValid())
|
||
+ .withFailMessage(() -> "validator, alg " + alg + ": " + full.getErrorMessage())
|
||
+ .isTrue();
|
||
+ }
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void aip20GasIsChargedForTheAuthorization() throws IOException {
|
||
+ final Transaction tx = decode(field(vector("valid-ml-dsa-2"), "raw"));
|
||
+ final long intrinsic = new OsakaGasCalculator().transactionIntrinsicGasCost(tx, 0L);
|
||
+ // 21,000 + 16 * (1,952 + 3,309) + 75,000 = 180,176 (AIP-20 worked example, empty calldata)
|
||
+ assertThat(intrinsic).isEqualTo(180_176L);
|
||
+ final Transaction tx87 = decode(field(vector("valid-ml-dsa-3"), "raw"));
|
||
+ assertThat(new OsakaGasCalculator().transactionIntrinsicGasCost(tx87, 0L))
|
||
+ .isEqualTo(21_000L + 16L * (2_592L + 4_627L) + 100_000L);
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void aCorruptedSignatureIsInvalidSignature() throws IOException {
|
||
+ for (final int alg : new int[] {1, 2, 3}) {
|
||
+ final Transaction tx = decode(field(vector("bad-signature-ml-dsa-" + alg), "raw"));
|
||
+ final ValidationResult<TransactionInvalidReason> r =
|
||
+ AerePqTransactionSupport.validateAuthorization(tx);
|
||
+ assertThat(r.isValid()).isFalse();
|
||
+ assertThat(r.getInvalidReason()).isEqualTo(TransactionInvalidReason.INVALID_SIGNATURE);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void theWrongChainIdIsRefusedByTheValidator() throws IOException {
|
||
+ final Transaction tx = decode(field(vector("wrong-chain-ml-dsa-2"), "raw"));
|
||
+ final ValidationResult<TransactionInvalidReason> r =
|
||
+ validator()
|
||
+ .validate(tx, Optional.of(Wei.of(1_000_000_000L)), Optional.of(Wei.ZERO), TransactionValidationParams.processingBlock());
|
||
+ assertThat(r.isValid()).isFalse();
|
||
+ assertThat(r.getInvalidReason()).isEqualTo(TransactionInvalidReason.WRONG_CHAIN_ID);
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void aShortSignatureAndAnUnknownAlgorithmAreRefusedBeforeAnyCryptography() throws IOException {
|
||
+ for (final int alg : new int[] {1, 2, 3}) {
|
||
+ final String raw = field(vector("short-signature-ml-dsa-" + alg), "raw");
|
||
+ assertThatThrownBy(() -> decode(raw))
|
||
+ .isInstanceOf(IllegalArgumentException.class)
|
||
+ .hasMessageContaining("byte signature");
|
||
+ }
|
||
+ final String unknown = field(vector("unknown-alg-0x10"), "raw");
|
||
+ assertThatThrownBy(() -> decode(unknown))
|
||
+ .isInstanceOf(IllegalArgumentException.class)
|
||
+ .hasMessageContaining("unknown post-quantum algorithm identifier 16");
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void theTypeIsNeverActiveWithoutTheForkBlockProperty() {
|
||
+ // the test JVM does not set aere.pqtx.forkBlock, so the rule is "never": the same as a binary without it
|
||
+ assertThat(AerePqTransactionSupport.forkBlock()).isEqualTo(Long.MAX_VALUE);
|
||
+ assertThat(AerePqTransactionSupport.isActiveAt(Long.MAX_VALUE - 1)).isFalse();
|
||
+ assertThat(AerePqTransactionSupport.inactiveMessage(1)).contains("not enabled");
|
||
+ }
|
||
+
|
||
+ @Test
|
||
+ void aClassicalTransactionCarriesNoAuthorizationAndStillWorks() {
|
||
+ final Transaction tx =
|
||
+ Transaction.builder()
|
||
+ .type(TransactionType.EIP1559)
|
||
+ .chainId(CHAIN_ID)
|
||
+ .nonce(0)
|
||
+ .maxPriorityFeePerGas(Wei.ONE)
|
||
+ .maxFeePerGas(Wei.ONE)
|
||
+ .gasLimit(21_000)
|
||
+ .to(Address.ZERO)
|
||
+ .value(Wei.ZERO)
|
||
+ .payload(Bytes.EMPTY)
|
||
+ .signAndBuild(
|
||
+ org.hyperledger.besu.crypto.SignatureAlgorithmFactory.getInstance().generateKeyPair());
|
||
+ assertThat(tx.getPqAuthorization()).isEmpty();
|
||
+ assertThat(tx.getR()).isNotNull();
|
||
+ assertThat(new OsakaGasCalculator().transactionIntrinsicGasCost(tx, 0L)).isEqualTo(21_000L);
|
||
+ }
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/INDEX.json b/ethereum/core/src/test/resources/aere/pqtx/INDEX.json
|
||
new file mode 100755
|
||
index 000000000..8ae144888
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/INDEX.json
|
||
@@ -0,0 +1,93 @@
|
||
+[
|
||
+ {
|
||
+ "id": "valid-ml-dsa-1",
|
||
+ "expect": "valid",
|
||
+ "alg": 1,
|
||
+ "hash": "0x5ee00afa7d595efaffab2cf573a82e50c7d0f37bc1c2a53a11f7120155bf57b6",
|
||
+ "sender": "0xa4fe6cb101b79c0531f265f6b2584b37073087a5"
|
||
+ },
|
||
+ {
|
||
+ "id": "bad-signature-ml-dsa-1",
|
||
+ "expect": "INVALID_SIGNATURE",
|
||
+ "alg": 1,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "wrong-chain-ml-dsa-1",
|
||
+ "expect": "WRONG_CHAIN_ID (when validated on 28001)",
|
||
+ "alg": 1,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "short-signature-ml-dsa-1",
|
||
+ "expect": "INVALID (length)",
|
||
+ "alg": 1,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "valid-ml-dsa-2",
|
||
+ "expect": "valid",
|
||
+ "alg": 2,
|
||
+ "hash": "0xc7903f14f8aa0ffc09cdfcd433e20f07ceaa63ab9b56b84ba41fc8dab7204952",
|
||
+ "sender": "0x0602be26ec9e01dd88121f7c203ead9eecb9ad3e"
|
||
+ },
|
||
+ {
|
||
+ "id": "bad-signature-ml-dsa-2",
|
||
+ "expect": "INVALID_SIGNATURE",
|
||
+ "alg": 2,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "wrong-chain-ml-dsa-2",
|
||
+ "expect": "WRONG_CHAIN_ID (when validated on 28001)",
|
||
+ "alg": 2,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "short-signature-ml-dsa-2",
|
||
+ "expect": "INVALID (length)",
|
||
+ "alg": 2,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "valid-ml-dsa-3",
|
||
+ "expect": "valid",
|
||
+ "alg": 3,
|
||
+ "hash": "0xe37a3c437aacfb3f7abe9bd9da80fb8a50398a56e6b60e6fd29f08abd049d9d7",
|
||
+ "sender": "0xaee69521a942a58325bd694f2cc3d64752465d4a"
|
||
+ },
|
||
+ {
|
||
+ "id": "bad-signature-ml-dsa-3",
|
||
+ "expect": "INVALID_SIGNATURE",
|
||
+ "alg": 3,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "wrong-chain-ml-dsa-3",
|
||
+ "expect": "WRONG_CHAIN_ID (when validated on 28001)",
|
||
+ "alg": 3,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "short-signature-ml-dsa-3",
|
||
+ "expect": "INVALID (length)",
|
||
+ "alg": 3,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ },
|
||
+ {
|
||
+ "id": "unknown-alg-0x10",
|
||
+ "expect": "INVALID (unknown alg_id)",
|
||
+ "alg": 16,
|
||
+ "hash": null,
|
||
+ "sender": null
|
||
+ }
|
||
+]
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-1.json b/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-1.json
|
||
new file mode 100755
|
||
index 000000000..c0a74d633
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-1.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "bad-signature-ml-dsa-1",
|
||
+ "expect": "INVALID_SIGNATURE",
|
||
+ "alg": 1,
|
||
+ "raw": "0x50f90ec5826d6180843b9aca0084773594008302d5709400000000000000000000000000000000000000010180c001b90520372c0f4874450fb92ace74d41bc0326c7f739589f9b86a97afa87ef65d5939e608c81a44909e41f41931349f744b7aedff8d5270b91c4a2f61192e2bb6e3e6d12231deab235359e78ccada386becb6a6a1105afc0999243ab8b363f7cd2c19b2b741c9969dcf20252f20d130dc05d9244f58d6de9b4fb4b6f0125c43b60ebe3c7272b6ae7578f1abb4bb5e2dcb31eebf4aa7089aa2bf40a0ba5eb73aaa90e45472168738cb0e866547e079075d0341c4728ed794cd449d0cdeceaf64d09173a2677e3f2621b56014df58ee8de2bbcf8cb2bf369e57a28e40b24df6d0b15d3417b7b7fce3c49230b3bb7c7080c4f1344380db37299d8c0c29a7c9e95bfc4f3ec70b767895be6ad798449f94c92f320696f8f9ec844fc9451f5ab30874e6c78673b932e24a918d5bc03f4fa647c8679631ad8b30ba4f9a1a790a535104f5079f781fa4c4aad807777327e08bd6e14b957e527650d39e2de7d30da7b2b27457d3539c2f99903054bd1a6d6301b2f83249db80dedc911059b047b5552407ed32b79b57ea4968198decf978fed532277fb189841d0c17f261f1a7c4618c33b258a71cb6b2b921c48735c1fbc375a80fe2d702e9f70db34547147f6d65153f1c508ff90aaf57dfde59ce6e56c5c52049b10fbc2640cd937bf5027d755444cd5e84aad66be4ccf04f710f0b970cbe7fc5e4e7a44f5d8fc2af94ec6df87862dabe0d85dd17e43728800d5dc8ff9e9e1fd349b9d6431f264836a447646a1ee2d73e6a4d1803d71b98510d94d53b5d07764400f413b7837f463e273980296ad5e78a62c83fb91354c25c2e28bfa19480ca41b0ca2d8beed456029eabc0ba69cf3504cf1207ab21bed0e3a60795f5b066019132212a9bd20e98b43bb32484454b7693bc63764d0ba8768da4336ad16a979b1d3e8b06e89afc4caafaddead83ad861a4596814062468d8cb2e131e71cf38c4e335bb3d1d9629251fd50a4273999a20e11d9a881fa2465c2ef32301fa8805ccb38b4656e3c815b54ef42f292d05847c0e5149b0a2ffd1719fcad10730b763406e9e453d2e4a556c397a984a7d8622466522e79f715f980279cb2d1d74d5fd15f8beb8df9c0a1fb93f0d5494ab701cd60cf2b613b484a191d873449c4815f44eebb62658ef90f7033a5e48d40c8f4ec9a25d4f1b73a150e5b03a4feec9142362e77d74d364bb8a40f9873efa2d9f458d84277fdb0063642d9ebc794356368a0b4e53f6ab0d9acf4418fa42d05c11db12cb67d6c4cbbfde4d85358abaf8042510db53c1540fcb40045b334bc54a17608e82433d1e9e53c99769b86b69b8cf1914584cdef479061718a2cc5bec5c31272e0463139721c0c3523a6ea31832b5c15aa59819304c217fbc51a2636bfff331e6dc1037e89be15c17d6708762976329353612f312b828e525c09b81afafa5ae5c25d82b70b6e55f892429a93e5eb4048ade675583e828da988f9d253123a06c0ed047adf4d93d20cc6c865f5a761fec27811305165cd4bda05f563215d0612944b88ade9d64477ae8fb441978720e70b0d77e2edafd3a2c571cd28a42cca2f289d157cec813c24e7f56051b4f28c153adfbb2c1ff90ea1fbc03cb89603387169072442f5d3081140e2256ebadcd775d2f1da92c15a9ff1ce6e980b3b1e91a7e379081ed46a4259fada21536af318eb2043ea16cece60b73acd415d239389cad9212e15bad1b1ae38f93c756635a9b87417faa844e4f43bae1f1ae68641a04f0ff1d55f9045cf7e3ed59fde5c07219b9113329356d4300885ee19c9955c5757db33c6ae75b49d035003171d02ccbd7321d6a14db0bd011d4877f04070dbda3b67bf22d083eb90974674be581b59cd495740a8a9aaaf7c6801a8bcedb531ace47da1be56ab30f1c4ccdaad6e81aa97352baca12b6c69754123bdee38c0d57bf15f0850572dc9b456234eaf37eb478f9117f952ae95a0d165d12d948b51672a03c9610a98cf332d6ad7ab8a87defb3ef7249cf8c3a815129ecf5600500702b7916ffe570cef0714e0c083a581c2971c45c4aa6b1c5226400e5fd594ea3ae97fe94a0dc7f1e0979b11a2f3d15ad54fea957992ada816f97cd76168a53ebffae36e5787b0f69e94b3e08eadefe4937ce8b383b5022e57ba7135cccd5b48e38916f1f0bdcbc5858bf93cad75195d4329ab41a518d820262b1b610f7bdbe1d6749d006a0dfe18d0be1a19fb3d8e37795b5bc37ebcd884f91459164cd2536b3496c4b25a4c74282ece5d64ab861184e942cf97f0edbe6e1293c4504d861e60d98c4f6523df27a1e80843005ad21665b3adcf46f349fb0d905d70631d2ee51c0086b252778eac27346eee65c0fc88c6db5936337b0afa7d8cec656612c81e11cc55abf421df770e6c2588c743d5540e1280be76309defaffde2b82c808976c337ee13735a21900a4686423625a0ba4819581edbe574e6d7053c5fd98d288db4104ea64fbc0e7ad11d50eb1470a882aa00ebfd983cdda14db34f7f968ccc93097cf037dceeb1375f2df4de09c8785f5fef8fbbe284566e5c9a2d38f5d2f9145b7f5087f6a89a56679680ca4180ad7da3ee45da685f0255a45db806e1379c1ed59bfe63feb7d74a239334c80ab9c1859d205ba798810adf8afc569170f94167439d137215d2ce0b2fa983ac138a3ce201cec4927c62b740912e7287417f86beb07af9c83fff843df1abd6e6f81865b82b3168528d1c473b4999b0179f1de8ae22e8ed7f698ee8463eb93fcfd4e017f29ab3f15a2e061de6deb09459d4ecc62741ffd8514d5c1f10eb3b1525ad60512ffad00e360e0d6add8ed6d6df48d63cf1e36f306bd76b1a245cdd09951727367e45b3a02d748dbfcbeea342be4cb0e1e3108e57993581409f8c6b34e2d38becfcf15c653b92c88412c087eddb0bc21eeb620317f49a9bf5d6164418a26322e1964fd676a547862c2a7ce5f13898e3fadec79a638f257532cfe977fe8ba5e96782f9e1e3e8b5f896a80d816141f0c988ea59ea321cffd23f298b76e49e92189e7f65718d14091daeb82d432470a2e472a39a154226a43c543db2bb933adad08344259ba08a65c543d2ee07b67328ca2d4e60e550b85215ea5873fedb505cc1e4db49e129249fb632ba22f11b897b9423d08f96ceaa863cd29dc16af6ac76c4388c2795250c04377277626992b085ed7be2cf1d63a2eda4b65e287081fdc4e9a3224ff57d81b3ba8d04eb88430a01c5eba35fad028e8de1812920cee2576d0bd291407c5fb70c5ce07104b9af7b98c4c709c7f019d4a66b136120b92612ad5e73dfcfc1da0fec3a7928e57d7d4769eecbaa4c269f2859d31d47d1ae40e4da5bfa6592074c5bf54b04c707b8d97455a0a606686e06bf5ef7617da2532f305267f61c5f627216b06ecc3da6c6f7b420e2dfecaa41657eab20c89927ad6eb5c4fcd513da89a637755f4a98c45cfa108f37415bbf49ee6cacfda8f22f7101a9798d844709a38f9168685f105157a937bb10d4f5b342deab8b8be8231490da52cc0c407bf942270ad93d4a9bed5c06499584835dbba75577dbbc47fd3d397f0417ade99549de4412c8893cf3e1a2ed74c234a7b60461efad57d9c9fed9eec3ebd652282b045174e19355d8cfcc10add9192ffffd428150dc3f48e0417e47d6407008c62486cd4057535a5a9ffc45ef559a51fbbece64306f64da9740108d0b51d01423379bb0a72fe050d2abf5f5acd25cff57f8e3bcdf938749c7bbf77437424ada88c167bcb6addc309b949a8e200b9a5b6797522635731b250e2405f98d054aaff4179ccb4b24159e4c033329100cadbef3da262203622d27899166f6c3c79a35daf7840853b9a3ce494bf035235cada8c31e28be56f0976ef9b96f15de57e6896a5aed57a7b5ce77cacd1c806ecf83566bee5d577f7414a106ce16ca6e8cbc144f571b1a37647041694a6409f68d15604960417a60bc4f1a878eb01e89159e701bb8fd96be45395a8b8c4f0cc5b982582741c4ccaff8961ea892f084b10646c7a27687a2d3c92324cc3a19a5b38ca2d5c573167ad54486ab3adfe9219882f947cc6a93a3827f4b51d76e90ffd1587646d921482022db8b5a22519be3a1e62e9a13ff9926e75c42e07aa295c8486df69dc96168e920e13c85eeda86dc560b9f5d4c77cb8ff001d390dc6c5a911c573ab1711df534930ef28832936c80cafcde731e999ce90741e669d93f653efba12466726fa997e7ad24d34395a02b8a4286f3604f120bf47e8ec41954e6def2de896be477ef7916f18214d28f58ae91ed8d7eae9e2df600d313b6cdb952195e9d030e0b8fc98a68cced3070f4abd2d252727320eb54b602ec861ba630ed3c5d6fc8c8b39f4f1e9c198a6dc8d5f825159ce15fcd7bea5701a225ac41bb152d1a077adc03ecf06870375f2d2618094a648b40244e4a981e7efeadc608c082dc1824c4ffdbc39afcc8c464ed5ca8dfc1540ae3a6c034364c356bf13f880abe8633fa041db78f4be0d17a4bb00959a697935c844c6ddc02222f7aebb1af2c96a757536159dc1dbc31131aefe4c198ccd2123eb5d0ca6147bbc9ab43e993508ef4ca383e2847d9fcb4c975dcb240bcfd164daa835311cf7dbde0f256deb5f3748b55c312a29a042725ecf07caa904513e71b4c0ebd3b31c2938e710e7c6be819bb3125e638ee4b54b4c8fe16df1cee7587e6bdfdcccf2e3b2aa4a54c86b0ae711f056c229c644f519f60570aed60fd3d0638dc341625fb4949d355e7d84cb478133d25730162623acbf5d36b9ed98dbd88b6bf7bf1f55006f5ba2d16297557f966cc01baca56e3f6435b724c0b6fa4cc0074efb0bb2cf0cba9a1c73d3337db7dc0c78b87746db7bbe5fc003edf608ce5d91dbd8b3cec0f738de14c8e2b6df47df91805eab5635402ff26245430641abd9511cffa6bf8d352a1f0d97ce2b08561c97a5f07a07e0ac42a2a73366442e0bf125a718553794b021640ef9f9f07040068cce2337606af46f897b7ad8ced05e14f7ab3e2bd847f810058d665a0c3b6903efd8f398c31e356b48216111d30348acf93d28dbec8e603cd16ea5d3b24f38367c52f5629fd51bec34e86ff21d4f5466a53aea7048babf3afaecec2c9de099bcb2845f66689e02306760ef5274e65f36fc61edf8112b3b414a878b8dbdc2ced0d7dae0e95c5d6e7c80a3b4cbccfe13293e454b6c757a8d9496999fb0c4d4dfe5e7f3f40e11172324323556687e95a4a6bfc4dadbec000000000000000000000000000000101a2f41"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-2.json b/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-2.json
|
||
new file mode 100755
|
||
index 000000000..c07213da9
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-2.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "bad-signature-ml-dsa-2",
|
||
+ "expect": "INVALID_SIGNATURE",
|
||
+ "alg": 2,
|
||
+ "raw": "0x50f914be826d6180843b9aca008477359400830383209400000000000000000000000000000000000000010180c002b907a05424000ae9a496294dd6b99046cfdbb235ae71031b379ce274c13b0c96411740cb61021a5390fbe8fb56b642b4e5e5abb7aeab143e0037f8db283b9f2febd650265ed6b05f1b867c124aef245c1811422f92414447fd0b20844e0f1b1cb4eec052400aad52b9d773aae0015c0c390bfdde3d367bd8ef9c3c73bca3164b9d418ecbb2d25303bbd12739a858c5fac4cbfa0203b9f3c319e9bc89d17a7a244b57d6613b5caabdb528f077eff9727015b9c266d777c0ba11920118c7ec4dd59b380c40e361a5b23ce04be4c61e12a1c21e091fa0d890687cbf588944db3e34253c75cdf797378de79162e0b4ca309f550365a289f652dd6d559478912cff70a5417589f73f14640970694d7b5a6bd8f000a65c632f0326ed3d128fda96dbea68cb812634dd75e9f63813a5645336681378b6a63220c066550aba43a5b937131d41f08752d13949a115a74bf96fa1925ff4338e10df0301abe40aaa49e14a1a1d58eef005a0f1d0299267002cebeda20cadcea7419cd0c365c53aede1aa36efaf764d3d36169747cdc8ee9a09e0a0ac6bcaeaeded0cd303c965d705d1b91a8b35f408ad8a033b02ff57610bddbfa60e2114e53f20f8fcad15dffac6a494c3f4f631590f2be3422af14cba7c900c9c38796952e20c3069bea2ab54bf0edf9315903aa5cf68549f878eafcc77561b36f8b78d950871ed4914417316f868a2bc54c72d3c9929f0138a2f0cbccb7c4141e94bb8a7ae11f660861cbbe498697d7327709271460a75bd4e024de3d4d6fe5af066944c96ba87459fa948a95eeb61abbaf643190ccaa9cd18591eb6f249a6eb92db89fc95616d21b41d7d15424b80a750938a12cd57d50ef95aaf222025dc4d81df320d9bc32c608b1c5a1aac8bd14c0f7a4c4380cdd65c793a6287050ff4d609102fd91e47e7365fb55513aeca273618528c199f7bb151e9c11a0bf202147734d1be9d5d0e9318096fa567317ed9fa6a8efe201b915b9aa05ca0d19e15c9a80449cc130b398ebbac3d938f55eea8f74e024b0e33dfecdbea02b920ddc5b277146685916194bfa1f8ac7784c7ed76923d4ff9ed97d3ceac283f9b26977df0133c5fa4fb5fcec577bc152e926529f06ff50c204c083c0b4d6b8d474cf5cf7cfcf7acf76921225443eb0abf5e4c76d0a3f524243ee4e372e80ff0f76dd9d135f240114a2ebe6d69609b6c60d275f251d7dceadc600d18e0cf8bc8fa8392e61fa32b8f7481c4883e19d820b51af0f87d3f7faae44e3b908fc759c6de59361487d8e424ffbd662d57a68801110e9cb099214143253949cc479eaae0e321fecab90c63b06819ce3cf56fc2fc1419408075c658024a28950aa47d549bcdb8b5bc9aeab463466c7834ca7d73058c206a95a023f0c8ac95badd383e63041e1f0ef69f51634f5ce2f48d80f8f2e92f4a1fb5322930141fc50e1e20bd235a8b8d768d473b46711257d028e710f82f0b6bd923da05ca64ae805f708577e125b3fca2feb5656f61ded034eaae481a195628801c82db85345f9ffdc72c860cffe2264ba4be2a08fdb37a4f5f80276baba4ea637847335c89dbd35504389f68b2d61ea66d4eac5fd0057d9e757d929214a7d83daf2fc2b3f840e083792d20d772584b252ba955ae8ae8c36af648c59ae0b25d3bca19413fbd749077b6969db5847409d13e4a67387e59116fe3836a733f3253d47f9919f49618fac8edf5fd711a4239447655d6c40f479f86ef3c9d4dc1a6f9683a3f1bc5c9730025e76ea1588d43494f59823f42c207e34412f73c7e2a126501b8fb810f12995c213063d909a5a9c2653d3511ceb809efa69c638f4c977d46a2a305cc831ecc0feebf5d9356ede6c780da78fe2ad683b3312282d5142612c0d1f85108de04de5c3d5414b62826d5b75f8887dc2d932c40f306c08e5d4f69ef4d344fe4317552df9890d0961e3d857bd9b2c5b44536d8606f62f66d14ddd43b0e5d3379cf66d664616df12b1c62385a57f6a562c34e120b79d64ca39d8b23e1e07b2c03910d711f09df5b54cb0e133dd751bea7832fdb38de2f1dafae69fbdf82b6887ff0a92940299020a835b958bb01b25b8699a0846614cb256a6621ef92e4a0947df9141ed4f91eca527aef25862158a8fa712dd60dda947f6a16e077810e29542a56f9244c34a73454b9ad0d8e8c40bd503efe12c4e5bf7d0ff8e6ab642a039f4e8b575d33c0c3de77a1abfa60b0252d7a549dd791d9630c8b848988157608448d77938bfb27beaea8f9b4a259263797c5b2fbdc7f469b2769f7dcb7b9478cdf5f109322eb2f0a83163469b72d8121fe8e01df227563cbd941a1f63961e2a010c6322a812a014279583a0066492a17d1a15c07024f6b8b1561041b3db608ec1c7475ce4d086e60523e85d7a955841558a35535d6e52cb166669a69049646b94d2fdb901ffbb1446a2d7f58696bce000ccbbb6942b0ad6480d006602c228218d3a2f0bc6a5d5c73acda9fc4b0b496a7d527050f8d77b71641f030368e9494bfe8e9dbf6dd4040426da1b0423739b40450273f4a8d551637e5fe3ca8d54fc476e6278e75cebf4a4ac3ac8ef3807041c4b274568797c8caaffae7df08c6c158d92411db981ea02cc212064c3ad6a9cd1cc02087acce5ceb8d7cddaec429d199c3d90670288be6e88e6826d1f6c417df5f35139c71a62c0267adfce7cb3aa49e827165b28c8cc157a691cb52ef103d8d7ca0ebfc628904d0b2d365dd3401b620d6d93cef670e2fb90ced32fc1486a0e70aeb6fef62ce5a0dfb51fcec12164e4024b0c49ce8b65e01356d80a9571af8f69a9c7256ed549d699a31ceff21c13c482ee0c5759f96125b0099495feacf22a001b2c887b107a9ca9e84de461fbc6e143566de56c710156de5b5f4b7ffe29c0124c1fbb6a792110284c9ad713d89bbb5ed444d09408c65a9f74c5f6c4fd281d31738db82913dcd1ac1fccbba24dc933fb9a8e6c4e426fb98590d7da0252c34d866c114526ded1c9d96daea12ecbd8f2a44531dfb72f02c02b267edf0560b1fb06b087bb6ce02b2922d92f81bb7da99b90e4a2dd68aa858759584490be602369dd606a510b6228e3b941421a3006a697b79866cae011d8aa496de4f3bfffdc0a087d01323db849f6237d7ac476d18bb417f26a697388b4c0a78533f3dd763398719c9ee5bf0299786fb8c4143af8c1195103390d4494b735c06b5815c454dba2fcdd27d214c48712609ffe7ad7c082e835d7477de2358fb3c4b5162027f816ca85aa4a46c25105175e77c8e5394db6fb3999c25ce578f066329182b28fd5b68769cb07ebc67e47a537f6cb62bfd18af162113a4df7f8908e0ce953b6a9637c850f24de0fda239c25fe4352f3b381fc270384d51d1af1ef0dea8501f98ea71f26de97e98799c4b2a316a216bd4af4861ad83fa4570532029564581bb35ac543355ba3aa246b59c6a5d9a91b938f3c4f0ad6d6f567fffdb6fb78402ded5fdc544a0f5fd87e4677326ca003dffdba8fd390487a6469991506a18f376b12db5be3bdcf4a4bc2f5b34dd8f7066bec3b40a6502f414eac3cd1ed43431b033757e86cca57691b0e1f7eec68fad9423f8b0620aa94798546bc878cf29d74ae74af5244ed9b97107fb83abe25dc160ec05cda1c50b76db981aca781868a7913a3e7c98aa5a3ea8bc81270e6f565138dba33c9c7e887641fd3dafd458b9c64600151038db05725a976950307c662c2eb668e3067f943b9bfd805307729b39ed77309fd5e67ecfc56cc231057a6628fb6f528fb969378529dea2c58fa0b4d791ca591ced733e8cf93a8e19907538f45c2618612648d3e1a78492afc154b7bb0285aea97d618e74a74530b492c66c6bd31557cdc55476b3f163196ec8e87f110834ffb8c232dc77cbf2f7b490f520b3b328af44fecca860a19bee9af6a5f69f63487d7dc6b7bf1233c4735522fedd475f905f044a0a7f658a7a378958cca56a163a343a010f4b65d1bc38cd57d08e0f887293fbc106ad7b15aacca6d51558cb8478b119acde04a19b007802a8e9578121304622aee7858d1794ade88973d6fdf981ebabc98fc417d765c075bf8f76b9781dff7c60071878027c057aade8eaf820186035499e9e5fbf8791e6fc0a0e49047af312a8b1b1e80628dc4db4f45842e19096a54733d28028203aa668bd8655631a01c000c956c32ff10572fdbc95b2f26d09fca84c093ddaa122ad93598c03de9273873ece5096648a6251a27e993ec7b6ea4f2181c09bb06852799323f3e993a4b7461439f702cb9df183fcaab11b8bd2ad391924d5e6ef261fea01c91cdc10d9345c290dfc3c040318d11419563d407c8365fef3dd31d8f9d7d338f5f2cd00433d1d06547ae9c650d14d9a7e5b683f0458e7a909d90d4a57201ca5b8753c13bda3591f9cadffd0987d1c7fca1c5a0cec1e13c612d0390d7c0e2f422c97cda29959cd7b714fbeaa5da7b0bcf911c2744a9a25c7d49e93342f61e10a33fda80fadfed2668bfab8767ce80480093b4845cd5ec83082e8f9ad63236743e72842d1a3226640a549c2c1d002a176e2427b2ae612dc272e3d9fa80a904eb8f93f494a52706346c08b06c9d1d8a61a9c7112c0933910882f0da6eea3c389f4faeea51c03394eab4cc02056d704b8839afd76f0839be5ffdc873b88f9a755be6f0229b0843839a25d63c18da89be1c5da930a101913ffba01fd00f2a447d5f58ae8f21554feb47f42d40c32158219dbbb1e5e96ab3dc26cd6a435525c265b65b0bf48d68e9b3c9178a509833aa47c23e63aa9a6f74bef1e4ef863556b11c014b85ac7c157f1e64531b676eb28c68e82e0089d2bd798213c836cc354d4883dc0b607456ab7f894f0a1f73356fc05a5c97a9cf3b231890c39105b751f6fc54063a08f3d3a264ab90cb7de1d0e2f6acb92302cc9b4bb512e720e6ff8343004028ad223a70d395c5f974d3ddd380f798e80edb4b13555c3be0cb1a500e19a8b1b05f9cae85d7eed756ebcfa57828f1054296ffa48d426ceb83c69ebe1b983421f42316ca6f50bf8df0f4d4aeef85005638a304d88764ec26366a1437867c89800aee55ba428e0c07542e123d748c795560153007f768b20bb057fc2643b7db992c3b9cbfd88657b17fbe8a783da2050affb518cab4226cdf28fa97f48651bd142932835f061f8642e79d1f7ae8ff8665aa85aba24a850b2042dd37e61e665a451f17cbe9d57ed5ecb1dce9ec34c576762929dbf46964de7c44c9f6b10fcf52b48649ded2d491bbe4bb6ad578cd31cbdea6df8342dbb7f33857617250b014fc6d887a448f7a5cef25ff69dbc94733bfac1d5f8593af7fbe4759d23ba8da1f405ba179c96d8ae49eb760446d842f0d61ab08508a3e31e4953e13a1b197d00644303e8a9513199583709f41757740a0dff347c3859d3a4ec391481af349019f75ccfdba111a4c338fd8283733115ce7c114111abb157c1a5a84f7b39779a54f000827a250bff00dbe9cb7162d81f6c942b719f9eb973ac7d4652b911622396c517c6e9c7e5f839c049855567fb53ae84579388e3c87af420272558c686209fd92fc339a553f873995932d9dce52f5e60cc0889c3283f94a0d2d5d011154d9935e1dfbb7e747b393bdd8a84f601adca56d4ac5e8e6f28100a7d5522de50dbf1bd7f5604fdfa660a58dc681b4b230abbc4f594a972a73456de1b7f48975cd03313a80074f5d6701db61860f33dfcc9f06e313e8881c385a50de28ced014daf702f01c45368419b73383008b9191293f59fa87a1ceb0cee64d486842ed7c289dca3b3f2e261df644de0f739079ba5ea195468f0693a995dae8e0f7e4611196824f329fc803bc3588d7d941d1fe86a3ecdb3eb8f6d4066ecee371f9a14e5bd46a40b53e87325bab7255099b4fe7f7b09eddaefc6582feecb8dec02b5e58d735a927d052e263027fa879fceb852b9e08db4636c7152f272a43ae4037c50210e90caa3e008fbfa98ed42cd425259096fc06644edab9b768779dcd892747f18a9cecc6aa31dc27d3f12a540447653edd5bed68f50da71b7992434b74d0209746f93ea429691fcb99da0ca32df822ec4332f7eb4bbe6d2111ac84a55932b3e173e388ab96a5a8a17c7d8b8131cf566e0335b0c4a37c5ae24e73c81146031295b69ce3032fa8e4c7616558179cc561f14864190d458cb82370749d595966047de698256126a4ca23a6bbd39201b8649fbcd387474ecf5b9f732e65938fe393a2a1269b06b9b49c5d8882d70776fc823da5842d812be2a65d2f5ee0d64f8258e761e6f2d4c1a825963b367d70b9e81b46fc25e4804fe9decf3aa0e47f1eba573a24f0e4f7b8cf8a886c7ef4175bd317709feeabe46df9719e7d7a4bc2c1bbc15a58b5332ea558e160f5d3b7aa84fe54ea7a24bd8e394ab794e72db7946780272556be33b7f32a0ee651c013d8ed3b5d75bc1c4826dc94f9e3711c53be3bcdf361329544f2993a189b6431a6dda8b81cb1b7c3a69ba96c1ac84a55100c4985cc85ce272e8eb5a57c563a7ad782664d561c3400e779317122d425c9c4193414bebd4d6ad31ba916448f65e9a7ca1f856dacf9d88b695410c8491a759d2c0304e8368b39cf502d0abf7233b1ba9671bc422ce182833ead52597481ea3ea26a2cc35e12a8c83bbb263202d5e9e7a5bb8ab2a5a844d596c24fdac423981fc4dc4291944ae476d59c9a31a05f79f0fe4b39f145c4fba857fa553a17fb2d5f941d5dac8dd3dd07e48eabfe5b98f3c41e7a84986dc3a7a3bb0ed2d4232cffbc50f167d58fb52fa3b357e76430d7f0f1aff6e2d51ea8f5b98bb66c5b5687821f33b9b6c2e407ad0e8140c4d5d4f1739167f8d63284caf4a43688473cd97bab401218fbb2ea13be81bbc05a81042a02eb1843bd46ca535e778e207c79ce3fe511a55d21bf20b24bcdfb43fa62b3469fae2ebd61e362d5d663fb2c08cbde5df9d8cc1faaf6370b5328ffccde873849299d61477a9fcf7c5c96fbc51b24c0f2cc6e39a46f4a9c1f5214f2cd06db62a37e2c6f477ceac0b92eb882d7bcd1fc3721a89745473eb45eee9a4fe6ab323d28f4db957d0c5dc1ed25ebc194f744a2cfe98474868e6acf5641ad454b3626ac2a27a9db416eb1763935eaa5612e43c49e8959ebcf5133863e98c19618e936f33952699fc224f41a4e259b40228047ed6a17cf4f3a42dc76df1346acb0986984f1692b5ed28f0825a23094ddbb8c1750e9035b1df2166f142e7f179473098ed73acb9ffb8be530542f31de88d6677f805cc30ccc0b60787e61f9d195ceacf07a35d979f9c3521f23671f378a6cd58ed2b0620ff7e2def5025f878d70008744c6a53caf325293353747c94c5ddf12e3a42686f97adc4db62b5e2e91132345963b7292fc9d13b484f75d8da000000000000000000000000000000000a13171d2127"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-3.json b/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-3.json
|
||
new file mode 100755
|
||
index 000000000..7131da266
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/bad-signature-ml-dsa-3.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "bad-signature-ml-dsa-3",
|
||
+ "expect": "INVALID_SIGNATURE",
|
||
+ "alg": 3,
|
||
+ "raw": "0x50f91c64826d6180843b9aca00847735940083045f289400000000000000000000000000000000000000010180c003b90a20fd3c43f5fc7807747a73e1d8e78cd9e611ad6bbba9b264534594174b49082aeab827927b335526cc50c2f0368fc666efb79c34af8ee90427d1718736acaad47f5959b9b26457619c07c2dda553d55a7498e30a37c92909f6b37c246dca4e8fd24d4cccd811396d276e5d11f1e8d14bb9eb4d5ec49798202422edd57ea4d8c0e8c6388e9c93a0ff2e52f7ca2303e40300c50c926a7da22919be462e2dcbdb3ec235b14290a282ee76a04f4bf7c5e2ec5c8fc0aaac72ce4f8fcf0d42b9fc3c4049ab6dfdfa12623d89c0d96434a8e13cb6f79ad6f4a8102f9a0bfe582d967372d8928ff9d7d7393b22ec1386ee91dd196eb9c349a6a12f7504e66a096eec0a8ae98e62275f6b84fb40a81a390c6ef0102c8fd2c11d303745b8fc49e638e6f3004961724a977a18d81efc67e37d0d44558e28cf9015dfa08eff82004c4a53dfa40c2451fa03a987f70c855dbee37e36480863044165e6d46d4c43278091317beab6f301d61c8f54f94ee88fa358c9aed6e55b80b4196e79a3d7251ede25c4baef8129882a69789df3a8262941199ded7bd381de00c257199c18e9086d9ce3f72c6d95c0a4d109a3a15474805f0dc06649a16a7805e8d74bd1af7658f5f9ef726d560595ff9f072d4cfaaf61283087843b904b0f5670ca551079c759d4a2839a71505e007cb5d49b0437b87a080fab5e2efdedd1d01f0f1ab72f0e6129a2525fc6e9829b56ce9d9f287a5bd80be8b1556e4ca82eafc60ec22315448768a72e45d4d956c16ee48a0658e307f81ee0f695f1b1b747d1d533d8da720f088b64608b1edb2d4d27247b2cd35e3d94e1256a3c5c944bbafe07b55ca74df4ec0b869733ddb466717a16e98af4ec310d046c90046c024fb33fbb2ffbb105d41bdd0e0af27b1239aa4d92b6ef8d727e51372fefc3b5c8bc6eb585a0ae2dd9970009555c2c2ced5e5a1e97c659565b6139dc4f3bae788e21f9658affa8fdb6f4733f7fa83fefab91a030f8ec976b8263c17abcef46dc22456d5347eea7c30dd25bdc3caad7cb2010f06573d56b6e5d28e6e847d8df8f18d6a2655ea66fe3c8e7e4ef192b5a8aeb35f8469277657b77155142c7b1653d5eb9cf9c4d69bbc5746e0c1876e330f9016a2f5343ec60b2f35ea380169a2bdf102888e6aae7e797d0bce73834f418018e8e55492da8236a542a999d9eea55bd52ee2e59feb0329d716c78c0bfcd79dc27cd9639399d2fd99d2fc9c4900ad60bdb8221501038ec4baadd2ac4830b2bfe1e20804c818c8e089661e7d842bc4e566fa0bc2d7968a44f8df0d4e88e494fc7bebdb695d3a8edf6a2703817b0f8c1a55569ac4a8ff0931137f075797e9744135a3fec6c767af26d4592a9022271a4052b1f1f24f072bd5ceb1d19e02b0bbf31251a7bb8b723bd3da02f59ca1c0c91bc10896970a1e0f8e0fd5b755da58d70be8935f65661629a9f833b35810113ce80125f8ed7a031cfd5eb1475b597856b4ce7629a9429d840a3457bbd70c05c73c6ce84dd59f917a24d06ca8743225ab8c266e209fbadf57cdb587df96eedf54c04fb3f83ec0dddd1d8bf9051c6de4db3aa099f1779f3f30f61f432e5c8f6b7ac4ee6c6dd6fce667556df155ddb2002735fb7addd8acf74863ccfe04a3088317634eb47e56b18c79f31318ac5e448a9094b5c2c70b44dbbbff7c235cef4701d504723b032726d009c6d7f527e645a23fc1ab478e6e2699211694d575bd436d778e7ae53868c63dfb78f591d82b979585cec8bbcde61f375e783e97e8f787fb392fa4f0bc3e9010aa9ec3cf6471bb16355c3ed3fdf2ee5b95ade86371d60fb0699a851770a212d0e0eeb3f20df78ab180343fd79a9d04d8dc56d9fe3d820b27d98d12275a40d270f4181aa1a18305c8d3469a954b2e85405a394684cc234702a6cb01c04ccc941a4392cf64ba31bea700d339152fce6abb0dbe84823b8d3b18258a29414fd52c91ccbc198e101287b79d8bd0e5f4b05a14a07055e66ea37d781934840a204638bffda400113bb1344126fe1c2ac1e57bb861c3d35349b1fba0c11e12921262ae52fb2e0bee444f8197e2817b9356e10af67e794a7967055936bfcb51f4be6fc5602a8df97ddcd73afe83c02f00d4f1d8302bd2e826d4c50fd3ded9a74debd0e807b694e912a8a3a800f5b983e171898874b77ea305ede4abdf0db5ca84a8a60b184374c08066537b08d42a609b97039ff8905bccc4454188b051c5d1e574e1e8b74cc5cbded064a5374c55f17002ee9b17447fdc324a12e3f2f414b491cccf20c9f98820461f4c7d61355a30f1a6cbb2fe7403b90587298fcc9500519451e44225c750b8b32a649ea288eda389e596390a5386652dea5d0e096ee270bcab9da0c3c4ba464f44172732a748e339cbfc8f0c1ee3187225e2fb29e67ffbd84df8acf759c817d628e03a245e9ae0cf00939fa12964e8dc124659eea8798b097ba52480532fa11194e4623ff63f6cc1d17c7080bb2c1459fe8cc9b197b89ba91986b7bfa61e514bf5c60f981e63baffd9fce44af87ad73fba197e46790fc03f8a46aa6d7590f47e08daedd7f564685208ee87da84b04b11cdc0c020bb26b0abdad3c1340649130e26af9c7651533313301e8b517a84c807d86a4c0cff68566d34da4111d67bdc77ef5f49ec7d83af24a143bceaee020acce02499c725ebc341a86d91c7f63dd962ffcc09fc0b5673873ee55cea4bba69b5058e4b364fb3802832d5118774790dd12eed78330412dc877cc034309a7e292ebee955a431fd46faf7884cf3bd5ab03d02b8784af2a84bb907ba5f021fc332f638a2d4b6451ea0a2cdee6ff1621d698eadfc99d6f405003f300e321a9e80ed3b577a899fa7dd891b53cab8acaa9fd3ce02640eaa75646f134c190817675b9e4a688d0668528fa3b378749bb6b1a0bd16873e89dfc927dcf568fc3cf94ac49d289ba1fb9c58a74574c8fbac321db256bf919e9432d6a8ae9a0dae900901f436b13d0c2b753a5eb6fcef03301d7faa15ff32ec0730335b13394bff66ea83a7043f9e1df5962671ff2d2759db234a4a4fa47fd3a9359bb14ef5b5fc398836d42afcc5d5f252b1b061afc6a0815b3a7586d25eed5ee52c56d2389b8f2438649ee652b431d3cc4262c6e5ea1c0ccec21aa6123e88b4bc933098576bd78cf5bcbbc278ee682029e05e91aac2043ad3ec1d3d97f6ebc6bd5faffa5bc71328cd4351bcb9a0d8d1ea9253b97b08c8c53b20e29703568d5d7dfa2bfa6aeb3a93043e4123116a125311695a11c8538658210971d7763ed7870c1309893909e306df22fe968612531e58a91d19dfe2c658ade19c8e0900c779af8ec333d19552e42cdedbe13ff85d99b10baf8daf70951290db56bc7ea049e6b468b6546a7f3ae77c2e14770eed1ea345f0d139336af4eee686ac2e73bd4262cb802e0173fb872a77cd2c0f3421c497b0260be79ae29d04d9a9da9d7bc101ae3ec9dace1133332f05b7b82aaee577c06c0d2a8eaa8a96db8b899cb3240cc4dca4f8eab513ad5b3529063b5df3664dde0db1e0ae5c29e69f011076fc7edc4261d043f38f1c68645466c9a5e685a07393b7e2f8f74db86742ba5ac089b45a42df3f943842747674c1653aa2a8ef282f64e7ec2ce1fada994288a5f9b95da4bc083ea008308b91213c64a08868ea0fdad9fbb1b485b793bce6e4fa945668b2351232a7c8a084fb2d87a5c83e7dced6bde3743617a7c4babcbf9381694b64d7e0feeb6615440e927a63293c6b695900b1e7afad1ae612c324a88e6761c3b6fdc41d18f514be1ba3a1ca53fdbcf8c19f95bcd60223abe52d07fd7c4114dad9f347cf122f6241429da7e598959c22692910323a0a699595398f518c58deea7159920d89e3e65702bc2cabea7e9ca0bbb7002fb7be5243bba6a08a12238ead443ff4394510d25eb279885d9112c44529f294c5a2bf493a74ba8f4e38744e632680b3ce055a897d2a5468ef52e6e70dc5af55a9fb83739f6cfc6994871662b8263f2e07e21a6514624909369e0138755165dd2af5a791da63c0604b68ff160fad82a578a06e76f62bb7e951b81d8fde2dade6c3a314eec5913151c16a93a5abd5ceb59ad96197a349721ab123b42f799dbde36d7965e0e5dfcf43d8d1ae13f4a00afd8dde36137d3de87f4e2c0366c18f4b3a449ffd9afc7c742c50456f6e642f7d09e86d5aef224b20ce5d8a2bf164484df8fc87daf69e459fc78c6b974cdb8fb1dccbd5290f560e3114302886e2828ad73ce71b06186254206743076c6af0c3d1facc36695dc28db1d026686b141247e1c7a9323d544b0079023cd2adedc0479ceefc8e0c34782603d0c27d18768eb5485a85bc385ffdfd25f735688a3b9a0c6f532b2a7989c751804de0163582293a17f635fdde14e9067f12929b079f89a53dfc87b986f89f718320ede83cf4086d0d095b24b66d5e3f1bfdb08b79cd5b25657cf2b20faff1d199c16bb7f631b33970b34c12997637447e4127db1bf580b339807637a86e0248cbcf8e1d30ae6fe053e2f9b7b3d0f9e3f4813af908b633560779012f9e06af00e252bb0df9f0caf7d1e82f8deb2ede21d13f406dd9ea69445d50844c95c921d8d1cbc8afbc5ddcd4157e65cbfbbafe2670e9146a5643db049a8d696f0eae07c3d4099447ef78bdb90fc05d7cc97bf9b9dee8719464ec6b9e6de866f73914a80396dea3900a9f7b43a47e648e20a9504da92c47ac65368813e5453e82020f8861aba2534346e6137e71adb28a5ff080365d6ea26dfc30ef5500d0760749d6e4e0f93aaebed544832308b19f72e92ebb8eaec2492c6ea7972fd359a8b67a1f4053bfb1a3c6fb720b5925a7a827e59b3bd0651b8014c77b25d61db17eb169cc2fa2442c82f68fb42200c59baa468a9fc92f13273ff071124f8b31e2b4b2517ee622d29489997ecb5676fb52e3002371c01004c214757b1f510091c2377a08d058209d18feb9b524a41712b6df4b92f2b14c583d3196749f367b3bbc8ab5e9e2615c511f23ba5fb1bac2ee9436dd8d162bd96f1fb663d2b520ba7e8ddfc2a4d549b63714654cfbb37ee1dca5f723139187ada8f8d5b42ad09ff196b70720d2527b4466d44f33cce486ef2e86311c75ead31a17b16989dc63bacf0d465379d9138df7ea2ebc71f4cc3b6662e24895050e2553dbc160a567d6722964a904d43bf2684206cee3562256e98addf3038e968cf6c09c921e2c89c9c249f6ba7afd20dd27587b4143f704f2738315a91c2d40c467111b4f3bae4f77bae402145e742ba83a527aeffca13ee2290988df882feaf5a3c24b416d59e06cf4f8832a016ce55419b7bd2028545557528a0af23f17942433e13fad089fdb79449bd9d99b0324b1828791249b6789a09cdfb6ec40c0fbaf8b28ea4f72d3df5159bea7a7965b94beb1bb01d87d76ae7ce47fc333fc152038ab4e7ca64a802f96f2e92bcc53ad9cae0242c622c99b2daf005e554cd6ba127991d84841ffe3ba0674eb7930509045dd00ab91a7c6acd2f4a40e7ffc9959929851e40d417f488a29f7bb5af3847a8caa5daa0682aea870ac8b866ccfdc435971e3d862c2f651cc6eb8a33fca313a56ab8228ee9ac7dce14ea3c3fba4f58c70888ae558d8cd632a2723ba54a3d538f4e20936a2ee543e9b2141e06095c72d4ee19908febf7c248c03a78655420da644746e2d508c31ceb0b648800d95dceec72f7576502046e5dce54b5a097f625001bfc92d6e4633b293cdfa63b1fca5de9e26d03ba2f1cf3647dbdad5359ed76bf702f0621c057dea3617af678016aa13360ebb02c6cb2fa0d3f137a1a3c639c989e12383841ab7ca5a84f84c08af4b85416ce7ec3ed91636a79add207bedf9dfb2ff626387f20cb3315502b2b06f361cbf6a51fb507598af41c5a5b9cd95ba1894ca372c5e1851e62a0d3d78dab6f92bd43ba6fcd71230b6cfd843d89268872b75e3c5b471db530b7ab5451dbe63fa0bdaa7d74907cb376643e129febbe6ce10b5dffbf323dc973f097d2081e06aad65e674c5a41bb81b80556fd78691fe6b5bfad47fd1b64db577f27f22f17973cbff3a7c4aa43569bbe6843d773a2f933f472650e88e0ec6643f87dfd37e7fba915c7386a130b8d4f0ff4d0e99a633d1f863f3e8ce4e1ac5e31438d89c3b6d5ace3aa6e14e7073164ea01e853958bece389316023127f9916297a47c5d6ab5513bab874c1ae3bf2850cfab9018cbf50a7febe03ff3e8e4e55ae5632812b6a147edf051b461bfe56f01a6ab571e0553e37a57a3a9811f4fda2e189d79b74215d6fe199595d18c6543c747572f8cdc61a53ce09d9ca96b43a5af5b56b53148dd4fdfc1e22c9958caa783f2d112d8d5fd39e6955df75d35c59a1967fc0d8d3293e39a6cdf82d6846b39a74b1a538372c266b3f12d7ccf464ff7e32fe54342994f51d344302b3b2e11eed2187a741eec99ef0a79a19a854c03d8bd3fcd557b9d8bfb35f0976da327fc7e8d95fb43db8e66be5b373385fc1b68099566c7e88aefe92c7c521d084c15c8d403d87bbc975e8d687e2a51e5ce53191e3db5bdc50f475853cda7cc5a7365c41035aecb61444c2a48492a600b58300b2805be97b4e9e30526e9e62bb3248a17c3809219307ca85351495c943a865359c783cf615a809c739cce0786c6045d9c8071797001434cbae571d42cef415e28ed6adab09ed10e0713dc1412ed80b8d26d549964321559137483c81b19203080b36abcd68e841f4c78b5302da79fd6e555f390322ae67e54c55749491889d79eb2982fc4428086bd1060c4113137ddb4dd7c9b690b802e805999d4f5127f66f6b1d397dc3509504e2196513b5787407b45b928cfc3c437523daa4f876dfe061e351cb3bad99ea205ab276c4f2a5ccee1027104f09adaf55cd282d4e9e44ac2b65f7e423da1cebb0ac70691347e7a7bd0de8bc9fb2e7a08afc0075a0e85902316cd6ec9a5802c51a6d65bf3251ae712ae0f66de6cba1e51efbad53ad7e769f851799caf5fb81ef35b4da814915dcfa67553f1c67158154707d16804be27af2115559e4758b313b9da4a1131718b29a75970b3f0a5e2f2c11a0a1ed47f238c145dc4fe9e8e963d8395c67dfa94a232b8133a0d953b05455f79e0bdff0bc3de9c04d93d97084ab99229622cfe3958ac5fda6757de1696b575f6250b441e6368386751b1d2f6007d254d152fe76578fbbe164af49cda805b9325f7ea47f5e18f3de1ce38006ae1bf027d3e354d6f923d8bc6286aaf9b9a7b9e7a7fbd36a31db0d88166dc68e7eb567d8164bed1e279a8810fc21656621ff7cb42a21ee04e6086924bb62dddd16c3343db69250f7ed95aba953202640bef18dfb6c00f1ee03c670a5cc6c0f3cd7cb006590dddffa6f19d450860e289f85edb4fb0dbbd2f992eebba09cddc1b20a3c98d8739ad1875a514b09b1f23cf406c4c55cc4266e0b8b283fa445849316c30bd19254e9d035756d2773cab7f5fd56d6d3a094a717ccca43251201cfddf80ba1aa0dad34f5a3acf8476b784fd53a1aff1307a7838705112650bd25dfea21b991d801f018a5dae26edb9dd5a0ab940a94b7bbb90fd1f30f9d1dd2ea3aad6d0a2a3c42fd2641233c7d624314c3a54ce616d2ca5683d04f6fc0924f0b667be32f4de8820f9cfab963a287a1c708857ebabed9b5bcc35d539ef9bc170636cd528ba86a620195134cacbc2b8e742376124b67ed8155ab53979e281f97b184c60355b008f15f45c8b7a506b1c1f511e4aaf0bc32fee27b656b01ed6afaa4053ed674a60175b6c89a77d42963111d0940730db02ff67534fe6a296e0e01e2db6b3f0fe9648286a0f3420cd4393163662751deed6457abbb370f83ed92e9da86a0181df13b8ef33e5718ce524a700ba5f2b40f3f973a67c1c412dc251c19e6b7ceb279dc1dfc36a3567e3a98a9d96ef52b0d0734f57bd9edebedd925167f230b1c81ca938e94ceebe43d2573735873a436331a8b76c1169c6a869889cb74e5d33721bbb99ec87f160c025f570f1d11c2e3ae6a52580785d854790139510179b003418dbcee1f4fd4fa39fc134521ffd7f29cee650472638dd04d8331ee439eaa32c57b56c4fd9c9ba87516a8236dc99b8d6e4c2a48e53a6779d5e13bbd73cc7917f0cfb8e231218bf33bc3c213599eb76476558f0e38a3979cdaad6ac6b03bd0ef0aefec634fbe0e1e87bd78123a19b7352326b9def856ecfc02b06622f94e8cb2a1cb6cf10d020f789a7db775063030f15b463f08878219636f2bb94ed11a3ed9689d797a3253809c7f2e0c60672e8476a9e272075c7f808258901e611c4d535a11bfe01daccaec3a26a187ab45a9fd0bb9a7ecf2e9c4aa3177ddaca1449f19f78ebe26be2e25bca012a10649b56899339f5418925648f3253bd716336dcf65e6b4f16d2ae51fed1acbc8335c103f721f46023cc2043f568ddb033aa5f2157e52b89eed4571cb523fcc66ef5cddc90679633c2a46f45f1a86c975db4f6f37f9fcfe54809ccf75305bc9f242f26f30a0ad5f3cd71cbd31ac45ceed2dc8571142a09b7d3091a4838727b9a067927e17b7559076649b405dfd480627881489d52339d4a8943ca396e92b92066e45d525acf7785a944345d25d721d6a354b1a9f3e2afd379d1c341badd0dd913a3471a5b78a81c0b338a2984e115d003b1deec1b44fd19824279d742017248fb4434cf47ad07fc87df86e634b2d8f6e0aa572088678b9a9f767404f06c84ea8cbf65d46effbde7de1f090d3d4b9e7c7c3b2b1dfa9e591efe12ffe0fc82c9eeb7fcd9f25fe438b39c46614438d0be7e1dad11bce8b91396f867531e8c45d8c01119abc2b20be253779b5e651bd80536854e2aabccddc5f4fbfb3497111fe9a8f8a417ab4dd806745c82126524ec325c931ac1f31a3cea19e159e1dbfbfcff761cccabefad38062872fe8a45a14781ba12551befb31c21150a56ccacf9815d8f458b1f591c71ba7b0459e7c09a4eac5c9e5b2984314ecd2f7054ed055ba082204f7ed62b1d513cd0992bc10c28bc745e30b27f6ca28ac84dec6cf0ef73c971ce12b2ddcc0d6264d8f7dfbba0a20f8ff1d7387cd9d9872f4b345b409950d66ababa9852f7f5ee634dad6085666956b97e4c9142dbdce96bf42d1334c61d04ffed5ac8f12a5075ac87a7416fd52579a876c89e22008759a93ebc57279215e178662a064bca65670089ec688532468c07161f56bbafbfa5655768123e713c7aff52852978e9d6004ab3a434d9b5c73f0d90dd1fe742a169a84f0e96a189bfc5265d8c5e2d9e42f5503d04ce01f9a912bf8b9bd8c282a4d40bbeca55d14971d1d305a16eb85d02b4edd8d35baea56156ba12f4e344dc4cb34509fc780ee97d24173a75e49960ec32055710bf8119d005447c6c391365737a0cff68d9f44868b97b2357dc051ed7fcf590b32292624545935e87f25e56b3e4a2b9c39c4936b5be9030b4711f246623264e0370291b675e75e1ce9cb425e5fabcfb55e25f084ea8a1b84870135ad997f7b700876691939cf268204669790a10ddd3d38cd22252226a09fddd395482deb561ee834ba452750d5b8e0de63c77c85a7446dd5bb29df2620f98e07bdac4cb59af8b9dc64d427dab780257e252e8d6793fd1b99f7c3162b4233a418526ab227d40b9deadc943d0f108a38d7a6b075465a44c920c0146338504eadf826cae345e864452e94706c8dceac5cca87469f2183a9c918295c09eef65f747b7a3d7fb3d259c4f531ffe48a5c338717ceb45efb557a47a593fac85cfaa4c263c109d385c01a3193a6ad1be5923d6a53e6c369a2b5e704cd6ac3ac255954c3fca1079895c596596873c1309fdcc5f36fe039d06806dd16cb00bd028edd6b44fb1e9ce4a020362824bef6a59502cce4e1d3d3884d7d865823deb092916a215ee73bdae1d4baf7f294caac7f63a36c2a15a40517438b8cecb93a5da3e11c25ff228ef3e7281360a2ce3ac66e69a2f136a83fbdbc44dd1737e9a31bdce16df9e118345ec1d9a9c47bfa60502722c9813d31c9f1b0364e2e25d77a0816db52f7e86bade9aff644df50b1cea9a339e76e869fa1fa50101f8182a2a6aee2e90d242d4b4d6b999d1c358a8d9297b6e0e2ec141c2b3692d70b141a213d477e87c52a2c87a5c6d1f0fb091f35f50915878ac70000000000000000000000000000000009111b212a32363b"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-1.json b/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-1.json
|
||
new file mode 100755
|
||
index 000000000..414ca8087
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-1.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "short-signature-ml-dsa-1",
|
||
+ "expect": "INVALID (length)",
|
||
+ "alg": 1,
|
||
+ "raw": "0x50f90ec4826d6180843b9aca0084773594008302d5709400000000000000000000000000000000000000010180c001b90520372c0f4874450fb92ace74d41bc0326c7f739589f9b86a97afa87ef65d5939e608c81a44909e41f41931349f744b7aedff8d5270b91c4a2f61192e2bb6e3e6d12231deab235359e78ccada386becb6a6a1105afc0999243ab8b363f7cd2c19b2b741c9969dcf20252f20d130dc05d9244f58d6de9b4fb4b6f0125c43b60ebe3c7272b6ae7578f1abb4bb5e2dcb31eebf4aa7089aa2bf40a0ba5eb73aaa90e45472168738cb0e866547e079075d0341c4728ed794cd449d0cdeceaf64d09173a2677e3f2621b56014df58ee8de2bbcf8cb2bf369e57a28e40b24df6d0b15d3417b7b7fce3c49230b3bb7c7080c4f1344380db37299d8c0c29a7c9e95bfc4f3ec70b767895be6ad798449f94c92f320696f8f9ec844fc9451f5ab30874e6c78673b932e24a918d5bc03f4fa647c8679631ad8b30ba4f9a1a790a535104f5079f781fa4c4aad807777327e08bd6e14b957e527650d39e2de7d30da7b2b27457d3539c2f99903054bd1a6d6301b2f83249db80dedc911059b047b5552407ed32b79b57ea4968198decf978fed532277fb189841d0c17f261f1a7c4618c33b258a71cb6b2b921c48735c1fbc375a80fe2d702e9f70db34547147f6d65153f1c508ff90aaf57dfde59ce6e56c5c52049b10fbc2640cd937bf5027d755444cd5e84aad66be4ccf04f710f0b970cbe7fc5e4e7a44f5d8fc2af94ec6df87862dabe0d85dd17e43728800d5dc8ff9e9e1fd349b9d6431f264836a447646a1ee2d73e6a4d1803d71b98510d94d53b5d07764400f413b7837f463e273980296ad5e78a62c83fb91354c25c2e28bfa19480ca41b0ca2d8beed456029eabc0ba69cf3504cf1207ab21bed0e3a60795f5b066019132212a9bd20e98b43bb32484454b7693bc63764d0ba8768da4336ad16a979b1d3e8b06e89afc4caafaddead83ad861a4596814062468d8cb2e131e71cf38c4e335bb3d1d9629251fd50a4273999a20e11d9a881fa2465c2ef32301fa8805ccb38b4656e3c815b54ef42f292d05847c0e5149b0a2ffd1719fcad10730b763406e9e453d2e4a556c397a984a7d8622466522e79f715f980279cb2d1d74d5fd15f8beb8df9c0a1fb93f0d5494ab701cd60cf2b613b484a191d873449c4815f44eebb62658ef90f7033a5e48d40c8f4ec9a25d4f1b73a150e5b03a4feec9142362e77d74d364bb8a40f9873efa2d9f458d84277fdb0063642d9ebc794356368a0b4e53f6ab0d9acf4418fa42d05c11db12cb67d6c4cbbfde4d85358abaf8042510db53c1540fcb40045b334bc54a17608e82433d1e9e53c99769b86b69b8cf1914584cdef479061718a2cc5bec5c31272e0463139721c0c3523a6ea31832b5c15aa59819304c217fbc51a2636bfff331e6dc1037e89be15c17d6708762976329353612f312b828e525c09b81afafa5ae5c25d82b70b6e55f892429a93e5eb4048ade675583e828da988f9d253123a06c0ed047adf4d93d20cc6c865f5a761fec27811305165cd4bda05f563215d0612944b88ade9d64477ae8fb441978720e70b0d77e2edafd3a2c571cd28a42cca2f289d157cec813c24e7f56051b4f28c153adfbb2c1ff90ea1fbc03cb89603387169072442f5d3081140e2256ebadcd775d2f1da92c15a9ff1ce6e980b3b1e91a7e379081ed46a4259fada21536af318eb2043ea16cece60b73acd415d239389cad9212e15bad1b1ae38f93c756635a9b87417faa844e4f43bae1f1ae68641a04f0ff1d55f9045cf7e3ed59fde5c07219b9113329356d4300885ee19c9955c5757db33c6ae75b49d035003171d02ccbd7321d6a14db0bd011d4877f04070dbda3b67bf22d083eb90973664be581b59cd495740a8a9aaaf7c6801a8bcedb531ace47da1be56ab30f1c4ccdaad6e81aa97352baca12b6c69754123bdee38c0d57bf15f0850572dc9b456234eaf37eb478f9117f952ae95a0d165d12d948b51672a03c9610a98cf332d6ad7ab8a87defb3ef7249cf8c3a815129ecf5600500702b7916ffe570cef0714e0c083a581c2971c45c4aa6b1c5226400e5fd594ea3ae97fe94a0dc7f1e0979b11a2f3d15ad54fea957992ada816f97cd76168a53ebffae36e5787b0f69e94b3e08eadefe4937ce8b383b5022e57ba7135cccd5b48e38916f1f0bdcbc5858bf93cad75195d4329ab41a518d820262b1b610f7bdbe1d6749d006a0dfe18d0be1a19fb3d8e37795b5bc37ebcd884f91459164cd2536b3496c4b25a4c74282ece5d64ab861184e942cf97f0edbe6e1293c4504d861e60d98c4f6523df27a1e80843005ad21665b3adcf46f349fb0d905d70631d2ee51c0086b252778eac27346eee65c0fc88c6db5936337b0afa7d8cec656612c81e11cc55abf421df770e6c2588c743d5540e1280be76309defaffde2b82c808976c337ee13735a21900a4686423625a0ba4819581edbe574e6d7053c5fd98d288db4104ea64fbc0e7ad11d50eb1470a882aa00ebfd983cdda14db34f7f968ccc93097cf037dceeb1375f2df4de09c8785f5fef8fbbe284566e5c9a2d38f5d2f9145b7f5087f6a89a56679680ca4180ad7da3ee45da685f0255a45db806e1379c1ed59bfe63feb7d74a239334c80ab9c1859d205ba798810adf8afc569170f94167439d137215d2ce0b2fa983ac138a3ce201cec4927c62b740912e7287417f86beb07af9c83fff843df1abd6e6f81865b82b3168528d1c473b4999b0179f1de8ae22e8ed7f698ee8463eb93fcfd4e017f29ab3f15a2e061de6deb09459d4ecc62741ffd8514d5c1f10eb3b1525ad60512ffad00e360e0d6add8ed6d6df48d63cf1e36f306bd76b1a245cdd09951727367e45b3a02d748dbfcbeea342be4cb0e1e3108e57993581409f8c6b34e2d38becfcf15c653b92c88412c087eddb0bc21eeb620317f49a9bf5d6164418a26322e1964fd676a547862c2a7ce5f13898e3fadec79a638f257532cfe977fe8ba5e96782f9e1e3e8b5f896a80d816141f0c988ea59ea321cffd23f298b76e49e92189e7f65718d14091daeb82d432470a2e472a39a154226a43c543db2bb933adad08344259ba08a65c543d2ee07b67328ca2d4e60e550b85215ea5873fedb505cc1e4db49e129249fb632ba22f11b897b9423d08f96ceaa863cd29dc16af6ac76c4388c2795250c04377277626992b085ed7be2cf1d63a2eda4b65e287081fdc4e9a3224ff57d81b3ba8d04eb88430a01c5eba35fad028e8de1812920cee2576d0bd291407c5fb70c5ce07104b9af7b98c4c709c7f019d4a66b136120b92612ad5e73dfcfc1da0fec3a7928e57d7d4769eecbaa4c269f2859d31d47d1ae40e4da5bfa6592074c5bf54b04c707b8d97455a0a606686e06bf5ef7617da2532f305267f61c5f627216b06ecc3da6c6f7b420e2dfecaa41657eab20c89927ad6eb5c4fcd513da89a637755f4a98c45cfa108f37415bbf49ee6cacfda8f22f7101a9798d844709a38f9168685f105157a937bb10d4f5b342deab8b8be8231490da52cc0c407bf942270ad93d4a9bed5c06499584835dbba75577dbbc47fd3d397f0417ade99549de4412c8893cf3e1a2ed74c234a7b60461efad57d9c9fed9eec3ebd652282b045174e19355d8cfcc10add9192ffffd428150dc3f48e0417e47d6407008c62486cd4057535a5a9ffc45ef559a51fbbece64306f64da9740108d0b51d01423379bb0a72fe050d2abf5f5acd25cff57f8e3bcdf938749c7bbf77437424ada88c167bcb6addc309b949a8e200b9a5b6797522635731b250e2405f98d054aaff4179ccb4b24159e4c033329100cadbef3da262203622d27899166f6c3c79a35daf7840853b9a3ce494bf035235cada8c31e28be56f0976ef9b96f15de57e6896a5aed57a7b5ce77cacd1c806ecf83566bee5d577f7414a106ce16ca6e8cbc144f571b1a37647041694a6409f68d15604960417a60bc4f1a878eb01e89159e701bb8fd96be45395a8b8c4f0cc5b982582741c4ccaff8961ea892f084b10646c7a27687a2d3c92324cc3a19a5b38ca2d5c573167ad54486ab3adfe9219882f947cc6a93a3827f4b51d76e90ffd1587646d921482022db8b5a22519be3a1e62e9a13ff9926e75c42e07aa295c8486df69dc96168e920e13c85eeda86dc560b9f5d4c77cb8ff001d390dc6c5a911c573ab1711df534930ef28832936c80cafcde731e999ce90741e669d93f653efba12466726fa997e7ad24d34395a02b8a4286f3604f120bf47e8ec41954e6def2de896be477ef7916f18214d28f58ae91ed8d7eae9e2df600d313b6cdb952195e9d030e0b8fc98a68cced3070f4abd2d252727320eb54b602ec861ba630ed3c5d6fc8c8b39f4f1e9c198a6dc8d5f825159ce15fcd7bea5701a225ac41bb152d1a077adc03ecf06870375f2d2618094a648b40244e4a981e7efeadc608c082dc1824c4ffdbc39afcc8c464ed5ca8dfc1540ae3a6c034364c356bf13f880abe8633fa041db78f4be0d17a4bb00959a697935c844c6ddc02222f7aebb1af2c96a757536159dc1dbc31131aefe4c198ccd2123eb5d0ca6147bbc9ab43e993508ef4ca383e2847d9fcb4c975dcb240bcfd164daa835311cf7dbde0f256deb5f3748b55c312a29a042725ecf07caa904513e71b4c0ebd3b31c2938e710e7c6be819bb3125e638ee4b54b4c8fe16df1cee7587e6bdfdcccf2e3b2aa4a54c86b0ae711f056c229c644f519f60570aed60fd3d0638dc341625fb4949d355e7d84cb478133d25730162623acbf5d36b9ed98dbd88b6bf7bf1f55006f5ba2d16297557f966cc01baca56e3f6435b724c0b6fa4cc0074efb0bb2cf0cba9a1c73d3337db7dc0c78b87746db7bbe5fc003edf608ce5d91dbd8b3cec0f738de14c8e2b6df47df91805eab5635402ff26245430641abd9511cffa6bf8d352a1f0d97ce2b08561c97a5f07a07e0ac42a2a73366442e0bf125a718553794b021640ef9f9f07040068cce2337606af46f897b7ad8ced05e14f7ab3e2bd847f810058d665a0c3b6903efd8f398c31e356b48216111d30348acf93d28dbec8e603cd16ea5d3b24f38367c52f5629fd51bec34e86ff21d4f5466a53aea7048babf3afaecec2c9de099bcb2845f66689e02306760ef5274e65f36fc61edf8112b3b414a878b8dbdc2ced0d7dae0e95c5d6e7c80a3b4cbccfe13293e454b6c757a8d9496999fb0c4d4dfe5e7f3f40e11172324323556687e95a4a6bfc4dadbec000000000000000000000000000000101a2f"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-2.json b/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-2.json
|
||
new file mode 100755
|
||
index 000000000..27b867d52
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-2.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "short-signature-ml-dsa-2",
|
||
+ "expect": "INVALID (length)",
|
||
+ "alg": 2,
|
||
+ "raw": "0x50f914bd826d6180843b9aca008477359400830383209400000000000000000000000000000000000000010180c002b907a05424000ae9a496294dd6b99046cfdbb235ae71031b379ce274c13b0c96411740cb61021a5390fbe8fb56b642b4e5e5abb7aeab143e0037f8db283b9f2febd650265ed6b05f1b867c124aef245c1811422f92414447fd0b20844e0f1b1cb4eec052400aad52b9d773aae0015c0c390bfdde3d367bd8ef9c3c73bca3164b9d418ecbb2d25303bbd12739a858c5fac4cbfa0203b9f3c319e9bc89d17a7a244b57d6613b5caabdb528f077eff9727015b9c266d777c0ba11920118c7ec4dd59b380c40e361a5b23ce04be4c61e12a1c21e091fa0d890687cbf588944db3e34253c75cdf797378de79162e0b4ca309f550365a289f652dd6d559478912cff70a5417589f73f14640970694d7b5a6bd8f000a65c632f0326ed3d128fda96dbea68cb812634dd75e9f63813a5645336681378b6a63220c066550aba43a5b937131d41f08752d13949a115a74bf96fa1925ff4338e10df0301abe40aaa49e14a1a1d58eef005a0f1d0299267002cebeda20cadcea7419cd0c365c53aede1aa36efaf764d3d36169747cdc8ee9a09e0a0ac6bcaeaeded0cd303c965d705d1b91a8b35f408ad8a033b02ff57610bddbfa60e2114e53f20f8fcad15dffac6a494c3f4f631590f2be3422af14cba7c900c9c38796952e20c3069bea2ab54bf0edf9315903aa5cf68549f878eafcc77561b36f8b78d950871ed4914417316f868a2bc54c72d3c9929f0138a2f0cbccb7c4141e94bb8a7ae11f660861cbbe498697d7327709271460a75bd4e024de3d4d6fe5af066944c96ba87459fa948a95eeb61abbaf643190ccaa9cd18591eb6f249a6eb92db89fc95616d21b41d7d15424b80a750938a12cd57d50ef95aaf222025dc4d81df320d9bc32c608b1c5a1aac8bd14c0f7a4c4380cdd65c793a6287050ff4d609102fd91e47e7365fb55513aeca273618528c199f7bb151e9c11a0bf202147734d1be9d5d0e9318096fa567317ed9fa6a8efe201b915b9aa05ca0d19e15c9a80449cc130b398ebbac3d938f55eea8f74e024b0e33dfecdbea02b920ddc5b277146685916194bfa1f8ac7784c7ed76923d4ff9ed97d3ceac283f9b26977df0133c5fa4fb5fcec577bc152e926529f06ff50c204c083c0b4d6b8d474cf5cf7cfcf7acf76921225443eb0abf5e4c76d0a3f524243ee4e372e80ff0f76dd9d135f240114a2ebe6d69609b6c60d275f251d7dceadc600d18e0cf8bc8fa8392e61fa32b8f7481c4883e19d820b51af0f87d3f7faae44e3b908fc759c6de59361487d8e424ffbd662d57a68801110e9cb099214143253949cc479eaae0e321fecab90c63b06819ce3cf56fc2fc1419408075c658024a28950aa47d549bcdb8b5bc9aeab463466c7834ca7d73058c206a95a023f0c8ac95badd383e63041e1f0ef69f51634f5ce2f48d80f8f2e92f4a1fb5322930141fc50e1e20bd235a8b8d768d473b46711257d028e710f82f0b6bd923da05ca64ae805f708577e125b3fca2feb5656f61ded034eaae481a195628801c82db85345f9ffdc72c860cffe2264ba4be2a08fdb37a4f5f80276baba4ea637847335c89dbd35504389f68b2d61ea66d4eac5fd0057d9e757d929214a7d83daf2fc2b3f840e083792d20d772584b252ba955ae8ae8c36af648c59ae0b25d3bca19413fbd749077b6969db5847409d13e4a67387e59116fe3836a733f3253d47f9919f49618fac8edf5fd711a4239447655d6c40f479f86ef3c9d4dc1a6f9683a3f1bc5c9730025e76ea1588d43494f59823f42c207e34412f73c7e2a126501b8fb810f12995c213063d909a5a9c2653d3511ceb809efa69c638f4c977d46a2a305cc831ecc0feebf5d9356ede6c780da78fe2ad683b3312282d5142612c0d1f85108de04de5c3d5414b62826d5b75f8887dc2d932c40f306c08e5d4f69ef4d344fe4317552df9890d0961e3d857bd9b2c5b44536d8606f62f66d14ddd43b0e5d3379cf66d664616df12b1c62385a57f6a562c34e120b79d64ca39d8b23e1e07b2c03910d711f09df5b54cb0e133dd751bea7832fdb38de2f1dafae69fbdf82b6887ff0a92940299020a835b958bb01b25b8699a0846614cb256a6621ef92e4a0947df9141ed4f91eca527aef25862158a8fa712dd60dda947f6a16e077810e29542a56f9244c34a73454b9ad0d8e8c40bd503efe12c4e5bf7d0ff8e6ab642a039f4e8b575d33c0c3de77a1abfa60b0252d7a549dd791d9630c8b848988157608448d77938bfb27beaea8f9b4a259263797c5b2fbdc7f469b2769f7dcb7b9478cdf5f109322eb2f0a83163469b72d8121fe8e01df227563cbd941a1f63961e2a010c6322a812a014279583a0066492a17d1a15c07024f6b8b1561041b3db608ec1c7475ce4d086e60523e85d7a955841558a35535d6e52cb166669a69049646b94d2fdb901ffbb1446a2d7f58696bce000ccbbb6942b0ad6480d006602c228218d3a2f0bc6a5d5c73acda9fc4b0b496a7d527050f8d77b71641f030368e9494bfe8e9dbf6dd4040426da1b0423739b40450273f4a8d551637e5fe3ca8d54fc476e6278e75cebf4a4ac3ac8ef3807041c4b274568797c8caaffae7df08c6c158d92411db981ea02cc212064c3ad6a9cd1cc02087acce5ceb8d7cddaec429d199c3d90670288be6e88e6826d1f6c417df5f35139c71a62c0267adfce7cb3aa49e827165b28c8cc157a691cb52ef103d8d7ca0ebfc628904d0b2d365dd3401b620d6d93cef670e2fb90cec33fc1486a0e70aeb6fef62ce5a0dfb51fcec12164e4024b0c49ce8b65e01356d80a9571af8f69a9c7256ed549d699a31ceff21c13c482ee0c5759f96125b0099495feacf22a001b2c887b107a9ca9e84de461fbc6e143566de56c710156de5b5f4b7ffe29c0124c1fbb6a792110284c9ad713d89bbb5ed444d09408c65a9f74c5f6c4fd281d31738db82913dcd1ac1fccbba24dc933fb9a8e6c4e426fb98590d7da0252c34d866c114526ded1c9d96daea12ecbd8f2a44531dfb72f02c02b267edf0560b1fb06b087bb6ce02b2922d92f81bb7da99b90e4a2dd68aa858759584490be602369dd606a510b6228e3b941421a3006a697b79866cae011d8aa496de4f3bfffdc0a087d01323db849f6237d7ac476d18bb417f26a697388b4c0a78533f3dd763398719c9ee5bf0299786fb8c4143af8c1195103390d4494b735c06b5815c454dba2fcdd27d214c48712609ffe7ad7c082e835d7477de2358fb3c4b5162027f816ca85aa4a46c25105175e77c8e5394db6fb3999c25ce578f066329182b28fd5b68769cb07ebc67e47a537f6cb62bfd18af162113a4df7f8908e0ce953b6a9637c850f24de0fda239c25fe4352f3b381fc270384d51d1af1ef0dea8501f98ea71f26de97e98799c4b2a316a216bd4af4861ad83fa4570532029564581bb35ac543355ba3aa246b59c6a5d9a91b938f3c4f0ad6d6f567fffdb6fb78402ded5fdc544a0f5fd87e4677326ca003dffdba8fd390487a6469991506a18f376b12db5be3bdcf4a4bc2f5b34dd8f7066bec3b40a6502f414eac3cd1ed43431b033757e86cca57691b0e1f7eec68fad9423f8b0620aa94798546bc878cf29d74ae74af5244ed9b97107fb83abe25dc160ec05cda1c50b76db981aca781868a7913a3e7c98aa5a3ea8bc81270e6f565138dba33c9c7e887641fd3dafd458b9c64600151038db05725a976950307c662c2eb668e3067f943b9bfd805307729b39ed77309fd5e67ecfc56cc231057a6628fb6f528fb969378529dea2c58fa0b4d791ca591ced733e8cf93a8e19907538f45c2618612648d3e1a78492afc154b7bb0285aea97d618e74a74530b492c66c6bd31557cdc55476b3f163196ec8e87f110834ffb8c232dc77cbf2f7b490f520b3b328af44fecca860a19bee9af6a5f69f63487d7dc6b7bf1233c4735522fedd475f905f044a0a7f658a7a378958cca56a163a343a010f4b65d1bc38cd57d08e0f887293fbc106ad7b15aacca6d51558cb8478b119acde04a19b007802a8e9578121304622aee7858d1794ade88973d6fdf981ebabc98fc417d765c075bf8f76b9781dff7c60071878027c057aade8eaf820186035499e9e5fbf8791e6fc0a0e49047af312a8b1b1e80628dc4db4f45842e19096a54733d28028203aa668bd8655631a01c000c956c32ff10572fdbc95b2f26d09fca84c093ddaa122ad93598c03de9273873ece5096648a6251a27e993ec7b6ea4f2181c09bb06852799323f3e993a4b7461439f702cb9df183fcaab11b8bd2ad391924d5e6ef261fea01c91cdc10d9345c290dfc3c040318d11419563d407c8365fef3dd31d8f9d7d338f5f2cd00433d1d06547ae9c650d14d9a7e5b683f0458e7a909d90d4a57201ca5b8753c13bda3591f9cadffd0987d1c7fca1c5a0cec1e13c612d0390d7c0e2f422c97cda29959cd7b714fbeaa5da7b0bcf911c2744a9a25c7d49e93342f61e10a33fda80fadfed2668bfab8767ce80480093b4845cd5ec83082e8f9ad63236743e72842d1a3226640a549c2c1d002a176e2427b2ae612dc272e3d9fa80a904eb8f93f494a52706346c08b06c9d1d8a61a9c7112c0933910882f0da6eea3c389f4faeea51c03394eab4cc02056d704b8839afd76f0839be5ffdc873b88f9a755be6f0229b0843839a25d63c18da89be1c5da930a101913ffba01fd00f2a447d5f58ae8f21554feb47f42d40c32158219dbbb1e5e96ab3dc26cd6a435525c265b65b0bf48d68e9b3c9178a509833aa47c23e63aa9a6f74bef1e4ef863556b11c014b85ac7c157f1e64531b676eb28c68e82e0089d2bd798213c836cc354d4883dc0b607456ab7f894f0a1f73356fc05a5c97a9cf3b231890c39105b751f6fc54063a08f3d3a264ab90cb7de1d0e2f6acb92302cc9b4bb512e720e6ff8343004028ad223a70d395c5f974d3ddd380f798e80edb4b13555c3be0cb1a500e19a8b1b05f9cae85d7eed756ebcfa57828f1054296ffa48d426ceb83c69ebe1b983421f42316ca6f50bf8df0f4d4aeef85005638a304d88764ec26366a1437867c89800aee55ba428e0c07542e123d748c795560153007f768b20bb057fc2643b7db992c3b9cbfd88657b17fbe8a783da2050affb518cab4226cdf28fa97f48651bd142932835f061f8642e79d1f7ae8ff8665aa85aba24a850b2042dd37e61e665a451f17cbe9d57ed5ecb1dce9ec34c576762929dbf46964de7c44c9f6b10fcf52b48649ded2d491bbe4bb6ad578cd31cbdea6df8342dbb7f33857617250b014fc6d887a448f7a5cef25ff69dbc94733bfac1d5f8593af7fbe4759d23ba8da1f405ba179c96d8ae49eb760446d842f0d61ab08508a3e31e4953e13a1b197d00644303e8a9513199583709f41757740a0dff347c3859d3a4ec391481af349019f75ccfdba111a4c338fd8283733115ce7c114111abb157c1a5a84f7b39779a54f000827a250bff00dbe9cb7162d81f6c942b719f9eb973ac7d4652b911622396c517c6e9c7e5f839c049855567fb53ae84579388e3c87af420272558c686209fd92fc339a553f873995932d9dce52f5e60cc0889c3283f94a0d2d5d011154d9935e1dfbb7e747b393bdd8a84f601adca56d4ac5e8e6f28100a7d5522de50dbf1bd7f5604fdfa660a58dc681b4b230abbc4f594a972a73456de1b7f48975cd03313a80074f5d6701db61860f33dfcc9f06e313e8881c385a50de28ced014daf702f01c45368419b73383008b9191293f59fa87a1ceb0cee64d486842ed7c289dca3b3f2e261df644de0f739079ba5ea195468f0693a995dae8e0f7e4611196824f329fc803bc3588d7d941d1fe86a3ecdb3eb8f6d4066ecee371f9a14e5bd46a40b53e87325bab7255099b4fe7f7b09eddaefc6582feecb8dec02b5e58d735a927d052e263027fa879fceb852b9e08db4636c7152f272a43ae4037c50210e90caa3e008fbfa98ed42cd425259096fc06644edab9b768779dcd892747f18a9cecc6aa31dc27d3f12a540447653edd5bed68f50da71b7992434b74d0209746f93ea429691fcb99da0ca32df822ec4332f7eb4bbe6d2111ac84a55932b3e173e388ab96a5a8a17c7d8b8131cf566e0335b0c4a37c5ae24e73c81146031295b69ce3032fa8e4c7616558179cc561f14864190d458cb82370749d595966047de698256126a4ca23a6bbd39201b8649fbcd387474ecf5b9f732e65938fe393a2a1269b06b9b49c5d8882d70776fc823da5842d812be2a65d2f5ee0d64f8258e761e6f2d4c1a825963b367d70b9e81b46fc25e4804fe9decf3aa0e47f1eba573a24f0e4f7b8cf8a886c7ef4175bd317709feeabe46df9719e7d7a4bc2c1bbc15a58b5332ea558e160f5d3b7aa84fe54ea7a24bd8e394ab794e72db7946780272556be33b7f32a0ee651c013d8ed3b5d75bc1c4826dc94f9e3711c53be3bcdf361329544f2993a189b6431a6dda8b81cb1b7c3a69ba96c1ac84a55100c4985cc85ce272e8eb5a57c563a7ad782664d561c3400e779317122d425c9c4193414bebd4d6ad31ba916448f65e9a7ca1f856dacf9d88b695410c8491a759d2c0304e8368b39cf502d0abf7233b1ba9671bc422ce182833ead52597481ea3ea26a2cc35e12a8c83bbb263202d5e9e7a5bb8ab2a5a844d596c24fdac423981fc4dc4291944ae476d59c9a31a05f79f0fe4b39f145c4fba857fa553a17fb2d5f941d5dac8dd3dd07e48eabfe5b98f3c41e7a84986dc3a7a3bb0ed2d4232cffbc50f167d58fb52fa3b357e76430d7f0f1aff6e2d51ea8f5b98bb66c5b5687821f33b9b6c2e407ad0e8140c4d5d4f1739167f8d63284caf4a43688473cd97bab401218fbb2ea13be81bbc05a81042a02eb1843bd46ca535e778e207c79ce3fe511a55d21bf20b24bcdfb43fa62b3469fae2ebd61e362d5d663fb2c08cbde5df9d8cc1faaf6370b5328ffccde873849299d61477a9fcf7c5c96fbc51b24c0f2cc6e39a46f4a9c1f5214f2cd06db62a37e2c6f477ceac0b92eb882d7bcd1fc3721a89745473eb45eee9a4fe6ab323d28f4db957d0c5dc1ed25ebc194f744a2cfe98474868e6acf5641ad454b3626ac2a27a9db416eb1763935eaa5612e43c49e8959ebcf5133863e98c19618e936f33952699fc224f41a4e259b40228047ed6a17cf4f3a42dc76df1346acb0986984f1692b5ed28f0825a23094ddbb8c1750e9035b1df2166f142e7f179473098ed73acb9ffb8be530542f31de88d6677f805cc30ccc0b60787e61f9d195ceacf07a35d979f9c3521f23671f378a6cd58ed2b0620ff7e2def5025f878d70008744c6a53caf325293353747c94c5ddf12e3a42686f97adc4db62b5e2e91132345963b7292fc9d13b484f75d8da000000000000000000000000000000000a13171d21"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-3.json b/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-3.json
|
||
new file mode 100755
|
||
index 000000000..25f29d47e
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/short-signature-ml-dsa-3.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "short-signature-ml-dsa-3",
|
||
+ "expect": "INVALID (length)",
|
||
+ "alg": 3,
|
||
+ "raw": "0x50f91c63826d6180843b9aca00847735940083045f289400000000000000000000000000000000000000010180c003b90a20fd3c43f5fc7807747a73e1d8e78cd9e611ad6bbba9b264534594174b49082aeab827927b335526cc50c2f0368fc666efb79c34af8ee90427d1718736acaad47f5959b9b26457619c07c2dda553d55a7498e30a37c92909f6b37c246dca4e8fd24d4cccd811396d276e5d11f1e8d14bb9eb4d5ec49798202422edd57ea4d8c0e8c6388e9c93a0ff2e52f7ca2303e40300c50c926a7da22919be462e2dcbdb3ec235b14290a282ee76a04f4bf7c5e2ec5c8fc0aaac72ce4f8fcf0d42b9fc3c4049ab6dfdfa12623d89c0d96434a8e13cb6f79ad6f4a8102f9a0bfe582d967372d8928ff9d7d7393b22ec1386ee91dd196eb9c349a6a12f7504e66a096eec0a8ae98e62275f6b84fb40a81a390c6ef0102c8fd2c11d303745b8fc49e638e6f3004961724a977a18d81efc67e37d0d44558e28cf9015dfa08eff82004c4a53dfa40c2451fa03a987f70c855dbee37e36480863044165e6d46d4c43278091317beab6f301d61c8f54f94ee88fa358c9aed6e55b80b4196e79a3d7251ede25c4baef8129882a69789df3a8262941199ded7bd381de00c257199c18e9086d9ce3f72c6d95c0a4d109a3a15474805f0dc06649a16a7805e8d74bd1af7658f5f9ef726d560595ff9f072d4cfaaf61283087843b904b0f5670ca551079c759d4a2839a71505e007cb5d49b0437b87a080fab5e2efdedd1d01f0f1ab72f0e6129a2525fc6e9829b56ce9d9f287a5bd80be8b1556e4ca82eafc60ec22315448768a72e45d4d956c16ee48a0658e307f81ee0f695f1b1b747d1d533d8da720f088b64608b1edb2d4d27247b2cd35e3d94e1256a3c5c944bbafe07b55ca74df4ec0b869733ddb466717a16e98af4ec310d046c90046c024fb33fbb2ffbb105d41bdd0e0af27b1239aa4d92b6ef8d727e51372fefc3b5c8bc6eb585a0ae2dd9970009555c2c2ced5e5a1e97c659565b6139dc4f3bae788e21f9658affa8fdb6f4733f7fa83fefab91a030f8ec976b8263c17abcef46dc22456d5347eea7c30dd25bdc3caad7cb2010f06573d56b6e5d28e6e847d8df8f18d6a2655ea66fe3c8e7e4ef192b5a8aeb35f8469277657b77155142c7b1653d5eb9cf9c4d69bbc5746e0c1876e330f9016a2f5343ec60b2f35ea380169a2bdf102888e6aae7e797d0bce73834f418018e8e55492da8236a542a999d9eea55bd52ee2e59feb0329d716c78c0bfcd79dc27cd9639399d2fd99d2fc9c4900ad60bdb8221501038ec4baadd2ac4830b2bfe1e20804c818c8e089661e7d842bc4e566fa0bc2d7968a44f8df0d4e88e494fc7bebdb695d3a8edf6a2703817b0f8c1a55569ac4a8ff0931137f075797e9744135a3fec6c767af26d4592a9022271a4052b1f1f24f072bd5ceb1d19e02b0bbf31251a7bb8b723bd3da02f59ca1c0c91bc10896970a1e0f8e0fd5b755da58d70be8935f65661629a9f833b35810113ce80125f8ed7a031cfd5eb1475b597856b4ce7629a9429d840a3457bbd70c05c73c6ce84dd59f917a24d06ca8743225ab8c266e209fbadf57cdb587df96eedf54c04fb3f83ec0dddd1d8bf9051c6de4db3aa099f1779f3f30f61f432e5c8f6b7ac4ee6c6dd6fce667556df155ddb2002735fb7addd8acf74863ccfe04a3088317634eb47e56b18c79f31318ac5e448a9094b5c2c70b44dbbbff7c235cef4701d504723b032726d009c6d7f527e645a23fc1ab478e6e2699211694d575bd436d778e7ae53868c63dfb78f591d82b979585cec8bbcde61f375e783e97e8f787fb392fa4f0bc3e9010aa9ec3cf6471bb16355c3ed3fdf2ee5b95ade86371d60fb0699a851770a212d0e0eeb3f20df78ab180343fd79a9d04d8dc56d9fe3d820b27d98d12275a40d270f4181aa1a18305c8d3469a954b2e85405a394684cc234702a6cb01c04ccc941a4392cf64ba31bea700d339152fce6abb0dbe84823b8d3b18258a29414fd52c91ccbc198e101287b79d8bd0e5f4b05a14a07055e66ea37d781934840a204638bffda400113bb1344126fe1c2ac1e57bb861c3d35349b1fba0c11e12921262ae52fb2e0bee444f8197e2817b9356e10af67e794a7967055936bfcb51f4be6fc5602a8df97ddcd73afe83c02f00d4f1d8302bd2e826d4c50fd3ded9a74debd0e807b694e912a8a3a800f5b983e171898874b77ea305ede4abdf0db5ca84a8a60b184374c08066537b08d42a609b97039ff8905bccc4454188b051c5d1e574e1e8b74cc5cbded064a5374c55f17002ee9b17447fdc324a12e3f2f414b491cccf20c9f98820461f4c7d61355a30f1a6cbb2fe7403b90587298fcc9500519451e44225c750b8b32a649ea288eda389e596390a5386652dea5d0e096ee270bcab9da0c3c4ba464f44172732a748e339cbfc8f0c1ee3187225e2fb29e67ffbd84df8acf759c817d628e03a245e9ae0cf00939fa12964e8dc124659eea8798b097ba52480532fa11194e4623ff63f6cc1d17c7080bb2c1459fe8cc9b197b89ba91986b7bfa61e514bf5c60f981e63baffd9fce44af87ad73fba197e46790fc03f8a46aa6d7590f47e08daedd7f564685208ee87da84b04b11cdc0c020bb26b0abdad3c1340649130e26af9c7651533313301e8b517a84c807d86a4c0cff68566d34da4111d67bdc77ef5f49ec7d83af24a143bceaee020acce02499c725ebc341a86d91c7f63dd962ffcc09fc0b5673873ee55cea4bba69b5058e4b364fb3802832d5118774790dd12eed78330412dc877cc034309a7e292ebee955a431fd46faf7884cf3bd5ab03d02b8784af2a84bb907ba5f021fc332f638a2d4b6451ea0a2cdee6ff1621d698eadfc99d6f405003f300e321a9e80ed3b577a899fa7dd891b53cab8acaa9fd3ce02640eaa75646f134c190817675b9e4a688d0668528fa3b378749bb6b1a0bd16873e89dfc927dcf568fc3cf94ac49d289ba1fb9c58a74574c8fbac321db256bf919e9432d6a8ae9a0dae900901f436b13d0c2b753a5eb6fcef03301d7faa15ff32ec0730335b13394bff66ea83a7043f9e1df5962671ff2d2759db234a4a4fa47fd3a9359bb14ef5b5fc398836d42afcc5d5f252b1b061afc6a0815b3a7586d25eed5ee52c56d2389b8f2438649ee652b431d3cc4262c6e5ea1c0ccec21aa6123e88b4bc933098576bd78cf5bcbbc278ee682029e05e91aac2043ad3ec1d3d97f6ebc6bd5faffa5bc71328cd4351bcb9a0d8d1ea9253b97b08c8c53b20e29703568d5d7dfa2bfa6aeb3a93043e4123116a125311695a11c8538658210971d7763ed7870c1309893909e306df22fe968612531e58a91d19dfe2c658ade19c8e0900c779af8ec333d19552e42cdedbe13ff85d99b10baf8daf70951290db56bc7ea049e6b468b6546a7f3ae77c2e14770eed1ea345f0d139336af4eee686ac2e73bd4262cb802e0173fb872a77cd2c0f3421c497b0260be79ae29d04d9a9da9d7bc101ae3ec9dace1133332f05b7b82aaee577c06c0d2a8eaa8a96db8b899cb3240cc4dca4f8eab513ad5b3529063b5df3664dde0db1e0ae5c29e69f011076fc7edc4261d043f38f1c68645466c9a5e685a07393b7e2f8f74db86742ba5ac089b45a42df3f943842747674c1653aa2a8ef282f64e7ec2ce1fada994288a5f9b95da4bc083ea008308b91212c74a08868ea0fdad9fbb1b485b793bce6e4fa945668b2351232a7c8a084fb2d87a5c83e7dced6bde3743617a7c4babcbf9381694b64d7e0feeb6615440e927a63293c6b695900b1e7afad1ae612c324a88e6761c3b6fdc41d18f514be1ba3a1ca53fdbcf8c19f95bcd60223abe52d07fd7c4114dad9f347cf122f6241429da7e598959c22692910323a0a699595398f518c58deea7159920d89e3e65702bc2cabea7e9ca0bbb7002fb7be5243bba6a08a12238ead443ff4394510d25eb279885d9112c44529f294c5a2bf493a74ba8f4e38744e632680b3ce055a897d2a5468ef52e6e70dc5af55a9fb83739f6cfc6994871662b8263f2e07e21a6514624909369e0138755165dd2af5a791da63c0604b68ff160fad82a578a06e76f62bb7e951b81d8fde2dade6c3a314eec5913151c16a93a5abd5ceb59ad96197a349721ab123b42f799dbde36d7965e0e5dfcf43d8d1ae13f4a00afd8dde36137d3de87f4e2c0366c18f4b3a449ffd9afc7c742c50456f6e642f7d09e86d5aef224b20ce5d8a2bf164484df8fc87daf69e459fc78c6b974cdb8fb1dccbd5290f560e3114302886e2828ad73ce71b06186254206743076c6af0c3d1facc36695dc28db1d026686b141247e1c7a9323d544b0079023cd2adedc0479ceefc8e0c34782603d0c27d18768eb5485a85bc385ffdfd25f735688a3b9a0c6f532b2a7989c751804de0163582293a17f635fdde14e9067f12929b079f89a53dfc87b986f89f718320ede83cf4086d0d095b24b66d5e3f1bfdb08b79cd5b25657cf2b20faff1d199c16bb7f631b33970b34c12997637447e4127db1bf580b339807637a86e0248cbcf8e1d30ae6fe053e2f9b7b3d0f9e3f4813af908b633560779012f9e06af00e252bb0df9f0caf7d1e82f8deb2ede21d13f406dd9ea69445d50844c95c921d8d1cbc8afbc5ddcd4157e65cbfbbafe2670e9146a5643db049a8d696f0eae07c3d4099447ef78bdb90fc05d7cc97bf9b9dee8719464ec6b9e6de866f73914a80396dea3900a9f7b43a47e648e20a9504da92c47ac65368813e5453e82020f8861aba2534346e6137e71adb28a5ff080365d6ea26dfc30ef5500d0760749d6e4e0f93aaebed544832308b19f72e92ebb8eaec2492c6ea7972fd359a8b67a1f4053bfb1a3c6fb720b5925a7a827e59b3bd0651b8014c77b25d61db17eb169cc2fa2442c82f68fb42200c59baa468a9fc92f13273ff071124f8b31e2b4b2517ee622d29489997ecb5676fb52e3002371c01004c214757b1f510091c2377a08d058209d18feb9b524a41712b6df4b92f2b14c583d3196749f367b3bbc8ab5e9e2615c511f23ba5fb1bac2ee9436dd8d162bd96f1fb663d2b520ba7e8ddfc2a4d549b63714654cfbb37ee1dca5f723139187ada8f8d5b42ad09ff196b70720d2527b4466d44f33cce486ef2e86311c75ead31a17b16989dc63bacf0d465379d9138df7ea2ebc71f4cc3b6662e24895050e2553dbc160a567d6722964a904d43bf2684206cee3562256e98addf3038e968cf6c09c921e2c89c9c249f6ba7afd20dd27587b4143f704f2738315a91c2d40c467111b4f3bae4f77bae402145e742ba83a527aeffca13ee2290988df882feaf5a3c24b416d59e06cf4f8832a016ce55419b7bd2028545557528a0af23f17942433e13fad089fdb79449bd9d99b0324b1828791249b6789a09cdfb6ec40c0fbaf8b28ea4f72d3df5159bea7a7965b94beb1bb01d87d76ae7ce47fc333fc152038ab4e7ca64a802f96f2e92bcc53ad9cae0242c622c99b2daf005e554cd6ba127991d84841ffe3ba0674eb7930509045dd00ab91a7c6acd2f4a40e7ffc9959929851e40d417f488a29f7bb5af3847a8caa5daa0682aea870ac8b866ccfdc435971e3d862c2f651cc6eb8a33fca313a56ab8228ee9ac7dce14ea3c3fba4f58c70888ae558d8cd632a2723ba54a3d538f4e20936a2ee543e9b2141e06095c72d4ee19908febf7c248c03a78655420da644746e2d508c31ceb0b648800d95dceec72f7576502046e5dce54b5a097f625001bfc92d6e4633b293cdfa63b1fca5de9e26d03ba2f1cf3647dbdad5359ed76bf702f0621c057dea3617af678016aa13360ebb02c6cb2fa0d3f137a1a3c639c989e12383841ab7ca5a84f84c08af4b85416ce7ec3ed91636a79add207bedf9dfb2ff626387f20cb3315502b2b06f361cbf6a51fb507598af41c5a5b9cd95ba1894ca372c5e1851e62a0d3d78dab6f92bd43ba6fcd71230b6cfd843d89268872b75e3c5b471db530b7ab5451dbe63fa0bdaa7d74907cb376643e129febbe6ce10b5dffbf323dc973f097d2081e06aad65e674c5a41bb81b80556fd78691fe6b5bfad47fd1b64db577f27f22f17973cbff3a7c4aa43569bbe6843d773a2f933f472650e88e0ec6643f87dfd37e7fba915c7386a130b8d4f0ff4d0e99a633d1f863f3e8ce4e1ac5e31438d89c3b6d5ace3aa6e14e7073164ea01e853958bece389316023127f9916297a47c5d6ab5513bab874c1ae3bf2850cfab9018cbf50a7febe03ff3e8e4e55ae5632812b6a147edf051b461bfe56f01a6ab571e0553e37a57a3a9811f4fda2e189d79b74215d6fe199595d18c6543c747572f8cdc61a53ce09d9ca96b43a5af5b56b53148dd4fdfc1e22c9958caa783f2d112d8d5fd39e6955df75d35c59a1967fc0d8d3293e39a6cdf82d6846b39a74b1a538372c266b3f12d7ccf464ff7e32fe54342994f51d344302b3b2e11eed2187a741eec99ef0a79a19a854c03d8bd3fcd557b9d8bfb35f0976da327fc7e8d95fb43db8e66be5b373385fc1b68099566c7e88aefe92c7c521d084c15c8d403d87bbc975e8d687e2a51e5ce53191e3db5bdc50f475853cda7cc5a7365c41035aecb61444c2a48492a600b58300b2805be97b4e9e30526e9e62bb3248a17c3809219307ca85351495c943a865359c783cf615a809c739cce0786c6045d9c8071797001434cbae571d42cef415e28ed6adab09ed10e0713dc1412ed80b8d26d549964321559137483c81b19203080b36abcd68e841f4c78b5302da79fd6e555f390322ae67e54c55749491889d79eb2982fc4428086bd1060c4113137ddb4dd7c9b690b802e805999d4f5127f66f6b1d397dc3509504e2196513b5787407b45b928cfc3c437523daa4f876dfe061e351cb3bad99ea205ab276c4f2a5ccee1027104f09adaf55cd282d4e9e44ac2b65f7e423da1cebb0ac70691347e7a7bd0de8bc9fb2e7a08afc0075a0e85902316cd6ec9a5802c51a6d65bf3251ae712ae0f66de6cba1e51efbad53ad7e769f851799caf5fb81ef35b4da814915dcfa67553f1c67158154707d16804be27af2115559e4758b313b9da4a1131718b29a75970b3f0a5e2f2c11a0a1ed47f238c145dc4fe9e8e963d8395c67dfa94a232b8133a0d953b05455f79e0bdff0bc3de9c04d93d97084ab99229622cfe3958ac5fda6757de1696b575f6250b441e6368386751b1d2f6007d254d152fe76578fbbe164af49cda805b9325f7ea47f5e18f3de1ce38006ae1bf027d3e354d6f923d8bc6286aaf9b9a7b9e7a7fbd36a31db0d88166dc68e7eb567d8164bed1e279a8810fc21656621ff7cb42a21ee04e6086924bb62dddd16c3343db69250f7ed95aba953202640bef18dfb6c00f1ee03c670a5cc6c0f3cd7cb006590dddffa6f19d450860e289f85edb4fb0dbbd2f992eebba09cddc1b20a3c98d8739ad1875a514b09b1f23cf406c4c55cc4266e0b8b283fa445849316c30bd19254e9d035756d2773cab7f5fd56d6d3a094a717ccca43251201cfddf80ba1aa0dad34f5a3acf8476b784fd53a1aff1307a7838705112650bd25dfea21b991d801f018a5dae26edb9dd5a0ab940a94b7bbb90fd1f30f9d1dd2ea3aad6d0a2a3c42fd2641233c7d624314c3a54ce616d2ca5683d04f6fc0924f0b667be32f4de8820f9cfab963a287a1c708857ebabed9b5bcc35d539ef9bc170636cd528ba86a620195134cacbc2b8e742376124b67ed8155ab53979e281f97b184c60355b008f15f45c8b7a506b1c1f511e4aaf0bc32fee27b656b01ed6afaa4053ed674a60175b6c89a77d42963111d0940730db02ff67534fe6a296e0e01e2db6b3f0fe9648286a0f3420cd4393163662751deed6457abbb370f83ed92e9da86a0181df13b8ef33e5718ce524a700ba5f2b40f3f973a67c1c412dc251c19e6b7ceb279dc1dfc36a3567e3a98a9d96ef52b0d0734f57bd9edebedd925167f230b1c81ca938e94ceebe43d2573735873a436331a8b76c1169c6a869889cb74e5d33721bbb99ec87f160c025f570f1d11c2e3ae6a52580785d854790139510179b003418dbcee1f4fd4fa39fc134521ffd7f29cee650472638dd04d8331ee439eaa32c57b56c4fd9c9ba87516a8236dc99b8d6e4c2a48e53a6779d5e13bbd73cc7917f0cfb8e231218bf33bc3c213599eb76476558f0e38a3979cdaad6ac6b03bd0ef0aefec634fbe0e1e87bd78123a19b7352326b9def856ecfc02b06622f94e8cb2a1cb6cf10d020f789a7db775063030f15b463f08878219636f2bb94ed11a3ed9689d797a3253809c7f2e0c60672e8476a9e272075c7f808258901e611c4d535a11bfe01daccaec3a26a187ab45a9fd0bb9a7ecf2e9c4aa3177ddaca1449f19f78ebe26be2e25bca012a10649b56899339f5418925648f3253bd716336dcf65e6b4f16d2ae51fed1acbc8335c103f721f46023cc2043f568ddb033aa5f2157e52b89eed4571cb523fcc66ef5cddc90679633c2a46f45f1a86c975db4f6f37f9fcfe54809ccf75305bc9f242f26f30a0ad5f3cd71cbd31ac45ceed2dc8571142a09b7d3091a4838727b9a067927e17b7559076649b405dfd480627881489d52339d4a8943ca396e92b92066e45d525acf7785a944345d25d721d6a354b1a9f3e2afd379d1c341badd0dd913a3471a5b78a81c0b338a2984e115d003b1deec1b44fd19824279d742017248fb4434cf47ad07fc87df86e634b2d8f6e0aa572088678b9a9f767404f06c84ea8cbf65d46effbde7de1f090d3d4b9e7c7c3b2b1dfa9e591efe12ffe0fc82c9eeb7fcd9f25fe438b39c46614438d0be7e1dad11bce8b91396f867531e8c45d8c01119abc2b20be253779b5e651bd80536854e2aabccddc5f4fbfb3497111fe9a8f8a417ab4dd806745c82126524ec325c931ac1f31a3cea19e159e1dbfbfcff761cccabefad38062872fe8a45a14781ba12551befb31c21150a56ccacf9815d8f458b1f591c71ba7b0459e7c09a4eac5c9e5b2984314ecd2f7054ed055ba082204f7ed62b1d513cd0992bc10c28bc745e30b27f6ca28ac84dec6cf0ef73c971ce12b2ddcc0d6264d8f7dfbba0a20f8ff1d7387cd9d9872f4b345b409950d66ababa9852f7f5ee634dad6085666956b97e4c9142dbdce96bf42d1334c61d04ffed5ac8f12a5075ac87a7416fd52579a876c89e22008759a93ebc57279215e178662a064bca65670089ec688532468c07161f56bbafbfa5655768123e713c7aff52852978e9d6004ab3a434d9b5c73f0d90dd1fe742a169a84f0e96a189bfc5265d8c5e2d9e42f5503d04ce01f9a912bf8b9bd8c282a4d40bbeca55d14971d1d305a16eb85d02b4edd8d35baea56156ba12f4e344dc4cb34509fc780ee97d24173a75e49960ec32055710bf8119d005447c6c391365737a0cff68d9f44868b97b2357dc051ed7fcf590b32292624545935e87f25e56b3e4a2b9c39c4936b5be9030b4711f246623264e0370291b675e75e1ce9cb425e5fabcfb55e25f084ea8a1b84870135ad997f7b700876691939cf268204669790a10ddd3d38cd22252226a09fddd395482deb561ee834ba452750d5b8e0de63c77c85a7446dd5bb29df2620f98e07bdac4cb59af8b9dc64d427dab780257e252e8d6793fd1b99f7c3162b4233a418526ab227d40b9deadc943d0f108a38d7a6b075465a44c920c0146338504eadf826cae345e864452e94706c8dceac5cca87469f2183a9c918295c09eef65f747b7a3d7fb3d259c4f531ffe48a5c338717ceb45efb557a47a593fac85cfaa4c263c109d385c01a3193a6ad1be5923d6a53e6c369a2b5e704cd6ac3ac255954c3fca1079895c596596873c1309fdcc5f36fe039d06806dd16cb00bd028edd6b44fb1e9ce4a020362824bef6a59502cce4e1d3d3884d7d865823deb092916a215ee73bdae1d4baf7f294caac7f63a36c2a15a40517438b8cecb93a5da3e11c25ff228ef3e7281360a2ce3ac66e69a2f136a83fbdbc44dd1737e9a31bdce16df9e118345ec1d9a9c47bfa60502722c9813d31c9f1b0364e2e25d77a0816db52f7e86bade9aff644df50b1cea9a339e76e869fa1fa50101f8182a2a6aee2e90d242d4b4d6b999d1c358a8d9297b6e0e2ec141c2b3692d70b141a213d477e87c52a2c87a5c6d1f0fb091f35f50915878ac70000000000000000000000000000000009111b212a3236"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/unknown-alg-0x10.json b/ethereum/core/src/test/resources/aere/pqtx/unknown-alg-0x10.json
|
||
new file mode 100755
|
||
index 000000000..397c978c2
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/unknown-alg-0x10.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "unknown-alg-0x10",
|
||
+ "expect": "INVALID (unknown alg_id)",
|
||
+ "alg": 16,
|
||
+ "raw": "0x50f90ec5826d6180843b9aca0084773594008302d5709400000000000000000000000000000000000000010180c010b90520caf597b4848d085dd620001a7707a9e0c120226d4551a49d4b6e0cbf82ad3dd96f26ac5e395a26aa1f3b569e89fc4914cec8fb3acd07350d1b8e0f6b66f7ac3e4f07395d148f5ba65789908df3cced072e5a56934264354556f4655afb86d9e892fa9926e44f74a340ec5a92bff6211740ecb879366826987e5556a513d8c2f585eb5ad5baffe6cf50aed2b96bb1f963bb124f2cc3b95ba6ec5c4f272e7e457bb1c6547e284ffd1c7b149b877c1a9856a3303f9aa5c4005c376767af6d7f00097e97d7a5bee0c196a12293ff2cef34a09f0f594fc12a2e40a4d7652fa8db49c02d76fb76320e29a0d6b15e97a65147429fdc70e4838ba9f60e0318132aebca93b564960caeef51770e45d8a6ea2171f9e9482441610de9fc8c56d80e952fe7c2ef0dfccdc0a337bcceebc20a8a2df53b4f61f289ebdfa2f134437e21fddcfa394bcd16562e41d1715724afb398f8312eacb3ad606fbafc00954407f83cdeee3bb5a3c565f50f9d54ebc8215817deae80e42c66dd0960ba23c3b1e99d710da8e1efecc89c76f769bb5e40b9ac5ae998216c3eef8f039fee88e43dbfd056be1c43145690c1c9d3775446c80d93214a89ff60892b4ad7c55bf56926b834cd21a3e09de040e2ad9b6499c0840957b6661ab1f149cf79ebee095b8c481e0feb761164b4fa5360e79987a0dd601a60de09ace752b5ab69fd73ff111e1410957ec95bedb2a9dcf307037463248e4b4d8c0fd1b455969145d2a77ccec9e101f5e9142e4f1629e19662269a9f422cd64f1ddc6d7bcaa30c949a7c67bd6e14fbf8dd7244ba465875df788b1d932631d6b749c37bccb00b04efb9a5c8d05dc73564bbeafe507c7e36eecd957c2054696602ec27892c88953fb9a5019899bc3ce475c4a2931ac49a4bc206b27b40ce3021096729ee2482bea5001985bb22a0f62dc36cbb38b8fad11d6a7c055312e69f8966a59b5c9b6237d7a8e59f43d94bfd5dd8e1589f3143ed4252f6fecf4bd40ee30b1382256fcd3218d4864dd281cf99d83c1ed4a766b26698a914f044d45405db8d7745b3d7aebac37e668c6e8c5ca09a0e4ec2190300c19990d96742ce7f539e05b8bfaacd2d3bbfc07faefe22d5e8795fc8a6e8cbaec0ed1489ce625ce9727ff52660025002ea692dfb39935ed30280363cd818a324d9bc782b46ff730e2e5955640bcbcbd285d2f2fa773154d3fef5bf13cfe81b857bbb576506ed5dafe4477e487171ee64c9e37d49df5ca7529dae30916b72965a391f4d3437303f7cce8c45dc187febd2a949fa7278f7f8775dd2bdd66b794945b0e96a0b58b6cd934deff1f4ccf156e8942c7533c8a45314ef5e3210fd5a3f063982211a122f9a3f1f99c253c37d981f223dccdda18a34bf3bfdf9e02ff607ab7c92ec4388dbb7fa210c7106bf570d60e5321ac1e1ed5fe32b4053759bdc3b87b1fb7920371b6c206d6f4f871d1667b41bb8e661f48144a312e3d7e0d372322d0a3dd8641574419c49f2ca4228328a089e97e86c4294b9b60af0998495379248325299e3846741ebaaa69994ce536201665cf6cd23de4958fff41f0601722df54d2111d845806c013b336d73c8461f9bf5a16eb05b08140c1a2291f78747c74cc2568e956f307e97b01bb3a67eb9cd51be8fd7ee8cbcdcc5b2b2c27950f5ff0f7e8330fc2f95e3a4ae49fb7512a6106c5cbbe4a5fda693dea445fc7e792676b5fded44d7da271c63e76e310ae988ff6885685868fa72e57e38d1b3c80318dbd5e075b29db1e038c56dabf7ba39fdf525f08aa69baba0817a0e289d5c12448eb4d07cd397fa39c312ecafeb9a846fd0b20667933c4c34bc5adcca7df159bfd5b909740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-1.json b/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-1.json
|
||
new file mode 100755
|
||
index 000000000..d38c774bb
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-1.json
|
||
@@ -0,0 +1,28 @@
|
||
+{
|
||
+ "id": "valid-ml-dsa-1",
|
||
+ "expect": "valid",
|
||
+ "alg": 1,
|
||
+ "chainId": 28001,
|
||
+ "publicKey": "0x372c0f4874450fb92ace74d41bc0326c7f739589f9b86a97afa87ef65d5939e608c81a44909e41f41931349f744b7aedff8d5270b91c4a2f61192e2bb6e3e6d12231deab235359e78ccada386becb6a6a1105afc0999243ab8b363f7cd2c19b2b741c9969dcf20252f20d130dc05d9244f58d6de9b4fb4b6f0125c43b60ebe3c7272b6ae7578f1abb4bb5e2dcb31eebf4aa7089aa2bf40a0ba5eb73aaa90e45472168738cb0e866547e079075d0341c4728ed794cd449d0cdeceaf64d09173a2677e3f2621b56014df58ee8de2bbcf8cb2bf369e57a28e40b24df6d0b15d3417b7b7fce3c49230b3bb7c7080c4f1344380db37299d8c0c29a7c9e95bfc4f3ec70b767895be6ad798449f94c92f320696f8f9ec844fc9451f5ab30874e6c78673b932e24a918d5bc03f4fa647c8679631ad8b30ba4f9a1a790a535104f5079f781fa4c4aad807777327e08bd6e14b957e527650d39e2de7d30da7b2b27457d3539c2f99903054bd1a6d6301b2f83249db80dedc911059b047b5552407ed32b79b57ea4968198decf978fed532277fb189841d0c17f261f1a7c4618c33b258a71cb6b2b921c48735c1fbc375a80fe2d702e9f70db34547147f6d65153f1c508ff90aaf57dfde59ce6e56c5c52049b10fbc2640cd937bf5027d755444cd5e84aad66be4ccf04f710f0b970cbe7fc5e4e7a44f5d8fc2af94ec6df87862dabe0d85dd17e43728800d5dc8ff9e9e1fd349b9d6431f264836a447646a1ee2d73e6a4d1803d71b98510d94d53b5d07764400f413b7837f463e273980296ad5e78a62c83fb91354c25c2e28bfa19480ca41b0ca2d8beed456029eabc0ba69cf3504cf1207ab21bed0e3a60795f5b066019132212a9bd20e98b43bb32484454b7693bc63764d0ba8768da4336ad16a979b1d3e8b06e89afc4caafaddead83ad861a4596814062468d8cb2e131e71cf38c4e335bb3d1d9629251fd50a4273999a20e11d9a881fa2465c2ef32301fa8805ccb38b4656e3c815b54ef42f292d05847c0e5149b0a2ffd1719fcad10730b763406e9e453d2e4a556c397a984a7d8622466522e79f715f980279cb2d1d74d5fd15f8beb8df9c0a1fb93f0d5494ab701cd60cf2b613b484a191d873449c4815f44eebb62658ef90f7033a5e48d40c8f4ec9a25d4f1b73a150e5b03a4feec9142362e77d74d364bb8a40f9873efa2d9f458d84277fdb0063642d9ebc794356368a0b4e53f6ab0d9acf4418fa42d05c11db12cb67d6c4cbbfde4d85358abaf8042510db53c1540fcb40045b334bc54a17608e82433d1e9e53c99769b86b69b8cf1914584cdef479061718a2cc5bec5c31272e0463139721c0c3523a6ea31832b5c15aa59819304c217fbc51a2636bfff331e6dc1037e89be15c17d6708762976329353612f312b828e525c09b81afafa5ae5c25d82b70b6e55f892429a93e5eb4048ade675583e828da988f9d253123a06c0ed047adf4d93d20cc6c865f5a761fec27811305165cd4bda05f563215d0612944b88ade9d64477ae8fb441978720e70b0d77e2edafd3a2c571cd28a42cca2f289d157cec813c24e7f56051b4f28c153adfbb2c1ff90ea1fbc03cb89603387169072442f5d3081140e2256ebadcd775d2f1da92c15a9ff1ce6e980b3b1e91a7e379081ed46a4259fada21536af318eb2043ea16cece60b73acd415d239389cad9212e15bad1b1ae38f93c756635a9b87417faa844e4f43bae1f1ae68641a04f0ff1d55f9045cf7e3ed59fde5c07219b9113329356d4300885ee19c9955c5757db33c6ae75b49d035003171d02ccbd7321d6a14db0bd011d4877f04070dbda3b67bf22d083e",
|
||
+ "seed": "0xfa8e8bc1e5b9aa3d7e7c7f7a5975ab8ee22b1f9bc118a3c20ca50f4f0e737aca",
|
||
+ "tx": {
|
||
+ "alg": 1,
|
||
+ "publicKey": "0x372c0f4874450fb92ace74d41bc0326c7f739589f9b86a97afa87ef65d5939e608c81a44909e41f41931349f744b7aedff8d5270b91c4a2f61192e2bb6e3e6d12231deab235359e78ccada386becb6a6a1105afc0999243ab8b363f7cd2c19b2b741c9969dcf20252f20d130dc05d9244f58d6de9b4fb4b6f0125c43b60ebe3c7272b6ae7578f1abb4bb5e2dcb31eebf4aa7089aa2bf40a0ba5eb73aaa90e45472168738cb0e866547e079075d0341c4728ed794cd449d0cdeceaf64d09173a2677e3f2621b56014df58ee8de2bbcf8cb2bf369e57a28e40b24df6d0b15d3417b7b7fce3c49230b3bb7c7080c4f1344380db37299d8c0c29a7c9e95bfc4f3ec70b767895be6ad798449f94c92f320696f8f9ec844fc9451f5ab30874e6c78673b932e24a918d5bc03f4fa647c8679631ad8b30ba4f9a1a790a535104f5079f781fa4c4aad807777327e08bd6e14b957e527650d39e2de7d30da7b2b27457d3539c2f99903054bd1a6d6301b2f83249db80dedc911059b047b5552407ed32b79b57ea4968198decf978fed532277fb189841d0c17f261f1a7c4618c33b258a71cb6b2b921c48735c1fbc375a80fe2d702e9f70db34547147f6d65153f1c508ff90aaf57dfde59ce6e56c5c52049b10fbc2640cd937bf5027d755444cd5e84aad66be4ccf04f710f0b970cbe7fc5e4e7a44f5d8fc2af94ec6df87862dabe0d85dd17e43728800d5dc8ff9e9e1fd349b9d6431f264836a447646a1ee2d73e6a4d1803d71b98510d94d53b5d07764400f413b7837f463e273980296ad5e78a62c83fb91354c25c2e28bfa19480ca41b0ca2d8beed456029eabc0ba69cf3504cf1207ab21bed0e3a60795f5b066019132212a9bd20e98b43bb32484454b7693bc63764d0ba8768da4336ad16a979b1d3e8b06e89afc4caafaddead83ad861a4596814062468d8cb2e131e71cf38c4e335bb3d1d9629251fd50a4273999a20e11d9a881fa2465c2ef32301fa8805ccb38b4656e3c815b54ef42f292d05847c0e5149b0a2ffd1719fcad10730b763406e9e453d2e4a556c397a984a7d8622466522e79f715f980279cb2d1d74d5fd15f8beb8df9c0a1fb93f0d5494ab701cd60cf2b613b484a191d873449c4815f44eebb62658ef90f7033a5e48d40c8f4ec9a25d4f1b73a150e5b03a4feec9142362e77d74d364bb8a40f9873efa2d9f458d84277fdb0063642d9ebc794356368a0b4e53f6ab0d9acf4418fa42d05c11db12cb67d6c4cbbfde4d85358abaf8042510db53c1540fcb40045b334bc54a17608e82433d1e9e53c99769b86b69b8cf1914584cdef479061718a2cc5bec5c31272e0463139721c0c3523a6ea31832b5c15aa59819304c217fbc51a2636bfff331e6dc1037e89be15c17d6708762976329353612f312b828e525c09b81afafa5ae5c25d82b70b6e55f892429a93e5eb4048ade675583e828da988f9d253123a06c0ed047adf4d93d20cc6c865f5a761fec27811305165cd4bda05f563215d0612944b88ade9d64477ae8fb441978720e70b0d77e2edafd3a2c571cd28a42cca2f289d157cec813c24e7f56051b4f28c153adfbb2c1ff90ea1fbc03cb89603387169072442f5d3081140e2256ebadcd775d2f1da92c15a9ff1ce6e980b3b1e91a7e379081ed46a4259fada21536af318eb2043ea16cece60b73acd415d239389cad9212e15bad1b1ae38f93c756635a9b87417faa844e4f43bae1f1ae68641a04f0ff1d55f9045cf7e3ed59fde5c07219b9113329356d4300885ee19c9955c5757db33c6ae75b49d035003171d02ccbd7321d6a14db0bd011d4877f04070dbda3b67bf22d083e",
|
||
+ "chainId": 28001,
|
||
+ "nonce": 0,
|
||
+ "maxPriorityFeePerGas": "1000000000",
|
||
+ "maxFeePerGas": "2000000000",
|
||
+ "to": "0x0000000000000000000000000000000000000001",
|
||
+ "value": "1",
|
||
+ "data": "0x",
|
||
+ "accessList": []
|
||
+ },
|
||
+ "algName": "ML-DSA-44",
|
||
+ "sender": "0xa4fe6cb101b79c0531f265f6b2584b37073087a5",
|
||
+ "signingPreimage": "0x50f9054e826d6180843b9aca0084773594008302d5709400000000000000000000000000000000000000010180c001b90520372c0f4874450fb92ace74d41bc0326c7f739589f9b86a97afa87ef65d5939e608c81a44909e41f41931349f744b7aedff8d5270b91c4a2f61192e2bb6e3e6d12231deab235359e78ccada386becb6a6a1105afc0999243ab8b363f7cd2c19b2b741c9969dcf20252f20d130dc05d9244f58d6de9b4fb4b6f0125c43b60ebe3c7272b6ae7578f1abb4bb5e2dcb31eebf4aa7089aa2bf40a0ba5eb73aaa90e45472168738cb0e866547e079075d0341c4728ed794cd449d0cdeceaf64d09173a2677e3f2621b56014df58ee8de2bbcf8cb2bf369e57a28e40b24df6d0b15d3417b7b7fce3c49230b3bb7c7080c4f1344380db37299d8c0c29a7c9e95bfc4f3ec70b767895be6ad798449f94c92f320696f8f9ec844fc9451f5ab30874e6c78673b932e24a918d5bc03f4fa647c8679631ad8b30ba4f9a1a790a535104f5079f781fa4c4aad807777327e08bd6e14b957e527650d39e2de7d30da7b2b27457d3539c2f99903054bd1a6d6301b2f83249db80dedc911059b047b5552407ed32b79b57ea4968198decf978fed532277fb189841d0c17f261f1a7c4618c33b258a71cb6b2b921c48735c1fbc375a80fe2d702e9f70db34547147f6d65153f1c508ff90aaf57dfde59ce6e56c5c52049b10fbc2640cd937bf5027d755444cd5e84aad66be4ccf04f710f0b970cbe7fc5e4e7a44f5d8fc2af94ec6df87862dabe0d85dd17e43728800d5dc8ff9e9e1fd349b9d6431f264836a447646a1ee2d73e6a4d1803d71b98510d94d53b5d07764400f413b7837f463e273980296ad5e78a62c83fb91354c25c2e28bfa19480ca41b0ca2d8beed456029eabc0ba69cf3504cf1207ab21bed0e3a60795f5b066019132212a9bd20e98b43bb32484454b7693bc63764d0ba8768da4336ad16a979b1d3e8b06e89afc4caafaddead83ad861a4596814062468d8cb2e131e71cf38c4e335bb3d1d9629251fd50a4273999a20e11d9a881fa2465c2ef32301fa8805ccb38b4656e3c815b54ef42f292d05847c0e5149b0a2ffd1719fcad10730b763406e9e453d2e4a556c397a984a7d8622466522e79f715f980279cb2d1d74d5fd15f8beb8df9c0a1fb93f0d5494ab701cd60cf2b613b484a191d873449c4815f44eebb62658ef90f7033a5e48d40c8f4ec9a25d4f1b73a150e5b03a4feec9142362e77d74d364bb8a40f9873efa2d9f458d84277fdb0063642d9ebc794356368a0b4e53f6ab0d9acf4418fa42d05c11db12cb67d6c4cbbfde4d85358abaf8042510db53c1540fcb40045b334bc54a17608e82433d1e9e53c99769b86b69b8cf1914584cdef479061718a2cc5bec5c31272e0463139721c0c3523a6ea31832b5c15aa59819304c217fbc51a2636bfff331e6dc1037e89be15c17d6708762976329353612f312b828e525c09b81afafa5ae5c25d82b70b6e55f892429a93e5eb4048ade675583e828da988f9d253123a06c0ed047adf4d93d20cc6c865f5a761fec27811305165cd4bda05f563215d0612944b88ade9d64477ae8fb441978720e70b0d77e2edafd3a2c571cd28a42cca2f289d157cec813c24e7f56051b4f28c153adfbb2c1ff90ea1fbc03cb89603387169072442f5d3081140e2256ebadcd775d2f1da92c15a9ff1ce6e980b3b1e91a7e379081ed46a4259fada21536af318eb2043ea16cece60b73acd415d239389cad9212e15bad1b1ae38f93c756635a9b87417faa844e4f43bae1f1ae68641a04f0ff1d55f9045cf7e3ed59fde5c07219b9113329356d4300885ee19c9955c5757db33c6ae75b49d035003171d02ccbd7321d6a14db0bd011d4877f04070dbda3b67bf22d083e",
|
||
+ "signingHash": "0xa998fed4c5f710305a6944f263d3d26edd3f4e3949d404f547eece43c10afd94",
|
||
+ "signature": "0x664be581b59cd495740a8a9aaaf7c6801a8bcedb531ace47da1be56ab30f1c4ccdaad6e81aa97352baca12b6c69754123bdee38c0d57bf15f0850572dc9b456234eaf37eb478f9117f952ae95a0d165d12d948b51672a03c9610a98cf332d6ad7ab8a87defb3ef7249cf8c3a815129ecf5600500702b7916ffe570cef0714e0c083a581c2971c45c4aa6b1c5226400e5fd594ea3ae97fe94a0dc7f1e0979b11a2f3d15ad54fea957992ada816f97cd76168a53ebffae36e5787b0f69e94b3e08eadefe4937ce8b383b5022e57ba7135cccd5b48e38916f1f0bdcbc5858bf93cad75195d4329ab41a518d820262b1b610f7bdbe1d6749d006a0dfe18d0be1a19fb3d8e37795b5bc37ebcd884f91459164cd2536b3496c4b25a4c74282ece5d64ab861184e942cf97f0edbe6e1293c4504d861e60d98c4f6523df27a1e80843005ad21665b3adcf46f349fb0d905d70631d2ee51c0086b252778eac27346eee65c0fc88c6db5936337b0afa7d8cec656612c81e11cc55abf421df770e6c2588c743d5540e1280be76309defaffde2b82c808976c337ee13735a21900a4686423625a0ba4819581edbe574e6d7053c5fd98d288db4104ea64fbc0e7ad11d50eb1470a882aa00ebfd983cdda14db34f7f968ccc93097cf037dceeb1375f2df4de09c8785f5fef8fbbe284566e5c9a2d38f5d2f9145b7f5087f6a89a56679680ca4180ad7da3ee45da685f0255a45db806e1379c1ed59bfe63feb7d74a239334c80ab9c1859d205ba798810adf8afc569170f94167439d137215d2ce0b2fa983ac138a3ce201cec4927c62b740912e7287417f86beb07af9c83fff843df1abd6e6f81865b82b3168528d1c473b4999b0179f1de8ae22e8ed7f698ee8463eb93fcfd4e017f29ab3f15a2e061de6deb09459d4ecc62741ffd8514d5c1f10eb3b1525ad60512ffad00e360e0d6add8ed6d6df48d63cf1e36f306bd76b1a245cdd09951727367e45b3a02d748dbfcbeea342be4cb0e1e3108e57993581409f8c6b34e2d38becfcf15c653b92c88412c087eddb0bc21eeb620317f49a9bf5d6164418a26322e1964fd676a547862c2a7ce5f13898e3fadec79a638f257532cfe977fe8ba5e96782f9e1e3e8b5f896a80d816141f0c988ea59ea321cffd23f298b76e49e92189e7f65718d14091daeb82d432470a2e472a39a154226a43c543db2bb933adad08344259ba08a65c543d2ee07b67328ca2d4e60e550b85215ea5873fedb505cc1e4db49e129249fb632ba22f11b897b9423d08f96ceaa863cd29dc16af6ac76c4388c2795250c04377277626992b085ed7be2cf1d63a2eda4b65e287081fdc4e9a3224ff57d81b3ba8d04eb88430a01c5eba35fad028e8de1812920cee2576d0bd291407c5fb70c5ce07104b9af7b98c4c709c7f019d4a66b136120b92612ad5e73dfcfc1da0fec3a7928e57d7d4769eecbaa4c269f2859d31d47d1ae40e4da5bfa6592074c5bf54b04c707b8d97455a0a606686e06bf5ef7617da2532f305267f61c5f627216b06ecc3da6c6f7b420e2dfecaa41657eab20c89927ad6eb5c4fcd513da89a637755f4a98c45cfa108f37415bbf49ee6cacfda8f22f7101a9798d844709a38f9168685f105157a937bb10d4f5b342deab8b8be8231490da52cc0c407bf942270ad93d4a9bed5c06499584835dbba75577dbbc47fd3d397f0417ade99549de4412c8893cf3e1a2ed74c234a7b60461efad57d9c9fed9eec3ebd652282b045174e19355d8cfcc10add9192ffffd428150dc3f48e0417e47d6407008c62486cd4057535a5a9ffc45ef559a51fbbece64306f64da9740108d0b51d01423379bb0a72fe050d2abf5f5acd25cff57f8e3bcdf938749c7bbf77437424ada88c167bcb6addc309b949a8e200b9a5b6797522635731b250e2405f98d054aaff4179ccb4b24159e4c033329100cadbef3da262203622d27899166f6c3c79a35daf7840853b9a3ce494bf035235cada8c31e28be56f0976ef9b96f15de57e6896a5aed57a7b5ce77cacd1c806ecf83566bee5d577f7414a106ce16ca6e8cbc144f571b1a37647041694a6409f68d15604960417a60bc4f1a878eb01e89159e701bb8fd96be45395a8b8c4f0cc5b982582741c4ccaff8961ea892f084b10646c7a27687a2d3c92324cc3a19a5b38ca2d5c573167ad54486ab3adfe9219882f947cc6a93a3827f4b51d76e90ffd1587646d921482022db8b5a22519be3a1e62e9a13ff9926e75c42e07aa295c8486df69dc96168e920e13c85eeda86dc560b9f5d4c77cb8ff001d390dc6c5a911c573ab1711df534930ef28832936c80cafcde731e999ce90741e669d93f653efba12466726fa997e7ad24d34395a02b8a4286f3604f120bf47e8ec41954e6def2de896be477ef7916f18214d28f58ae91ed8d7eae9e2df600d313b6cdb952195e9d030e0b8fc98a68cced3070f4abd2d252727320eb54b602ec861ba630ed3c5d6fc8c8b39f4f1e9c198a6dc8d5f825159ce15fcd7bea5701a225ac41bb152d1a077adc03ecf06870375f2d2618094a648b40244e4a981e7efeadc608c082dc1824c4ffdbc39afcc8c464ed5ca8dfc1540ae3a6c034364c356bf13f880abe8633fa041db78f4be0d17a4bb00959a697935c844c6ddc02222f7aebb1af2c96a757536159dc1dbc31131aefe4c198ccd2123eb5d0ca6147bbc9ab43e993508ef4ca383e2847d9fcb4c975dcb240bcfd164daa835311cf7dbde0f256deb5f3748b55c312a29a042725ecf07caa904513e71b4c0ebd3b31c2938e710e7c6be819bb3125e638ee4b54b4c8fe16df1cee7587e6bdfdcccf2e3b2aa4a54c86b0ae711f056c229c644f519f60570aed60fd3d0638dc341625fb4949d355e7d84cb478133d25730162623acbf5d36b9ed98dbd88b6bf7bf1f55006f5ba2d16297557f966cc01baca56e3f6435b724c0b6fa4cc0074efb0bb2cf0cba9a1c73d3337db7dc0c78b87746db7bbe5fc003edf608ce5d91dbd8b3cec0f738de14c8e2b6df47df91805eab5635402ff26245430641abd9511cffa6bf8d352a1f0d97ce2b08561c97a5f07a07e0ac42a2a73366442e0bf125a718553794b021640ef9f9f07040068cce2337606af46f897b7ad8ced05e14f7ab3e2bd847f810058d665a0c3b6903efd8f398c31e356b48216111d30348acf93d28dbec8e603cd16ea5d3b24f38367c52f5629fd51bec34e86ff21d4f5466a53aea7048babf3afaecec2c9de099bcb2845f66689e02306760ef5274e65f36fc61edf8112b3b414a878b8dbdc2ced0d7dae0e95c5d6e7c80a3b4cbccfe13293e454b6c757a8d9496999fb0c4d4dfe5e7f3f40e11172324323556687e95a4a6bfc4dadbec000000000000000000000000000000101a2f41",
|
||
+ "raw": "0x50f90ec5826d6180843b9aca0084773594008302d5709400000000000000000000000000000000000000010180c001b90520372c0f4874450fb92ace74d41bc0326c7f739589f9b86a97afa87ef65d5939e608c81a44909e41f41931349f744b7aedff8d5270b91c4a2f61192e2bb6e3e6d12231deab235359e78ccada386becb6a6a1105afc0999243ab8b363f7cd2c19b2b741c9969dcf20252f20d130dc05d9244f58d6de9b4fb4b6f0125c43b60ebe3c7272b6ae7578f1abb4bb5e2dcb31eebf4aa7089aa2bf40a0ba5eb73aaa90e45472168738cb0e866547e079075d0341c4728ed794cd449d0cdeceaf64d09173a2677e3f2621b56014df58ee8de2bbcf8cb2bf369e57a28e40b24df6d0b15d3417b7b7fce3c49230b3bb7c7080c4f1344380db37299d8c0c29a7c9e95bfc4f3ec70b767895be6ad798449f94c92f320696f8f9ec844fc9451f5ab30874e6c78673b932e24a918d5bc03f4fa647c8679631ad8b30ba4f9a1a790a535104f5079f781fa4c4aad807777327e08bd6e14b957e527650d39e2de7d30da7b2b27457d3539c2f99903054bd1a6d6301b2f83249db80dedc911059b047b5552407ed32b79b57ea4968198decf978fed532277fb189841d0c17f261f1a7c4618c33b258a71cb6b2b921c48735c1fbc375a80fe2d702e9f70db34547147f6d65153f1c508ff90aaf57dfde59ce6e56c5c52049b10fbc2640cd937bf5027d755444cd5e84aad66be4ccf04f710f0b970cbe7fc5e4e7a44f5d8fc2af94ec6df87862dabe0d85dd17e43728800d5dc8ff9e9e1fd349b9d6431f264836a447646a1ee2d73e6a4d1803d71b98510d94d53b5d07764400f413b7837f463e273980296ad5e78a62c83fb91354c25c2e28bfa19480ca41b0ca2d8beed456029eabc0ba69cf3504cf1207ab21bed0e3a60795f5b066019132212a9bd20e98b43bb32484454b7693bc63764d0ba8768da4336ad16a979b1d3e8b06e89afc4caafaddead83ad861a4596814062468d8cb2e131e71cf38c4e335bb3d1d9629251fd50a4273999a20e11d9a881fa2465c2ef32301fa8805ccb38b4656e3c815b54ef42f292d05847c0e5149b0a2ffd1719fcad10730b763406e9e453d2e4a556c397a984a7d8622466522e79f715f980279cb2d1d74d5fd15f8beb8df9c0a1fb93f0d5494ab701cd60cf2b613b484a191d873449c4815f44eebb62658ef90f7033a5e48d40c8f4ec9a25d4f1b73a150e5b03a4feec9142362e77d74d364bb8a40f9873efa2d9f458d84277fdb0063642d9ebc794356368a0b4e53f6ab0d9acf4418fa42d05c11db12cb67d6c4cbbfde4d85358abaf8042510db53c1540fcb40045b334bc54a17608e82433d1e9e53c99769b86b69b8cf1914584cdef479061718a2cc5bec5c31272e0463139721c0c3523a6ea31832b5c15aa59819304c217fbc51a2636bfff331e6dc1037e89be15c17d6708762976329353612f312b828e525c09b81afafa5ae5c25d82b70b6e55f892429a93e5eb4048ade675583e828da988f9d253123a06c0ed047adf4d93d20cc6c865f5a761fec27811305165cd4bda05f563215d0612944b88ade9d64477ae8fb441978720e70b0d77e2edafd3a2c571cd28a42cca2f289d157cec813c24e7f56051b4f28c153adfbb2c1ff90ea1fbc03cb89603387169072442f5d3081140e2256ebadcd775d2f1da92c15a9ff1ce6e980b3b1e91a7e379081ed46a4259fada21536af318eb2043ea16cece60b73acd415d239389cad9212e15bad1b1ae38f93c756635a9b87417faa844e4f43bae1f1ae68641a04f0ff1d55f9045cf7e3ed59fde5c07219b9113329356d4300885ee19c9955c5757db33c6ae75b49d035003171d02ccbd7321d6a14db0bd011d4877f04070dbda3b67bf22d083eb90974664be581b59cd495740a8a9aaaf7c6801a8bcedb531ace47da1be56ab30f1c4ccdaad6e81aa97352baca12b6c69754123bdee38c0d57bf15f0850572dc9b456234eaf37eb478f9117f952ae95a0d165d12d948b51672a03c9610a98cf332d6ad7ab8a87defb3ef7249cf8c3a815129ecf5600500702b7916ffe570cef0714e0c083a581c2971c45c4aa6b1c5226400e5fd594ea3ae97fe94a0dc7f1e0979b11a2f3d15ad54fea957992ada816f97cd76168a53ebffae36e5787b0f69e94b3e08eadefe4937ce8b383b5022e57ba7135cccd5b48e38916f1f0bdcbc5858bf93cad75195d4329ab41a518d820262b1b610f7bdbe1d6749d006a0dfe18d0be1a19fb3d8e37795b5bc37ebcd884f91459164cd2536b3496c4b25a4c74282ece5d64ab861184e942cf97f0edbe6e1293c4504d861e60d98c4f6523df27a1e80843005ad21665b3adcf46f349fb0d905d70631d2ee51c0086b252778eac27346eee65c0fc88c6db5936337b0afa7d8cec656612c81e11cc55abf421df770e6c2588c743d5540e1280be76309defaffde2b82c808976c337ee13735a21900a4686423625a0ba4819581edbe574e6d7053c5fd98d288db4104ea64fbc0e7ad11d50eb1470a882aa00ebfd983cdda14db34f7f968ccc93097cf037dceeb1375f2df4de09c8785f5fef8fbbe284566e5c9a2d38f5d2f9145b7f5087f6a89a56679680ca4180ad7da3ee45da685f0255a45db806e1379c1ed59bfe63feb7d74a239334c80ab9c1859d205ba798810adf8afc569170f94167439d137215d2ce0b2fa983ac138a3ce201cec4927c62b740912e7287417f86beb07af9c83fff843df1abd6e6f81865b82b3168528d1c473b4999b0179f1de8ae22e8ed7f698ee8463eb93fcfd4e017f29ab3f15a2e061de6deb09459d4ecc62741ffd8514d5c1f10eb3b1525ad60512ffad00e360e0d6add8ed6d6df48d63cf1e36f306bd76b1a245cdd09951727367e45b3a02d748dbfcbeea342be4cb0e1e3108e57993581409f8c6b34e2d38becfcf15c653b92c88412c087eddb0bc21eeb620317f49a9bf5d6164418a26322e1964fd676a547862c2a7ce5f13898e3fadec79a638f257532cfe977fe8ba5e96782f9e1e3e8b5f896a80d816141f0c988ea59ea321cffd23f298b76e49e92189e7f65718d14091daeb82d432470a2e472a39a154226a43c543db2bb933adad08344259ba08a65c543d2ee07b67328ca2d4e60e550b85215ea5873fedb505cc1e4db49e129249fb632ba22f11b897b9423d08f96ceaa863cd29dc16af6ac76c4388c2795250c04377277626992b085ed7be2cf1d63a2eda4b65e287081fdc4e9a3224ff57d81b3ba8d04eb88430a01c5eba35fad028e8de1812920cee2576d0bd291407c5fb70c5ce07104b9af7b98c4c709c7f019d4a66b136120b92612ad5e73dfcfc1da0fec3a7928e57d7d4769eecbaa4c269f2859d31d47d1ae40e4da5bfa6592074c5bf54b04c707b8d97455a0a606686e06bf5ef7617da2532f305267f61c5f627216b06ecc3da6c6f7b420e2dfecaa41657eab20c89927ad6eb5c4fcd513da89a637755f4a98c45cfa108f37415bbf49ee6cacfda8f22f7101a9798d844709a38f9168685f105157a937bb10d4f5b342deab8b8be8231490da52cc0c407bf942270ad93d4a9bed5c06499584835dbba75577dbbc47fd3d397f0417ade99549de4412c8893cf3e1a2ed74c234a7b60461efad57d9c9fed9eec3ebd652282b045174e19355d8cfcc10add9192ffffd428150dc3f48e0417e47d6407008c62486cd4057535a5a9ffc45ef559a51fbbece64306f64da9740108d0b51d01423379bb0a72fe050d2abf5f5acd25cff57f8e3bcdf938749c7bbf77437424ada88c167bcb6addc309b949a8e200b9a5b6797522635731b250e2405f98d054aaff4179ccb4b24159e4c033329100cadbef3da262203622d27899166f6c3c79a35daf7840853b9a3ce494bf035235cada8c31e28be56f0976ef9b96f15de57e6896a5aed57a7b5ce77cacd1c806ecf83566bee5d577f7414a106ce16ca6e8cbc144f571b1a37647041694a6409f68d15604960417a60bc4f1a878eb01e89159e701bb8fd96be45395a8b8c4f0cc5b982582741c4ccaff8961ea892f084b10646c7a27687a2d3c92324cc3a19a5b38ca2d5c573167ad54486ab3adfe9219882f947cc6a93a3827f4b51d76e90ffd1587646d921482022db8b5a22519be3a1e62e9a13ff9926e75c42e07aa295c8486df69dc96168e920e13c85eeda86dc560b9f5d4c77cb8ff001d390dc6c5a911c573ab1711df534930ef28832936c80cafcde731e999ce90741e669d93f653efba12466726fa997e7ad24d34395a02b8a4286f3604f120bf47e8ec41954e6def2de896be477ef7916f18214d28f58ae91ed8d7eae9e2df600d313b6cdb952195e9d030e0b8fc98a68cced3070f4abd2d252727320eb54b602ec861ba630ed3c5d6fc8c8b39f4f1e9c198a6dc8d5f825159ce15fcd7bea5701a225ac41bb152d1a077adc03ecf06870375f2d2618094a648b40244e4a981e7efeadc608c082dc1824c4ffdbc39afcc8c464ed5ca8dfc1540ae3a6c034364c356bf13f880abe8633fa041db78f4be0d17a4bb00959a697935c844c6ddc02222f7aebb1af2c96a757536159dc1dbc31131aefe4c198ccd2123eb5d0ca6147bbc9ab43e993508ef4ca383e2847d9fcb4c975dcb240bcfd164daa835311cf7dbde0f256deb5f3748b55c312a29a042725ecf07caa904513e71b4c0ebd3b31c2938e710e7c6be819bb3125e638ee4b54b4c8fe16df1cee7587e6bdfdcccf2e3b2aa4a54c86b0ae711f056c229c644f519f60570aed60fd3d0638dc341625fb4949d355e7d84cb478133d25730162623acbf5d36b9ed98dbd88b6bf7bf1f55006f5ba2d16297557f966cc01baca56e3f6435b724c0b6fa4cc0074efb0bb2cf0cba9a1c73d3337db7dc0c78b87746db7bbe5fc003edf608ce5d91dbd8b3cec0f738de14c8e2b6df47df91805eab5635402ff26245430641abd9511cffa6bf8d352a1f0d97ce2b08561c97a5f07a07e0ac42a2a73366442e0bf125a718553794b021640ef9f9f07040068cce2337606af46f897b7ad8ced05e14f7ab3e2bd847f810058d665a0c3b6903efd8f398c31e356b48216111d30348acf93d28dbec8e603cd16ea5d3b24f38367c52f5629fd51bec34e86ff21d4f5466a53aea7048babf3afaecec2c9de099bcb2845f66689e02306760ef5274e65f36fc61edf8112b3b414a878b8dbdc2ced0d7dae0e95c5d6e7c80a3b4cbccfe13293e454b6c757a8d9496999fb0c4d4dfe5e7f3f40e11172324323556687e95a4a6bfc4dadbec000000000000000000000000000000101a2f41",
|
||
+ "hash": "0x5ee00afa7d595efaffab2cf573a82e50c7d0f37bc1c2a53a11f7120155bf57b6",
|
||
+ "intrinsicGasEstimate": "135712"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-2.json b/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-2.json
|
||
new file mode 100755
|
||
index 000000000..3a93c378b
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-2.json
|
||
@@ -0,0 +1,28 @@
|
||
+{
|
||
+ "id": "valid-ml-dsa-2",
|
||
+ "expect": "valid",
|
||
+ "alg": 2,
|
||
+ "chainId": 28001,
|
||
+ "publicKey": "0x5424000ae9a496294dd6b99046cfdbb235ae71031b379ce274c13b0c96411740cb61021a5390fbe8fb56b642b4e5e5abb7aeab143e0037f8db283b9f2febd650265ed6b05f1b867c124aef245c1811422f92414447fd0b20844e0f1b1cb4eec052400aad52b9d773aae0015c0c390bfdde3d367bd8ef9c3c73bca3164b9d418ecbb2d25303bbd12739a858c5fac4cbfa0203b9f3c319e9bc89d17a7a244b57d6613b5caabdb528f077eff9727015b9c266d777c0ba11920118c7ec4dd59b380c40e361a5b23ce04be4c61e12a1c21e091fa0d890687cbf588944db3e34253c75cdf797378de79162e0b4ca309f550365a289f652dd6d559478912cff70a5417589f73f14640970694d7b5a6bd8f000a65c632f0326ed3d128fda96dbea68cb812634dd75e9f63813a5645336681378b6a63220c066550aba43a5b937131d41f08752d13949a115a74bf96fa1925ff4338e10df0301abe40aaa49e14a1a1d58eef005a0f1d0299267002cebeda20cadcea7419cd0c365c53aede1aa36efaf764d3d36169747cdc8ee9a09e0a0ac6bcaeaeded0cd303c965d705d1b91a8b35f408ad8a033b02ff57610bddbfa60e2114e53f20f8fcad15dffac6a494c3f4f631590f2be3422af14cba7c900c9c38796952e20c3069bea2ab54bf0edf9315903aa5cf68549f878eafcc77561b36f8b78d950871ed4914417316f868a2bc54c72d3c9929f0138a2f0cbccb7c4141e94bb8a7ae11f660861cbbe498697d7327709271460a75bd4e024de3d4d6fe5af066944c96ba87459fa948a95eeb61abbaf643190ccaa9cd18591eb6f249a6eb92db89fc95616d21b41d7d15424b80a750938a12cd57d50ef95aaf222025dc4d81df320d9bc32c608b1c5a1aac8bd14c0f7a4c4380cdd65c793a6287050ff4d609102fd91e47e7365fb55513aeca273618528c199f7bb151e9c11a0bf202147734d1be9d5d0e9318096fa567317ed9fa6a8efe201b915b9aa05ca0d19e15c9a80449cc130b398ebbac3d938f55eea8f74e024b0e33dfecdbea02b920ddc5b277146685916194bfa1f8ac7784c7ed76923d4ff9ed97d3ceac283f9b26977df0133c5fa4fb5fcec577bc152e926529f06ff50c204c083c0b4d6b8d474cf5cf7cfcf7acf76921225443eb0abf5e4c76d0a3f524243ee4e372e80ff0f76dd9d135f240114a2ebe6d69609b6c60d275f251d7dceadc600d18e0cf8bc8fa8392e61fa32b8f7481c4883e19d820b51af0f87d3f7faae44e3b908fc759c6de59361487d8e424ffbd662d57a68801110e9cb099214143253949cc479eaae0e321fecab90c63b06819ce3cf56fc2fc1419408075c658024a28950aa47d549bcdb8b5bc9aeab463466c7834ca7d73058c206a95a023f0c8ac95badd383e63041e1f0ef69f51634f5ce2f48d80f8f2e92f4a1fb5322930141fc50e1e20bd235a8b8d768d473b46711257d028e710f82f0b6bd923da05ca64ae805f708577e125b3fca2feb5656f61ded034eaae481a195628801c82db85345f9ffdc72c860cffe2264ba4be2a08fdb37a4f5f80276baba4ea637847335c89dbd35504389f68b2d61ea66d4eac5fd0057d9e757d929214a7d83daf2fc2b3f840e083792d20d772584b252ba955ae8ae8c36af648c59ae0b25d3bca19413fbd749077b6969db5847409d13e4a67387e59116fe3836a733f3253d47f9919f49618fac8edf5fd711a4239447655d6c40f479f86ef3c9d4dc1a6f9683a3f1bc5c9730025e76ea1588d43494f59823f42c207e34412f73c7e2a126501b8fb810f12995c213063d909a5a9c2653d3511ceb809efa69c638f4c977d46a2a305cc831ecc0feebf5d9356ede6c780da78fe2ad683b3312282d5142612c0d1f85108de04de5c3d5414b62826d5b75f8887dc2d932c40f306c08e5d4f69ef4d344fe4317552df9890d0961e3d857bd9b2c5b44536d8606f62f66d14ddd43b0e5d3379cf66d664616df12b1c62385a57f6a562c34e120b79d64ca39d8b23e1e07b2c03910d711f09df5b54cb0e133dd751bea7832fdb38de2f1dafae69fbdf82b6887ff0a92940299020a835b958bb01b25b8699a0846614cb256a6621ef92e4a0947df9141ed4f91eca527aef25862158a8fa712dd60dda947f6a16e077810e29542a56f9244c34a73454b9ad0d8e8c40bd503efe12c4e5bf7d0ff8e6ab642a039f4e8b575d33c0c3de77a1abfa60b0252d7a549dd791d9630c8b848988157608448d77938bfb27beaea8f9b4a259263797c5b2fbdc7f469b2769f7dcb7b9478cdf5f109322eb2f0a83163469b72d8121fe8e01df227563cbd941a1f63961e2a010c6322a812a014279583a0066492a17d1a15c07024f6b8b1561041b3db608ec1c7475ce4d086e60523e85d7a955841558a35535d6e52cb166669a69049646b94d2fdb901ffbb1446a2d7f58696bce000ccbbb6942b0ad6480d006602c228218d3a2f0bc6a5d5c73acda9fc4b0b496a7d527050f8d77b71641f030368e9494bfe8e9dbf6dd4040426da1b0423739b40450273f4a8d551637e5fe3ca8d54fc476e6278e75cebf4a4ac3ac8ef3807041c4b274568797c8caaffae7df08c6c158d92411db981ea02cc212064c3ad6a9cd1cc02087acce5ceb8d7cddaec429d199c3d90670288be6e88e6826d1f6c417df5f35139c71a62c0267adfce7cb3aa49e827165b28c8cc157a691cb52ef103d8d7ca0ebfc628904d0b2d365dd3401b620d6d93cef670e2f",
|
||
+ "seed": "0xdaaaf3ca4a40b10b8d8329296d5a0eb0ea604486c8bb582e6d7cd3d7f7dacc63",
|
||
+ "tx": {
|
||
+ "alg": 2,
|
||
+ "publicKey": "0x5424000ae9a496294dd6b99046cfdbb235ae71031b379ce274c13b0c96411740cb61021a5390fbe8fb56b642b4e5e5abb7aeab143e0037f8db283b9f2febd650265ed6b05f1b867c124aef245c1811422f92414447fd0b20844e0f1b1cb4eec052400aad52b9d773aae0015c0c390bfdde3d367bd8ef9c3c73bca3164b9d418ecbb2d25303bbd12739a858c5fac4cbfa0203b9f3c319e9bc89d17a7a244b57d6613b5caabdb528f077eff9727015b9c266d777c0ba11920118c7ec4dd59b380c40e361a5b23ce04be4c61e12a1c21e091fa0d890687cbf588944db3e34253c75cdf797378de79162e0b4ca309f550365a289f652dd6d559478912cff70a5417589f73f14640970694d7b5a6bd8f000a65c632f0326ed3d128fda96dbea68cb812634dd75e9f63813a5645336681378b6a63220c066550aba43a5b937131d41f08752d13949a115a74bf96fa1925ff4338e10df0301abe40aaa49e14a1a1d58eef005a0f1d0299267002cebeda20cadcea7419cd0c365c53aede1aa36efaf764d3d36169747cdc8ee9a09e0a0ac6bcaeaeded0cd303c965d705d1b91a8b35f408ad8a033b02ff57610bddbfa60e2114e53f20f8fcad15dffac6a494c3f4f631590f2be3422af14cba7c900c9c38796952e20c3069bea2ab54bf0edf9315903aa5cf68549f878eafcc77561b36f8b78d950871ed4914417316f868a2bc54c72d3c9929f0138a2f0cbccb7c4141e94bb8a7ae11f660861cbbe498697d7327709271460a75bd4e024de3d4d6fe5af066944c96ba87459fa948a95eeb61abbaf643190ccaa9cd18591eb6f249a6eb92db89fc95616d21b41d7d15424b80a750938a12cd57d50ef95aaf222025dc4d81df320d9bc32c608b1c5a1aac8bd14c0f7a4c4380cdd65c793a6287050ff4d609102fd91e47e7365fb55513aeca273618528c199f7bb151e9c11a0bf202147734d1be9d5d0e9318096fa567317ed9fa6a8efe201b915b9aa05ca0d19e15c9a80449cc130b398ebbac3d938f55eea8f74e024b0e33dfecdbea02b920ddc5b277146685916194bfa1f8ac7784c7ed76923d4ff9ed97d3ceac283f9b26977df0133c5fa4fb5fcec577bc152e926529f06ff50c204c083c0b4d6b8d474cf5cf7cfcf7acf76921225443eb0abf5e4c76d0a3f524243ee4e372e80ff0f76dd9d135f240114a2ebe6d69609b6c60d275f251d7dceadc600d18e0cf8bc8fa8392e61fa32b8f7481c4883e19d820b51af0f87d3f7faae44e3b908fc759c6de59361487d8e424ffbd662d57a68801110e9cb099214143253949cc479eaae0e321fecab90c63b06819ce3cf56fc2fc1419408075c658024a28950aa47d549bcdb8b5bc9aeab463466c7834ca7d73058c206a95a023f0c8ac95badd383e63041e1f0ef69f51634f5ce2f48d80f8f2e92f4a1fb5322930141fc50e1e20bd235a8b8d768d473b46711257d028e710f82f0b6bd923da05ca64ae805f708577e125b3fca2feb5656f61ded034eaae481a195628801c82db85345f9ffdc72c860cffe2264ba4be2a08fdb37a4f5f80276baba4ea637847335c89dbd35504389f68b2d61ea66d4eac5fd0057d9e757d929214a7d83daf2fc2b3f840e083792d20d772584b252ba955ae8ae8c36af648c59ae0b25d3bca19413fbd749077b6969db5847409d13e4a67387e59116fe3836a733f3253d47f9919f49618fac8edf5fd711a4239447655d6c40f479f86ef3c9d4dc1a6f9683a3f1bc5c9730025e76ea1588d43494f59823f42c207e34412f73c7e2a126501b8fb810f12995c213063d909a5a9c2653d3511ceb809efa69c638f4c977d46a2a305cc831ecc0feebf5d9356ede6c780da78fe2ad683b3312282d5142612c0d1f85108de04de5c3d5414b62826d5b75f8887dc2d932c40f306c08e5d4f69ef4d344fe4317552df9890d0961e3d857bd9b2c5b44536d8606f62f66d14ddd43b0e5d3379cf66d664616df12b1c62385a57f6a562c34e120b79d64ca39d8b23e1e07b2c03910d711f09df5b54cb0e133dd751bea7832fdb38de2f1dafae69fbdf82b6887ff0a92940299020a835b958bb01b25b8699a0846614cb256a6621ef92e4a0947df9141ed4f91eca527aef25862158a8fa712dd60dda947f6a16e077810e29542a56f9244c34a73454b9ad0d8e8c40bd503efe12c4e5bf7d0ff8e6ab642a039f4e8b575d33c0c3de77a1abfa60b0252d7a549dd791d9630c8b848988157608448d77938bfb27beaea8f9b4a259263797c5b2fbdc7f469b2769f7dcb7b9478cdf5f109322eb2f0a83163469b72d8121fe8e01df227563cbd941a1f63961e2a010c6322a812a014279583a0066492a17d1a15c07024f6b8b1561041b3db608ec1c7475ce4d086e60523e85d7a955841558a35535d6e52cb166669a69049646b94d2fdb901ffbb1446a2d7f58696bce000ccbbb6942b0ad6480d006602c228218d3a2f0bc6a5d5c73acda9fc4b0b496a7d527050f8d77b71641f030368e9494bfe8e9dbf6dd4040426da1b0423739b40450273f4a8d551637e5fe3ca8d54fc476e6278e75cebf4a4ac3ac8ef3807041c4b274568797c8caaffae7df08c6c158d92411db981ea02cc212064c3ad6a9cd1cc02087acce5ceb8d7cddaec429d199c3d90670288be6e88e6826d1f6c417df5f35139c71a62c0267adfce7cb3aa49e827165b28c8cc157a691cb52ef103d8d7ca0ebfc628904d0b2d365dd3401b620d6d93cef670e2f",
|
||
+ "chainId": 28001,
|
||
+ "nonce": 0,
|
||
+ "maxPriorityFeePerGas": "1000000000",
|
||
+ "maxFeePerGas": "2000000000",
|
||
+ "to": "0x0000000000000000000000000000000000000001",
|
||
+ "value": "1",
|
||
+ "data": "0x",
|
||
+ "accessList": []
|
||
+ },
|
||
+ "algName": "ML-DSA-65",
|
||
+ "sender": "0x0602be26ec9e01dd88121f7c203ead9eecb9ad3e",
|
||
+ "signingPreimage": "0x50f907ce826d6180843b9aca008477359400830383209400000000000000000000000000000000000000010180c002b907a05424000ae9a496294dd6b99046cfdbb235ae71031b379ce274c13b0c96411740cb61021a5390fbe8fb56b642b4e5e5abb7aeab143e0037f8db283b9f2febd650265ed6b05f1b867c124aef245c1811422f92414447fd0b20844e0f1b1cb4eec052400aad52b9d773aae0015c0c390bfdde3d367bd8ef9c3c73bca3164b9d418ecbb2d25303bbd12739a858c5fac4cbfa0203b9f3c319e9bc89d17a7a244b57d6613b5caabdb528f077eff9727015b9c266d777c0ba11920118c7ec4dd59b380c40e361a5b23ce04be4c61e12a1c21e091fa0d890687cbf588944db3e34253c75cdf797378de79162e0b4ca309f550365a289f652dd6d559478912cff70a5417589f73f14640970694d7b5a6bd8f000a65c632f0326ed3d128fda96dbea68cb812634dd75e9f63813a5645336681378b6a63220c066550aba43a5b937131d41f08752d13949a115a74bf96fa1925ff4338e10df0301abe40aaa49e14a1a1d58eef005a0f1d0299267002cebeda20cadcea7419cd0c365c53aede1aa36efaf764d3d36169747cdc8ee9a09e0a0ac6bcaeaeded0cd303c965d705d1b91a8b35f408ad8a033b02ff57610bddbfa60e2114e53f20f8fcad15dffac6a494c3f4f631590f2be3422af14cba7c900c9c38796952e20c3069bea2ab54bf0edf9315903aa5cf68549f878eafcc77561b36f8b78d950871ed4914417316f868a2bc54c72d3c9929f0138a2f0cbccb7c4141e94bb8a7ae11f660861cbbe498697d7327709271460a75bd4e024de3d4d6fe5af066944c96ba87459fa948a95eeb61abbaf643190ccaa9cd18591eb6f249a6eb92db89fc95616d21b41d7d15424b80a750938a12cd57d50ef95aaf222025dc4d81df320d9bc32c608b1c5a1aac8bd14c0f7a4c4380cdd65c793a6287050ff4d609102fd91e47e7365fb55513aeca273618528c199f7bb151e9c11a0bf202147734d1be9d5d0e9318096fa567317ed9fa6a8efe201b915b9aa05ca0d19e15c9a80449cc130b398ebbac3d938f55eea8f74e024b0e33dfecdbea02b920ddc5b277146685916194bfa1f8ac7784c7ed76923d4ff9ed97d3ceac283f9b26977df0133c5fa4fb5fcec577bc152e926529f06ff50c204c083c0b4d6b8d474cf5cf7cfcf7acf76921225443eb0abf5e4c76d0a3f524243ee4e372e80ff0f76dd9d135f240114a2ebe6d69609b6c60d275f251d7dceadc600d18e0cf8bc8fa8392e61fa32b8f7481c4883e19d820b51af0f87d3f7faae44e3b908fc759c6de59361487d8e424ffbd662d57a68801110e9cb099214143253949cc479eaae0e321fecab90c63b06819ce3cf56fc2fc1419408075c658024a28950aa47d549bcdb8b5bc9aeab463466c7834ca7d73058c206a95a023f0c8ac95badd383e63041e1f0ef69f51634f5ce2f48d80f8f2e92f4a1fb5322930141fc50e1e20bd235a8b8d768d473b46711257d028e710f82f0b6bd923da05ca64ae805f708577e125b3fca2feb5656f61ded034eaae481a195628801c82db85345f9ffdc72c860cffe2264ba4be2a08fdb37a4f5f80276baba4ea637847335c89dbd35504389f68b2d61ea66d4eac5fd0057d9e757d929214a7d83daf2fc2b3f840e083792d20d772584b252ba955ae8ae8c36af648c59ae0b25d3bca19413fbd749077b6969db5847409d13e4a67387e59116fe3836a733f3253d47f9919f49618fac8edf5fd711a4239447655d6c40f479f86ef3c9d4dc1a6f9683a3f1bc5c9730025e76ea1588d43494f59823f42c207e34412f73c7e2a126501b8fb810f12995c213063d909a5a9c2653d3511ceb809efa69c638f4c977d46a2a305cc831ecc0feebf5d9356ede6c780da78fe2ad683b3312282d5142612c0d1f85108de04de5c3d5414b62826d5b75f8887dc2d932c40f306c08e5d4f69ef4d344fe4317552df9890d0961e3d857bd9b2c5b44536d8606f62f66d14ddd43b0e5d3379cf66d664616df12b1c62385a57f6a562c34e120b79d64ca39d8b23e1e07b2c03910d711f09df5b54cb0e133dd751bea7832fdb38de2f1dafae69fbdf82b6887ff0a92940299020a835b958bb01b25b8699a0846614cb256a6621ef92e4a0947df9141ed4f91eca527aef25862158a8fa712dd60dda947f6a16e077810e29542a56f9244c34a73454b9ad0d8e8c40bd503efe12c4e5bf7d0ff8e6ab642a039f4e8b575d33c0c3de77a1abfa60b0252d7a549dd791d9630c8b848988157608448d77938bfb27beaea8f9b4a259263797c5b2fbdc7f469b2769f7dcb7b9478cdf5f109322eb2f0a83163469b72d8121fe8e01df227563cbd941a1f63961e2a010c6322a812a014279583a0066492a17d1a15c07024f6b8b1561041b3db608ec1c7475ce4d086e60523e85d7a955841558a35535d6e52cb166669a69049646b94d2fdb901ffbb1446a2d7f58696bce000ccbbb6942b0ad6480d006602c228218d3a2f0bc6a5d5c73acda9fc4b0b496a7d527050f8d77b71641f030368e9494bfe8e9dbf6dd4040426da1b0423739b40450273f4a8d551637e5fe3ca8d54fc476e6278e75cebf4a4ac3ac8ef3807041c4b274568797c8caaffae7df08c6c158d92411db981ea02cc212064c3ad6a9cd1cc02087acce5ceb8d7cddaec429d199c3d90670288be6e88e6826d1f6c417df5f35139c71a62c0267adfce7cb3aa49e827165b28c8cc157a691cb52ef103d8d7ca0ebfc628904d0b2d365dd3401b620d6d93cef670e2f",
|
||
+ "signingHash": "0xce8c919ee46badc976518a728e7720c6afe65322bb25ff83a28c364c7ba1999e",
|
||
+ "signature": "0x33fc1486a0e70aeb6fef62ce5a0dfb51fcec12164e4024b0c49ce8b65e01356d80a9571af8f69a9c7256ed549d699a31ceff21c13c482ee0c5759f96125b0099495feacf22a001b2c887b107a9ca9e84de461fbc6e143566de56c710156de5b5f4b7ffe29c0124c1fbb6a792110284c9ad713d89bbb5ed444d09408c65a9f74c5f6c4fd281d31738db82913dcd1ac1fccbba24dc933fb9a8e6c4e426fb98590d7da0252c34d866c114526ded1c9d96daea12ecbd8f2a44531dfb72f02c02b267edf0560b1fb06b087bb6ce02b2922d92f81bb7da99b90e4a2dd68aa858759584490be602369dd606a510b6228e3b941421a3006a697b79866cae011d8aa496de4f3bfffdc0a087d01323db849f6237d7ac476d18bb417f26a697388b4c0a78533f3dd763398719c9ee5bf0299786fb8c4143af8c1195103390d4494b735c06b5815c454dba2fcdd27d214c48712609ffe7ad7c082e835d7477de2358fb3c4b5162027f816ca85aa4a46c25105175e77c8e5394db6fb3999c25ce578f066329182b28fd5b68769cb07ebc67e47a537f6cb62bfd18af162113a4df7f8908e0ce953b6a9637c850f24de0fda239c25fe4352f3b381fc270384d51d1af1ef0dea8501f98ea71f26de97e98799c4b2a316a216bd4af4861ad83fa4570532029564581bb35ac543355ba3aa246b59c6a5d9a91b938f3c4f0ad6d6f567fffdb6fb78402ded5fdc544a0f5fd87e4677326ca003dffdba8fd390487a6469991506a18f376b12db5be3bdcf4a4bc2f5b34dd8f7066bec3b40a6502f414eac3cd1ed43431b033757e86cca57691b0e1f7eec68fad9423f8b0620aa94798546bc878cf29d74ae74af5244ed9b97107fb83abe25dc160ec05cda1c50b76db981aca781868a7913a3e7c98aa5a3ea8bc81270e6f565138dba33c9c7e887641fd3dafd458b9c64600151038db05725a976950307c662c2eb668e3067f943b9bfd805307729b39ed77309fd5e67ecfc56cc231057a6628fb6f528fb969378529dea2c58fa0b4d791ca591ced733e8cf93a8e19907538f45c2618612648d3e1a78492afc154b7bb0285aea97d618e74a74530b492c66c6bd31557cdc55476b3f163196ec8e87f110834ffb8c232dc77cbf2f7b490f520b3b328af44fecca860a19bee9af6a5f69f63487d7dc6b7bf1233c4735522fedd475f905f044a0a7f658a7a378958cca56a163a343a010f4b65d1bc38cd57d08e0f887293fbc106ad7b15aacca6d51558cb8478b119acde04a19b007802a8e9578121304622aee7858d1794ade88973d6fdf981ebabc98fc417d765c075bf8f76b9781dff7c60071878027c057aade8eaf820186035499e9e5fbf8791e6fc0a0e49047af312a8b1b1e80628dc4db4f45842e19096a54733d28028203aa668bd8655631a01c000c956c32ff10572fdbc95b2f26d09fca84c093ddaa122ad93598c03de9273873ece5096648a6251a27e993ec7b6ea4f2181c09bb06852799323f3e993a4b7461439f702cb9df183fcaab11b8bd2ad391924d5e6ef261fea01c91cdc10d9345c290dfc3c040318d11419563d407c8365fef3dd31d8f9d7d338f5f2cd00433d1d06547ae9c650d14d9a7e5b683f0458e7a909d90d4a57201ca5b8753c13bda3591f9cadffd0987d1c7fca1c5a0cec1e13c612d0390d7c0e2f422c97cda29959cd7b714fbeaa5da7b0bcf911c2744a9a25c7d49e93342f61e10a33fda80fadfed2668bfab8767ce80480093b4845cd5ec83082e8f9ad63236743e72842d1a3226640a549c2c1d002a176e2427b2ae612dc272e3d9fa80a904eb8f93f494a52706346c08b06c9d1d8a61a9c7112c0933910882f0da6eea3c389f4faeea51c03394eab4cc02056d704b8839afd76f0839be5ffdc873b88f9a755be6f0229b0843839a25d63c18da89be1c5da930a101913ffba01fd00f2a447d5f58ae8f21554feb47f42d40c32158219dbbb1e5e96ab3dc26cd6a435525c265b65b0bf48d68e9b3c9178a509833aa47c23e63aa9a6f74bef1e4ef863556b11c014b85ac7c157f1e64531b676eb28c68e82e0089d2bd798213c836cc354d4883dc0b607456ab7f894f0a1f73356fc05a5c97a9cf3b231890c39105b751f6fc54063a08f3d3a264ab90cb7de1d0e2f6acb92302cc9b4bb512e720e6ff8343004028ad223a70d395c5f974d3ddd380f798e80edb4b13555c3be0cb1a500e19a8b1b05f9cae85d7eed756ebcfa57828f1054296ffa48d426ceb83c69ebe1b983421f42316ca6f50bf8df0f4d4aeef85005638a304d88764ec26366a1437867c89800aee55ba428e0c07542e123d748c795560153007f768b20bb057fc2643b7db992c3b9cbfd88657b17fbe8a783da2050affb518cab4226cdf28fa97f48651bd142932835f061f8642e79d1f7ae8ff8665aa85aba24a850b2042dd37e61e665a451f17cbe9d57ed5ecb1dce9ec34c576762929dbf46964de7c44c9f6b10fcf52b48649ded2d491bbe4bb6ad578cd31cbdea6df8342dbb7f33857617250b014fc6d887a448f7a5cef25ff69dbc94733bfac1d5f8593af7fbe4759d23ba8da1f405ba179c96d8ae49eb760446d842f0d61ab08508a3e31e4953e13a1b197d00644303e8a9513199583709f41757740a0dff347c3859d3a4ec391481af349019f75ccfdba111a4c338fd8283733115ce7c114111abb157c1a5a84f7b39779a54f000827a250bff00dbe9cb7162d81f6c942b719f9eb973ac7d4652b911622396c517c6e9c7e5f839c049855567fb53ae84579388e3c87af420272558c686209fd92fc339a553f873995932d9dce52f5e60cc0889c3283f94a0d2d5d011154d9935e1dfbb7e747b393bdd8a84f601adca56d4ac5e8e6f28100a7d5522de50dbf1bd7f5604fdfa660a58dc681b4b230abbc4f594a972a73456de1b7f48975cd03313a80074f5d6701db61860f33dfcc9f06e313e8881c385a50de28ced014daf702f01c45368419b73383008b9191293f59fa87a1ceb0cee64d486842ed7c289dca3b3f2e261df644de0f739079ba5ea195468f0693a995dae8e0f7e4611196824f329fc803bc3588d7d941d1fe86a3ecdb3eb8f6d4066ecee371f9a14e5bd46a40b53e87325bab7255099b4fe7f7b09eddaefc6582feecb8dec02b5e58d735a927d052e263027fa879fceb852b9e08db4636c7152f272a43ae4037c50210e90caa3e008fbfa98ed42cd425259096fc06644edab9b768779dcd892747f18a9cecc6aa31dc27d3f12a540447653edd5bed68f50da71b7992434b74d0209746f93ea429691fcb99da0ca32df822ec4332f7eb4bbe6d2111ac84a55932b3e173e388ab96a5a8a17c7d8b8131cf566e0335b0c4a37c5ae24e73c81146031295b69ce3032fa8e4c7616558179cc561f14864190d458cb82370749d595966047de698256126a4ca23a6bbd39201b8649fbcd387474ecf5b9f732e65938fe393a2a1269b06b9b49c5d8882d70776fc823da5842d812be2a65d2f5ee0d64f8258e761e6f2d4c1a825963b367d70b9e81b46fc25e4804fe9decf3aa0e47f1eba573a24f0e4f7b8cf8a886c7ef4175bd317709feeabe46df9719e7d7a4bc2c1bbc15a58b5332ea558e160f5d3b7aa84fe54ea7a24bd8e394ab794e72db7946780272556be33b7f32a0ee651c013d8ed3b5d75bc1c4826dc94f9e3711c53be3bcdf361329544f2993a189b6431a6dda8b81cb1b7c3a69ba96c1ac84a55100c4985cc85ce272e8eb5a57c563a7ad782664d561c3400e779317122d425c9c4193414bebd4d6ad31ba916448f65e9a7ca1f856dacf9d88b695410c8491a759d2c0304e8368b39cf502d0abf7233b1ba9671bc422ce182833ead52597481ea3ea26a2cc35e12a8c83bbb263202d5e9e7a5bb8ab2a5a844d596c24fdac423981fc4dc4291944ae476d59c9a31a05f79f0fe4b39f145c4fba857fa553a17fb2d5f941d5dac8dd3dd07e48eabfe5b98f3c41e7a84986dc3a7a3bb0ed2d4232cffbc50f167d58fb52fa3b357e76430d7f0f1aff6e2d51ea8f5b98bb66c5b5687821f33b9b6c2e407ad0e8140c4d5d4f1739167f8d63284caf4a43688473cd97bab401218fbb2ea13be81bbc05a81042a02eb1843bd46ca535e778e207c79ce3fe511a55d21bf20b24bcdfb43fa62b3469fae2ebd61e362d5d663fb2c08cbde5df9d8cc1faaf6370b5328ffccde873849299d61477a9fcf7c5c96fbc51b24c0f2cc6e39a46f4a9c1f5214f2cd06db62a37e2c6f477ceac0b92eb882d7bcd1fc3721a89745473eb45eee9a4fe6ab323d28f4db957d0c5dc1ed25ebc194f744a2cfe98474868e6acf5641ad454b3626ac2a27a9db416eb1763935eaa5612e43c49e8959ebcf5133863e98c19618e936f33952699fc224f41a4e259b40228047ed6a17cf4f3a42dc76df1346acb0986984f1692b5ed28f0825a23094ddbb8c1750e9035b1df2166f142e7f179473098ed73acb9ffb8be530542f31de88d6677f805cc30ccc0b60787e61f9d195ceacf07a35d979f9c3521f23671f378a6cd58ed2b0620ff7e2def5025f878d70008744c6a53caf325293353747c94c5ddf12e3a42686f97adc4db62b5e2e91132345963b7292fc9d13b484f75d8da000000000000000000000000000000000a13171d2127",
|
||
+ "raw": "0x50f914be826d6180843b9aca008477359400830383209400000000000000000000000000000000000000010180c002b907a05424000ae9a496294dd6b99046cfdbb235ae71031b379ce274c13b0c96411740cb61021a5390fbe8fb56b642b4e5e5abb7aeab143e0037f8db283b9f2febd650265ed6b05f1b867c124aef245c1811422f92414447fd0b20844e0f1b1cb4eec052400aad52b9d773aae0015c0c390bfdde3d367bd8ef9c3c73bca3164b9d418ecbb2d25303bbd12739a858c5fac4cbfa0203b9f3c319e9bc89d17a7a244b57d6613b5caabdb528f077eff9727015b9c266d777c0ba11920118c7ec4dd59b380c40e361a5b23ce04be4c61e12a1c21e091fa0d890687cbf588944db3e34253c75cdf797378de79162e0b4ca309f550365a289f652dd6d559478912cff70a5417589f73f14640970694d7b5a6bd8f000a65c632f0326ed3d128fda96dbea68cb812634dd75e9f63813a5645336681378b6a63220c066550aba43a5b937131d41f08752d13949a115a74bf96fa1925ff4338e10df0301abe40aaa49e14a1a1d58eef005a0f1d0299267002cebeda20cadcea7419cd0c365c53aede1aa36efaf764d3d36169747cdc8ee9a09e0a0ac6bcaeaeded0cd303c965d705d1b91a8b35f408ad8a033b02ff57610bddbfa60e2114e53f20f8fcad15dffac6a494c3f4f631590f2be3422af14cba7c900c9c38796952e20c3069bea2ab54bf0edf9315903aa5cf68549f878eafcc77561b36f8b78d950871ed4914417316f868a2bc54c72d3c9929f0138a2f0cbccb7c4141e94bb8a7ae11f660861cbbe498697d7327709271460a75bd4e024de3d4d6fe5af066944c96ba87459fa948a95eeb61abbaf643190ccaa9cd18591eb6f249a6eb92db89fc95616d21b41d7d15424b80a750938a12cd57d50ef95aaf222025dc4d81df320d9bc32c608b1c5a1aac8bd14c0f7a4c4380cdd65c793a6287050ff4d609102fd91e47e7365fb55513aeca273618528c199f7bb151e9c11a0bf202147734d1be9d5d0e9318096fa567317ed9fa6a8efe201b915b9aa05ca0d19e15c9a80449cc130b398ebbac3d938f55eea8f74e024b0e33dfecdbea02b920ddc5b277146685916194bfa1f8ac7784c7ed76923d4ff9ed97d3ceac283f9b26977df0133c5fa4fb5fcec577bc152e926529f06ff50c204c083c0b4d6b8d474cf5cf7cfcf7acf76921225443eb0abf5e4c76d0a3f524243ee4e372e80ff0f76dd9d135f240114a2ebe6d69609b6c60d275f251d7dceadc600d18e0cf8bc8fa8392e61fa32b8f7481c4883e19d820b51af0f87d3f7faae44e3b908fc759c6de59361487d8e424ffbd662d57a68801110e9cb099214143253949cc479eaae0e321fecab90c63b06819ce3cf56fc2fc1419408075c658024a28950aa47d549bcdb8b5bc9aeab463466c7834ca7d73058c206a95a023f0c8ac95badd383e63041e1f0ef69f51634f5ce2f48d80f8f2e92f4a1fb5322930141fc50e1e20bd235a8b8d768d473b46711257d028e710f82f0b6bd923da05ca64ae805f708577e125b3fca2feb5656f61ded034eaae481a195628801c82db85345f9ffdc72c860cffe2264ba4be2a08fdb37a4f5f80276baba4ea637847335c89dbd35504389f68b2d61ea66d4eac5fd0057d9e757d929214a7d83daf2fc2b3f840e083792d20d772584b252ba955ae8ae8c36af648c59ae0b25d3bca19413fbd749077b6969db5847409d13e4a67387e59116fe3836a733f3253d47f9919f49618fac8edf5fd711a4239447655d6c40f479f86ef3c9d4dc1a6f9683a3f1bc5c9730025e76ea1588d43494f59823f42c207e34412f73c7e2a126501b8fb810f12995c213063d909a5a9c2653d3511ceb809efa69c638f4c977d46a2a305cc831ecc0feebf5d9356ede6c780da78fe2ad683b3312282d5142612c0d1f85108de04de5c3d5414b62826d5b75f8887dc2d932c40f306c08e5d4f69ef4d344fe4317552df9890d0961e3d857bd9b2c5b44536d8606f62f66d14ddd43b0e5d3379cf66d664616df12b1c62385a57f6a562c34e120b79d64ca39d8b23e1e07b2c03910d711f09df5b54cb0e133dd751bea7832fdb38de2f1dafae69fbdf82b6887ff0a92940299020a835b958bb01b25b8699a0846614cb256a6621ef92e4a0947df9141ed4f91eca527aef25862158a8fa712dd60dda947f6a16e077810e29542a56f9244c34a73454b9ad0d8e8c40bd503efe12c4e5bf7d0ff8e6ab642a039f4e8b575d33c0c3de77a1abfa60b0252d7a549dd791d9630c8b848988157608448d77938bfb27beaea8f9b4a259263797c5b2fbdc7f469b2769f7dcb7b9478cdf5f109322eb2f0a83163469b72d8121fe8e01df227563cbd941a1f63961e2a010c6322a812a014279583a0066492a17d1a15c07024f6b8b1561041b3db608ec1c7475ce4d086e60523e85d7a955841558a35535d6e52cb166669a69049646b94d2fdb901ffbb1446a2d7f58696bce000ccbbb6942b0ad6480d006602c228218d3a2f0bc6a5d5c73acda9fc4b0b496a7d527050f8d77b71641f030368e9494bfe8e9dbf6dd4040426da1b0423739b40450273f4a8d551637e5fe3ca8d54fc476e6278e75cebf4a4ac3ac8ef3807041c4b274568797c8caaffae7df08c6c158d92411db981ea02cc212064c3ad6a9cd1cc02087acce5ceb8d7cddaec429d199c3d90670288be6e88e6826d1f6c417df5f35139c71a62c0267adfce7cb3aa49e827165b28c8cc157a691cb52ef103d8d7ca0ebfc628904d0b2d365dd3401b620d6d93cef670e2fb90ced33fc1486a0e70aeb6fef62ce5a0dfb51fcec12164e4024b0c49ce8b65e01356d80a9571af8f69a9c7256ed549d699a31ceff21c13c482ee0c5759f96125b0099495feacf22a001b2c887b107a9ca9e84de461fbc6e143566de56c710156de5b5f4b7ffe29c0124c1fbb6a792110284c9ad713d89bbb5ed444d09408c65a9f74c5f6c4fd281d31738db82913dcd1ac1fccbba24dc933fb9a8e6c4e426fb98590d7da0252c34d866c114526ded1c9d96daea12ecbd8f2a44531dfb72f02c02b267edf0560b1fb06b087bb6ce02b2922d92f81bb7da99b90e4a2dd68aa858759584490be602369dd606a510b6228e3b941421a3006a697b79866cae011d8aa496de4f3bfffdc0a087d01323db849f6237d7ac476d18bb417f26a697388b4c0a78533f3dd763398719c9ee5bf0299786fb8c4143af8c1195103390d4494b735c06b5815c454dba2fcdd27d214c48712609ffe7ad7c082e835d7477de2358fb3c4b5162027f816ca85aa4a46c25105175e77c8e5394db6fb3999c25ce578f066329182b28fd5b68769cb07ebc67e47a537f6cb62bfd18af162113a4df7f8908e0ce953b6a9637c850f24de0fda239c25fe4352f3b381fc270384d51d1af1ef0dea8501f98ea71f26de97e98799c4b2a316a216bd4af4861ad83fa4570532029564581bb35ac543355ba3aa246b59c6a5d9a91b938f3c4f0ad6d6f567fffdb6fb78402ded5fdc544a0f5fd87e4677326ca003dffdba8fd390487a6469991506a18f376b12db5be3bdcf4a4bc2f5b34dd8f7066bec3b40a6502f414eac3cd1ed43431b033757e86cca57691b0e1f7eec68fad9423f8b0620aa94798546bc878cf29d74ae74af5244ed9b97107fb83abe25dc160ec05cda1c50b76db981aca781868a7913a3e7c98aa5a3ea8bc81270e6f565138dba33c9c7e887641fd3dafd458b9c64600151038db05725a976950307c662c2eb668e3067f943b9bfd805307729b39ed77309fd5e67ecfc56cc231057a6628fb6f528fb969378529dea2c58fa0b4d791ca591ced733e8cf93a8e19907538f45c2618612648d3e1a78492afc154b7bb0285aea97d618e74a74530b492c66c6bd31557cdc55476b3f163196ec8e87f110834ffb8c232dc77cbf2f7b490f520b3b328af44fecca860a19bee9af6a5f69f63487d7dc6b7bf1233c4735522fedd475f905f044a0a7f658a7a378958cca56a163a343a010f4b65d1bc38cd57d08e0f887293fbc106ad7b15aacca6d51558cb8478b119acde04a19b007802a8e9578121304622aee7858d1794ade88973d6fdf981ebabc98fc417d765c075bf8f76b9781dff7c60071878027c057aade8eaf820186035499e9e5fbf8791e6fc0a0e49047af312a8b1b1e80628dc4db4f45842e19096a54733d28028203aa668bd8655631a01c000c956c32ff10572fdbc95b2f26d09fca84c093ddaa122ad93598c03de9273873ece5096648a6251a27e993ec7b6ea4f2181c09bb06852799323f3e993a4b7461439f702cb9df183fcaab11b8bd2ad391924d5e6ef261fea01c91cdc10d9345c290dfc3c040318d11419563d407c8365fef3dd31d8f9d7d338f5f2cd00433d1d06547ae9c650d14d9a7e5b683f0458e7a909d90d4a57201ca5b8753c13bda3591f9cadffd0987d1c7fca1c5a0cec1e13c612d0390d7c0e2f422c97cda29959cd7b714fbeaa5da7b0bcf911c2744a9a25c7d49e93342f61e10a33fda80fadfed2668bfab8767ce80480093b4845cd5ec83082e8f9ad63236743e72842d1a3226640a549c2c1d002a176e2427b2ae612dc272e3d9fa80a904eb8f93f494a52706346c08b06c9d1d8a61a9c7112c0933910882f0da6eea3c389f4faeea51c03394eab4cc02056d704b8839afd76f0839be5ffdc873b88f9a755be6f0229b0843839a25d63c18da89be1c5da930a101913ffba01fd00f2a447d5f58ae8f21554feb47f42d40c32158219dbbb1e5e96ab3dc26cd6a435525c265b65b0bf48d68e9b3c9178a509833aa47c23e63aa9a6f74bef1e4ef863556b11c014b85ac7c157f1e64531b676eb28c68e82e0089d2bd798213c836cc354d4883dc0b607456ab7f894f0a1f73356fc05a5c97a9cf3b231890c39105b751f6fc54063a08f3d3a264ab90cb7de1d0e2f6acb92302cc9b4bb512e720e6ff8343004028ad223a70d395c5f974d3ddd380f798e80edb4b13555c3be0cb1a500e19a8b1b05f9cae85d7eed756ebcfa57828f1054296ffa48d426ceb83c69ebe1b983421f42316ca6f50bf8df0f4d4aeef85005638a304d88764ec26366a1437867c89800aee55ba428e0c07542e123d748c795560153007f768b20bb057fc2643b7db992c3b9cbfd88657b17fbe8a783da2050affb518cab4226cdf28fa97f48651bd142932835f061f8642e79d1f7ae8ff8665aa85aba24a850b2042dd37e61e665a451f17cbe9d57ed5ecb1dce9ec34c576762929dbf46964de7c44c9f6b10fcf52b48649ded2d491bbe4bb6ad578cd31cbdea6df8342dbb7f33857617250b014fc6d887a448f7a5cef25ff69dbc94733bfac1d5f8593af7fbe4759d23ba8da1f405ba179c96d8ae49eb760446d842f0d61ab08508a3e31e4953e13a1b197d00644303e8a9513199583709f41757740a0dff347c3859d3a4ec391481af349019f75ccfdba111a4c338fd8283733115ce7c114111abb157c1a5a84f7b39779a54f000827a250bff00dbe9cb7162d81f6c942b719f9eb973ac7d4652b911622396c517c6e9c7e5f839c049855567fb53ae84579388e3c87af420272558c686209fd92fc339a553f873995932d9dce52f5e60cc0889c3283f94a0d2d5d011154d9935e1dfbb7e747b393bdd8a84f601adca56d4ac5e8e6f28100a7d5522de50dbf1bd7f5604fdfa660a58dc681b4b230abbc4f594a972a73456de1b7f48975cd03313a80074f5d6701db61860f33dfcc9f06e313e8881c385a50de28ced014daf702f01c45368419b73383008b9191293f59fa87a1ceb0cee64d486842ed7c289dca3b3f2e261df644de0f739079ba5ea195468f0693a995dae8e0f7e4611196824f329fc803bc3588d7d941d1fe86a3ecdb3eb8f6d4066ecee371f9a14e5bd46a40b53e87325bab7255099b4fe7f7b09eddaefc6582feecb8dec02b5e58d735a927d052e263027fa879fceb852b9e08db4636c7152f272a43ae4037c50210e90caa3e008fbfa98ed42cd425259096fc06644edab9b768779dcd892747f18a9cecc6aa31dc27d3f12a540447653edd5bed68f50da71b7992434b74d0209746f93ea429691fcb99da0ca32df822ec4332f7eb4bbe6d2111ac84a55932b3e173e388ab96a5a8a17c7d8b8131cf566e0335b0c4a37c5ae24e73c81146031295b69ce3032fa8e4c7616558179cc561f14864190d458cb82370749d595966047de698256126a4ca23a6bbd39201b8649fbcd387474ecf5b9f732e65938fe393a2a1269b06b9b49c5d8882d70776fc823da5842d812be2a65d2f5ee0d64f8258e761e6f2d4c1a825963b367d70b9e81b46fc25e4804fe9decf3aa0e47f1eba573a24f0e4f7b8cf8a886c7ef4175bd317709feeabe46df9719e7d7a4bc2c1bbc15a58b5332ea558e160f5d3b7aa84fe54ea7a24bd8e394ab794e72db7946780272556be33b7f32a0ee651c013d8ed3b5d75bc1c4826dc94f9e3711c53be3bcdf361329544f2993a189b6431a6dda8b81cb1b7c3a69ba96c1ac84a55100c4985cc85ce272e8eb5a57c563a7ad782664d561c3400e779317122d425c9c4193414bebd4d6ad31ba916448f65e9a7ca1f856dacf9d88b695410c8491a759d2c0304e8368b39cf502d0abf7233b1ba9671bc422ce182833ead52597481ea3ea26a2cc35e12a8c83bbb263202d5e9e7a5bb8ab2a5a844d596c24fdac423981fc4dc4291944ae476d59c9a31a05f79f0fe4b39f145c4fba857fa553a17fb2d5f941d5dac8dd3dd07e48eabfe5b98f3c41e7a84986dc3a7a3bb0ed2d4232cffbc50f167d58fb52fa3b357e76430d7f0f1aff6e2d51ea8f5b98bb66c5b5687821f33b9b6c2e407ad0e8140c4d5d4f1739167f8d63284caf4a43688473cd97bab401218fbb2ea13be81bbc05a81042a02eb1843bd46ca535e778e207c79ce3fe511a55d21bf20b24bcdfb43fa62b3469fae2ebd61e362d5d663fb2c08cbde5df9d8cc1faaf6370b5328ffccde873849299d61477a9fcf7c5c96fbc51b24c0f2cc6e39a46f4a9c1f5214f2cd06db62a37e2c6f477ceac0b92eb882d7bcd1fc3721a89745473eb45eee9a4fe6ab323d28f4db957d0c5dc1ed25ebc194f744a2cfe98474868e6acf5641ad454b3626ac2a27a9db416eb1763935eaa5612e43c49e8959ebcf5133863e98c19618e936f33952699fc224f41a4e259b40228047ed6a17cf4f3a42dc76df1346acb0986984f1692b5ed28f0825a23094ddbb8c1750e9035b1df2166f142e7f179473098ed73acb9ffb8be530542f31de88d6677f805cc30ccc0b60787e61f9d195ceacf07a35d979f9c3521f23671f378a6cd58ed2b0620ff7e2def5025f878d70008744c6a53caf325293353747c94c5ddf12e3a42686f97adc4db62b5e2e91132345963b7292fc9d13b484f75d8da000000000000000000000000000000000a13171d2127",
|
||
+ "hash": "0xc7903f14f8aa0ffc09cdfcd433e20f07ceaa63ab9b56b84ba41fc8dab7204952",
|
||
+ "intrinsicGasEstimate": "180176"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-3.json b/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-3.json
|
||
new file mode 100755
|
||
index 000000000..5ccfbf6e4
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/valid-ml-dsa-3.json
|
||
@@ -0,0 +1,28 @@
|
||
+{
|
||
+ "id": "valid-ml-dsa-3",
|
||
+ "expect": "valid",
|
||
+ "alg": 3,
|
||
+ "chainId": 28001,
|
||
+ "publicKey": "0xfd3c43f5fc7807747a73e1d8e78cd9e611ad6bbba9b264534594174b49082aeab827927b335526cc50c2f0368fc666efb79c34af8ee90427d1718736acaad47f5959b9b26457619c07c2dda553d55a7498e30a37c92909f6b37c246dca4e8fd24d4cccd811396d276e5d11f1e8d14bb9eb4d5ec49798202422edd57ea4d8c0e8c6388e9c93a0ff2e52f7ca2303e40300c50c926a7da22919be462e2dcbdb3ec235b14290a282ee76a04f4bf7c5e2ec5c8fc0aaac72ce4f8fcf0d42b9fc3c4049ab6dfdfa12623d89c0d96434a8e13cb6f79ad6f4a8102f9a0bfe582d967372d8928ff9d7d7393b22ec1386ee91dd196eb9c349a6a12f7504e66a096eec0a8ae98e62275f6b84fb40a81a390c6ef0102c8fd2c11d303745b8fc49e638e6f3004961724a977a18d81efc67e37d0d44558e28cf9015dfa08eff82004c4a53dfa40c2451fa03a987f70c855dbee37e36480863044165e6d46d4c43278091317beab6f301d61c8f54f94ee88fa358c9aed6e55b80b4196e79a3d7251ede25c4baef8129882a69789df3a8262941199ded7bd381de00c257199c18e9086d9ce3f72c6d95c0a4d109a3a15474805f0dc06649a16a7805e8d74bd1af7658f5f9ef726d560595ff9f072d4cfaaf61283087843b904b0f5670ca551079c759d4a2839a71505e007cb5d49b0437b87a080fab5e2efdedd1d01f0f1ab72f0e6129a2525fc6e9829b56ce9d9f287a5bd80be8b1556e4ca82eafc60ec22315448768a72e45d4d956c16ee48a0658e307f81ee0f695f1b1b747d1d533d8da720f088b64608b1edb2d4d27247b2cd35e3d94e1256a3c5c944bbafe07b55ca74df4ec0b869733ddb466717a16e98af4ec310d046c90046c024fb33fbb2ffbb105d41bdd0e0af27b1239aa4d92b6ef8d727e51372fefc3b5c8bc6eb585a0ae2dd9970009555c2c2ced5e5a1e97c659565b6139dc4f3bae788e21f9658affa8fdb6f4733f7fa83fefab91a030f8ec976b8263c17abcef46dc22456d5347eea7c30dd25bdc3caad7cb2010f06573d56b6e5d28e6e847d8df8f18d6a2655ea66fe3c8e7e4ef192b5a8aeb35f8469277657b77155142c7b1653d5eb9cf9c4d69bbc5746e0c1876e330f9016a2f5343ec60b2f35ea380169a2bdf102888e6aae7e797d0bce73834f418018e8e55492da8236a542a999d9eea55bd52ee2e59feb0329d716c78c0bfcd79dc27cd9639399d2fd99d2fc9c4900ad60bdb8221501038ec4baadd2ac4830b2bfe1e20804c818c8e089661e7d842bc4e566fa0bc2d7968a44f8df0d4e88e494fc7bebdb695d3a8edf6a2703817b0f8c1a55569ac4a8ff0931137f075797e9744135a3fec6c767af26d4592a9022271a4052b1f1f24f072bd5ceb1d19e02b0bbf31251a7bb8b723bd3da02f59ca1c0c91bc10896970a1e0f8e0fd5b755da58d70be8935f65661629a9f833b35810113ce80125f8ed7a031cfd5eb1475b597856b4ce7629a9429d840a3457bbd70c05c73c6ce84dd59f917a24d06ca8743225ab8c266e209fbadf57cdb587df96eedf54c04fb3f83ec0dddd1d8bf9051c6de4db3aa099f1779f3f30f61f432e5c8f6b7ac4ee6c6dd6fce667556df155ddb2002735fb7addd8acf74863ccfe04a3088317634eb47e56b18c79f31318ac5e448a9094b5c2c70b44dbbbff7c235cef4701d504723b032726d009c6d7f527e645a23fc1ab478e6e2699211694d575bd436d778e7ae53868c63dfb78f591d82b979585cec8bbcde61f375e783e97e8f787fb392fa4f0bc3e9010aa9ec3cf6471bb16355c3ed3fdf2ee5b95ade86371d60fb0699a851770a212d0e0eeb3f20df78ab180343fd79a9d04d8dc56d9fe3d820b27d98d12275a40d270f4181aa1a18305c8d3469a954b2e85405a394684cc234702a6cb01c04ccc941a4392cf64ba31bea700d339152fce6abb0dbe84823b8d3b18258a29414fd52c91ccbc198e101287b79d8bd0e5f4b05a14a07055e66ea37d781934840a204638bffda400113bb1344126fe1c2ac1e57bb861c3d35349b1fba0c11e12921262ae52fb2e0bee444f8197e2817b9356e10af67e794a7967055936bfcb51f4be6fc5602a8df97ddcd73afe83c02f00d4f1d8302bd2e826d4c50fd3ded9a74debd0e807b694e912a8a3a800f5b983e171898874b77ea305ede4abdf0db5ca84a8a60b184374c08066537b08d42a609b97039ff8905bccc4454188b051c5d1e574e1e8b74cc5cbded064a5374c55f17002ee9b17447fdc324a12e3f2f414b491cccf20c9f98820461f4c7d61355a30f1a6cbb2fe7403b90587298fcc9500519451e44225c750b8b32a649ea288eda389e596390a5386652dea5d0e096ee270bcab9da0c3c4ba464f44172732a748e339cbfc8f0c1ee3187225e2fb29e67ffbd84df8acf759c817d628e03a245e9ae0cf00939fa12964e8dc124659eea8798b097ba52480532fa11194e4623ff63f6cc1d17c7080bb2c1459fe8cc9b197b89ba91986b7bfa61e514bf5c60f981e63baffd9fce44af87ad73fba197e46790fc03f8a46aa6d7590f47e08daedd7f564685208ee87da84b04b11cdc0c020bb26b0abdad3c1340649130e26af9c7651533313301e8b517a84c807d86a4c0cff68566d34da4111d67bdc77ef5f49ec7d83af24a143bceaee020acce02499c725ebc341a86d91c7f63dd962ffcc09fc0b5673873ee55cea4bba69b5058e4b364fb3802832d5118774790dd12eed78330412dc877cc034309a7e292ebee955a431fd46faf7884cf3bd5ab03d02b8784af2a84bb907ba5f021fc332f638a2d4b6451ea0a2cdee6ff1621d698eadfc99d6f405003f300e321a9e80ed3b577a899fa7dd891b53cab8acaa9fd3ce02640eaa75646f134c190817675b9e4a688d0668528fa3b378749bb6b1a0bd16873e89dfc927dcf568fc3cf94ac49d289ba1fb9c58a74574c8fbac321db256bf919e9432d6a8ae9a0dae900901f436b13d0c2b753a5eb6fcef03301d7faa15ff32ec0730335b13394bff66ea83a7043f9e1df5962671ff2d2759db234a4a4fa47fd3a9359bb14ef5b5fc398836d42afcc5d5f252b1b061afc6a0815b3a7586d25eed5ee52c56d2389b8f2438649ee652b431d3cc4262c6e5ea1c0ccec21aa6123e88b4bc933098576bd78cf5bcbbc278ee682029e05e91aac2043ad3ec1d3d97f6ebc6bd5faffa5bc71328cd4351bcb9a0d8d1ea9253b97b08c8c53b20e29703568d5d7dfa2bfa6aeb3a93043e4123116a125311695a11c8538658210971d7763ed7870c1309893909e306df22fe968612531e58a91d19dfe2c658ade19c8e0900c779af8ec333d19552e42cdedbe13ff85d99b10baf8daf70951290db56bc7ea049e6b468b6546a7f3ae77c2e14770eed1ea345f0d139336af4eee686ac2e73bd4262cb802e0173fb872a77cd2c0f3421c497b0260be79ae29d04d9a9da9d7bc101ae3ec9dace1133332f05b7b82aaee577c06c0d2a8eaa8a96db8b899cb3240cc4dca4f8eab513ad5b3529063b5df3664dde0db1e0ae5c29e69f011076fc7edc4261d043f38f1c68645466c9a5e685a07393b7e2f8f74db86742ba5ac089b45a42df3f943842747674c1653aa2a8ef282f64e7ec2ce1fada994288a5f9b95da4bc083ea008308",
|
||
+ "seed": "0xa8af8968099758df7640e2c9f1713fe31d70766e2c2b18bc2ae82f5b1e1e8fa5",
|
||
+ "tx": {
|
||
+ "alg": 3,
|
||
+ "publicKey": "0xfd3c43f5fc7807747a73e1d8e78cd9e611ad6bbba9b264534594174b49082aeab827927b335526cc50c2f0368fc666efb79c34af8ee90427d1718736acaad47f5959b9b26457619c07c2dda553d55a7498e30a37c92909f6b37c246dca4e8fd24d4cccd811396d276e5d11f1e8d14bb9eb4d5ec49798202422edd57ea4d8c0e8c6388e9c93a0ff2e52f7ca2303e40300c50c926a7da22919be462e2dcbdb3ec235b14290a282ee76a04f4bf7c5e2ec5c8fc0aaac72ce4f8fcf0d42b9fc3c4049ab6dfdfa12623d89c0d96434a8e13cb6f79ad6f4a8102f9a0bfe582d967372d8928ff9d7d7393b22ec1386ee91dd196eb9c349a6a12f7504e66a096eec0a8ae98e62275f6b84fb40a81a390c6ef0102c8fd2c11d303745b8fc49e638e6f3004961724a977a18d81efc67e37d0d44558e28cf9015dfa08eff82004c4a53dfa40c2451fa03a987f70c855dbee37e36480863044165e6d46d4c43278091317beab6f301d61c8f54f94ee88fa358c9aed6e55b80b4196e79a3d7251ede25c4baef8129882a69789df3a8262941199ded7bd381de00c257199c18e9086d9ce3f72c6d95c0a4d109a3a15474805f0dc06649a16a7805e8d74bd1af7658f5f9ef726d560595ff9f072d4cfaaf61283087843b904b0f5670ca551079c759d4a2839a71505e007cb5d49b0437b87a080fab5e2efdedd1d01f0f1ab72f0e6129a2525fc6e9829b56ce9d9f287a5bd80be8b1556e4ca82eafc60ec22315448768a72e45d4d956c16ee48a0658e307f81ee0f695f1b1b747d1d533d8da720f088b64608b1edb2d4d27247b2cd35e3d94e1256a3c5c944bbafe07b55ca74df4ec0b869733ddb466717a16e98af4ec310d046c90046c024fb33fbb2ffbb105d41bdd0e0af27b1239aa4d92b6ef8d727e51372fefc3b5c8bc6eb585a0ae2dd9970009555c2c2ced5e5a1e97c659565b6139dc4f3bae788e21f9658affa8fdb6f4733f7fa83fefab91a030f8ec976b8263c17abcef46dc22456d5347eea7c30dd25bdc3caad7cb2010f06573d56b6e5d28e6e847d8df8f18d6a2655ea66fe3c8e7e4ef192b5a8aeb35f8469277657b77155142c7b1653d5eb9cf9c4d69bbc5746e0c1876e330f9016a2f5343ec60b2f35ea380169a2bdf102888e6aae7e797d0bce73834f418018e8e55492da8236a542a999d9eea55bd52ee2e59feb0329d716c78c0bfcd79dc27cd9639399d2fd99d2fc9c4900ad60bdb8221501038ec4baadd2ac4830b2bfe1e20804c818c8e089661e7d842bc4e566fa0bc2d7968a44f8df0d4e88e494fc7bebdb695d3a8edf6a2703817b0f8c1a55569ac4a8ff0931137f075797e9744135a3fec6c767af26d4592a9022271a4052b1f1f24f072bd5ceb1d19e02b0bbf31251a7bb8b723bd3da02f59ca1c0c91bc10896970a1e0f8e0fd5b755da58d70be8935f65661629a9f833b35810113ce80125f8ed7a031cfd5eb1475b597856b4ce7629a9429d840a3457bbd70c05c73c6ce84dd59f917a24d06ca8743225ab8c266e209fbadf57cdb587df96eedf54c04fb3f83ec0dddd1d8bf9051c6de4db3aa099f1779f3f30f61f432e5c8f6b7ac4ee6c6dd6fce667556df155ddb2002735fb7addd8acf74863ccfe04a3088317634eb47e56b18c79f31318ac5e448a9094b5c2c70b44dbbbff7c235cef4701d504723b032726d009c6d7f527e645a23fc1ab478e6e2699211694d575bd436d778e7ae53868c63dfb78f591d82b979585cec8bbcde61f375e783e97e8f787fb392fa4f0bc3e9010aa9ec3cf6471bb16355c3ed3fdf2ee5b95ade86371d60fb0699a851770a212d0e0eeb3f20df78ab180343fd79a9d04d8dc56d9fe3d820b27d98d12275a40d270f4181aa1a18305c8d3469a954b2e85405a394684cc234702a6cb01c04ccc941a4392cf64ba31bea700d339152fce6abb0dbe84823b8d3b18258a29414fd52c91ccbc198e101287b79d8bd0e5f4b05a14a07055e66ea37d781934840a204638bffda400113bb1344126fe1c2ac1e57bb861c3d35349b1fba0c11e12921262ae52fb2e0bee444f8197e2817b9356e10af67e794a7967055936bfcb51f4be6fc5602a8df97ddcd73afe83c02f00d4f1d8302bd2e826d4c50fd3ded9a74debd0e807b694e912a8a3a800f5b983e171898874b77ea305ede4abdf0db5ca84a8a60b184374c08066537b08d42a609b97039ff8905bccc4454188b051c5d1e574e1e8b74cc5cbded064a5374c55f17002ee9b17447fdc324a12e3f2f414b491cccf20c9f98820461f4c7d61355a30f1a6cbb2fe7403b90587298fcc9500519451e44225c750b8b32a649ea288eda389e596390a5386652dea5d0e096ee270bcab9da0c3c4ba464f44172732a748e339cbfc8f0c1ee3187225e2fb29e67ffbd84df8acf759c817d628e03a245e9ae0cf00939fa12964e8dc124659eea8798b097ba52480532fa11194e4623ff63f6cc1d17c7080bb2c1459fe8cc9b197b89ba91986b7bfa61e514bf5c60f981e63baffd9fce44af87ad73fba197e46790fc03f8a46aa6d7590f47e08daedd7f564685208ee87da84b04b11cdc0c020bb26b0abdad3c1340649130e26af9c7651533313301e8b517a84c807d86a4c0cff68566d34da4111d67bdc77ef5f49ec7d83af24a143bceaee020acce02499c725ebc341a86d91c7f63dd962ffcc09fc0b5673873ee55cea4bba69b5058e4b364fb3802832d5118774790dd12eed78330412dc877cc034309a7e292ebee955a431fd46faf7884cf3bd5ab03d02b8784af2a84bb907ba5f021fc332f638a2d4b6451ea0a2cdee6ff1621d698eadfc99d6f405003f300e321a9e80ed3b577a899fa7dd891b53cab8acaa9fd3ce02640eaa75646f134c190817675b9e4a688d0668528fa3b378749bb6b1a0bd16873e89dfc927dcf568fc3cf94ac49d289ba1fb9c58a74574c8fbac321db256bf919e9432d6a8ae9a0dae900901f436b13d0c2b753a5eb6fcef03301d7faa15ff32ec0730335b13394bff66ea83a7043f9e1df5962671ff2d2759db234a4a4fa47fd3a9359bb14ef5b5fc398836d42afcc5d5f252b1b061afc6a0815b3a7586d25eed5ee52c56d2389b8f2438649ee652b431d3cc4262c6e5ea1c0ccec21aa6123e88b4bc933098576bd78cf5bcbbc278ee682029e05e91aac2043ad3ec1d3d97f6ebc6bd5faffa5bc71328cd4351bcb9a0d8d1ea9253b97b08c8c53b20e29703568d5d7dfa2bfa6aeb3a93043e4123116a125311695a11c8538658210971d7763ed7870c1309893909e306df22fe968612531e58a91d19dfe2c658ade19c8e0900c779af8ec333d19552e42cdedbe13ff85d99b10baf8daf70951290db56bc7ea049e6b468b6546a7f3ae77c2e14770eed1ea345f0d139336af4eee686ac2e73bd4262cb802e0173fb872a77cd2c0f3421c497b0260be79ae29d04d9a9da9d7bc101ae3ec9dace1133332f05b7b82aaee577c06c0d2a8eaa8a96db8b899cb3240cc4dca4f8eab513ad5b3529063b5df3664dde0db1e0ae5c29e69f011076fc7edc4261d043f38f1c68645466c9a5e685a07393b7e2f8f74db86742ba5ac089b45a42df3f943842747674c1653aa2a8ef282f64e7ec2ce1fada994288a5f9b95da4bc083ea008308",
|
||
+ "chainId": 28001,
|
||
+ "nonce": 0,
|
||
+ "maxPriorityFeePerGas": "1000000000",
|
||
+ "maxFeePerGas": "2000000000",
|
||
+ "to": "0x0000000000000000000000000000000000000001",
|
||
+ "value": "1",
|
||
+ "data": "0x",
|
||
+ "accessList": []
|
||
+ },
|
||
+ "algName": "ML-DSA-87",
|
||
+ "sender": "0xaee69521a942a58325bd694f2cc3d64752465d4a",
|
||
+ "signingPreimage": "0x50f90a4e826d6180843b9aca00847735940083045f289400000000000000000000000000000000000000010180c003b90a20fd3c43f5fc7807747a73e1d8e78cd9e611ad6bbba9b264534594174b49082aeab827927b335526cc50c2f0368fc666efb79c34af8ee90427d1718736acaad47f5959b9b26457619c07c2dda553d55a7498e30a37c92909f6b37c246dca4e8fd24d4cccd811396d276e5d11f1e8d14bb9eb4d5ec49798202422edd57ea4d8c0e8c6388e9c93a0ff2e52f7ca2303e40300c50c926a7da22919be462e2dcbdb3ec235b14290a282ee76a04f4bf7c5e2ec5c8fc0aaac72ce4f8fcf0d42b9fc3c4049ab6dfdfa12623d89c0d96434a8e13cb6f79ad6f4a8102f9a0bfe582d967372d8928ff9d7d7393b22ec1386ee91dd196eb9c349a6a12f7504e66a096eec0a8ae98e62275f6b84fb40a81a390c6ef0102c8fd2c11d303745b8fc49e638e6f3004961724a977a18d81efc67e37d0d44558e28cf9015dfa08eff82004c4a53dfa40c2451fa03a987f70c855dbee37e36480863044165e6d46d4c43278091317beab6f301d61c8f54f94ee88fa358c9aed6e55b80b4196e79a3d7251ede25c4baef8129882a69789df3a8262941199ded7bd381de00c257199c18e9086d9ce3f72c6d95c0a4d109a3a15474805f0dc06649a16a7805e8d74bd1af7658f5f9ef726d560595ff9f072d4cfaaf61283087843b904b0f5670ca551079c759d4a2839a71505e007cb5d49b0437b87a080fab5e2efdedd1d01f0f1ab72f0e6129a2525fc6e9829b56ce9d9f287a5bd80be8b1556e4ca82eafc60ec22315448768a72e45d4d956c16ee48a0658e307f81ee0f695f1b1b747d1d533d8da720f088b64608b1edb2d4d27247b2cd35e3d94e1256a3c5c944bbafe07b55ca74df4ec0b869733ddb466717a16e98af4ec310d046c90046c024fb33fbb2ffbb105d41bdd0e0af27b1239aa4d92b6ef8d727e51372fefc3b5c8bc6eb585a0ae2dd9970009555c2c2ced5e5a1e97c659565b6139dc4f3bae788e21f9658affa8fdb6f4733f7fa83fefab91a030f8ec976b8263c17abcef46dc22456d5347eea7c30dd25bdc3caad7cb2010f06573d56b6e5d28e6e847d8df8f18d6a2655ea66fe3c8e7e4ef192b5a8aeb35f8469277657b77155142c7b1653d5eb9cf9c4d69bbc5746e0c1876e330f9016a2f5343ec60b2f35ea380169a2bdf102888e6aae7e797d0bce73834f418018e8e55492da8236a542a999d9eea55bd52ee2e59feb0329d716c78c0bfcd79dc27cd9639399d2fd99d2fc9c4900ad60bdb8221501038ec4baadd2ac4830b2bfe1e20804c818c8e089661e7d842bc4e566fa0bc2d7968a44f8df0d4e88e494fc7bebdb695d3a8edf6a2703817b0f8c1a55569ac4a8ff0931137f075797e9744135a3fec6c767af26d4592a9022271a4052b1f1f24f072bd5ceb1d19e02b0bbf31251a7bb8b723bd3da02f59ca1c0c91bc10896970a1e0f8e0fd5b755da58d70be8935f65661629a9f833b35810113ce80125f8ed7a031cfd5eb1475b597856b4ce7629a9429d840a3457bbd70c05c73c6ce84dd59f917a24d06ca8743225ab8c266e209fbadf57cdb587df96eedf54c04fb3f83ec0dddd1d8bf9051c6de4db3aa099f1779f3f30f61f432e5c8f6b7ac4ee6c6dd6fce667556df155ddb2002735fb7addd8acf74863ccfe04a3088317634eb47e56b18c79f31318ac5e448a9094b5c2c70b44dbbbff7c235cef4701d504723b032726d009c6d7f527e645a23fc1ab478e6e2699211694d575bd436d778e7ae53868c63dfb78f591d82b979585cec8bbcde61f375e783e97e8f787fb392fa4f0bc3e9010aa9ec3cf6471bb16355c3ed3fdf2ee5b95ade86371d60fb0699a851770a212d0e0eeb3f20df78ab180343fd79a9d04d8dc56d9fe3d820b27d98d12275a40d270f4181aa1a18305c8d3469a954b2e85405a394684cc234702a6cb01c04ccc941a4392cf64ba31bea700d339152fce6abb0dbe84823b8d3b18258a29414fd52c91ccbc198e101287b79d8bd0e5f4b05a14a07055e66ea37d781934840a204638bffda400113bb1344126fe1c2ac1e57bb861c3d35349b1fba0c11e12921262ae52fb2e0bee444f8197e2817b9356e10af67e794a7967055936bfcb51f4be6fc5602a8df97ddcd73afe83c02f00d4f1d8302bd2e826d4c50fd3ded9a74debd0e807b694e912a8a3a800f5b983e171898874b77ea305ede4abdf0db5ca84a8a60b184374c08066537b08d42a609b97039ff8905bccc4454188b051c5d1e574e1e8b74cc5cbded064a5374c55f17002ee9b17447fdc324a12e3f2f414b491cccf20c9f98820461f4c7d61355a30f1a6cbb2fe7403b90587298fcc9500519451e44225c750b8b32a649ea288eda389e596390a5386652dea5d0e096ee270bcab9da0c3c4ba464f44172732a748e339cbfc8f0c1ee3187225e2fb29e67ffbd84df8acf759c817d628e03a245e9ae0cf00939fa12964e8dc124659eea8798b097ba52480532fa11194e4623ff63f6cc1d17c7080bb2c1459fe8cc9b197b89ba91986b7bfa61e514bf5c60f981e63baffd9fce44af87ad73fba197e46790fc03f8a46aa6d7590f47e08daedd7f564685208ee87da84b04b11cdc0c020bb26b0abdad3c1340649130e26af9c7651533313301e8b517a84c807d86a4c0cff68566d34da4111d67bdc77ef5f49ec7d83af24a143bceaee020acce02499c725ebc341a86d91c7f63dd962ffcc09fc0b5673873ee55cea4bba69b5058e4b364fb3802832d5118774790dd12eed78330412dc877cc034309a7e292ebee955a431fd46faf7884cf3bd5ab03d02b8784af2a84bb907ba5f021fc332f638a2d4b6451ea0a2cdee6ff1621d698eadfc99d6f405003f300e321a9e80ed3b577a899fa7dd891b53cab8acaa9fd3ce02640eaa75646f134c190817675b9e4a688d0668528fa3b378749bb6b1a0bd16873e89dfc927dcf568fc3cf94ac49d289ba1fb9c58a74574c8fbac321db256bf919e9432d6a8ae9a0dae900901f436b13d0c2b753a5eb6fcef03301d7faa15ff32ec0730335b13394bff66ea83a7043f9e1df5962671ff2d2759db234a4a4fa47fd3a9359bb14ef5b5fc398836d42afcc5d5f252b1b061afc6a0815b3a7586d25eed5ee52c56d2389b8f2438649ee652b431d3cc4262c6e5ea1c0ccec21aa6123e88b4bc933098576bd78cf5bcbbc278ee682029e05e91aac2043ad3ec1d3d97f6ebc6bd5faffa5bc71328cd4351bcb9a0d8d1ea9253b97b08c8c53b20e29703568d5d7dfa2bfa6aeb3a93043e4123116a125311695a11c8538658210971d7763ed7870c1309893909e306df22fe968612531e58a91d19dfe2c658ade19c8e0900c779af8ec333d19552e42cdedbe13ff85d99b10baf8daf70951290db56bc7ea049e6b468b6546a7f3ae77c2e14770eed1ea345f0d139336af4eee686ac2e73bd4262cb802e0173fb872a77cd2c0f3421c497b0260be79ae29d04d9a9da9d7bc101ae3ec9dace1133332f05b7b82aaee577c06c0d2a8eaa8a96db8b899cb3240cc4dca4f8eab513ad5b3529063b5df3664dde0db1e0ae5c29e69f011076fc7edc4261d043f38f1c68645466c9a5e685a07393b7e2f8f74db86742ba5ac089b45a42df3f943842747674c1653aa2a8ef282f64e7ec2ce1fada994288a5f9b95da4bc083ea008308",
|
||
+ "signingHash": "0x3ef7803edb46bad878a1a585571475b75bba9b66e2407b73c6d5794ec507790d",
|
||
+ "signature": "0xc74a08868ea0fdad9fbb1b485b793bce6e4fa945668b2351232a7c8a084fb2d87a5c83e7dced6bde3743617a7c4babcbf9381694b64d7e0feeb6615440e927a63293c6b695900b1e7afad1ae612c324a88e6761c3b6fdc41d18f514be1ba3a1ca53fdbcf8c19f95bcd60223abe52d07fd7c4114dad9f347cf122f6241429da7e598959c22692910323a0a699595398f518c58deea7159920d89e3e65702bc2cabea7e9ca0bbb7002fb7be5243bba6a08a12238ead443ff4394510d25eb279885d9112c44529f294c5a2bf493a74ba8f4e38744e632680b3ce055a897d2a5468ef52e6e70dc5af55a9fb83739f6cfc6994871662b8263f2e07e21a6514624909369e0138755165dd2af5a791da63c0604b68ff160fad82a578a06e76f62bb7e951b81d8fde2dade6c3a314eec5913151c16a93a5abd5ceb59ad96197a349721ab123b42f799dbde36d7965e0e5dfcf43d8d1ae13f4a00afd8dde36137d3de87f4e2c0366c18f4b3a449ffd9afc7c742c50456f6e642f7d09e86d5aef224b20ce5d8a2bf164484df8fc87daf69e459fc78c6b974cdb8fb1dccbd5290f560e3114302886e2828ad73ce71b06186254206743076c6af0c3d1facc36695dc28db1d026686b141247e1c7a9323d544b0079023cd2adedc0479ceefc8e0c34782603d0c27d18768eb5485a85bc385ffdfd25f735688a3b9a0c6f532b2a7989c751804de0163582293a17f635fdde14e9067f12929b079f89a53dfc87b986f89f718320ede83cf4086d0d095b24b66d5e3f1bfdb08b79cd5b25657cf2b20faff1d199c16bb7f631b33970b34c12997637447e4127db1bf580b339807637a86e0248cbcf8e1d30ae6fe053e2f9b7b3d0f9e3f4813af908b633560779012f9e06af00e252bb0df9f0caf7d1e82f8deb2ede21d13f406dd9ea69445d50844c95c921d8d1cbc8afbc5ddcd4157e65cbfbbafe2670e9146a5643db049a8d696f0eae07c3d4099447ef78bdb90fc05d7cc97bf9b9dee8719464ec6b9e6de866f73914a80396dea3900a9f7b43a47e648e20a9504da92c47ac65368813e5453e82020f8861aba2534346e6137e71adb28a5ff080365d6ea26dfc30ef5500d0760749d6e4e0f93aaebed544832308b19f72e92ebb8eaec2492c6ea7972fd359a8b67a1f4053bfb1a3c6fb720b5925a7a827e59b3bd0651b8014c77b25d61db17eb169cc2fa2442c82f68fb42200c59baa468a9fc92f13273ff071124f8b31e2b4b2517ee622d29489997ecb5676fb52e3002371c01004c214757b1f510091c2377a08d058209d18feb9b524a41712b6df4b92f2b14c583d3196749f367b3bbc8ab5e9e2615c511f23ba5fb1bac2ee9436dd8d162bd96f1fb663d2b520ba7e8ddfc2a4d549b63714654cfbb37ee1dca5f723139187ada8f8d5b42ad09ff196b70720d2527b4466d44f33cce486ef2e86311c75ead31a17b16989dc63bacf0d465379d9138df7ea2ebc71f4cc3b6662e24895050e2553dbc160a567d6722964a904d43bf2684206cee3562256e98addf3038e968cf6c09c921e2c89c9c249f6ba7afd20dd27587b4143f704f2738315a91c2d40c467111b4f3bae4f77bae402145e742ba83a527aeffca13ee2290988df882feaf5a3c24b416d59e06cf4f8832a016ce55419b7bd2028545557528a0af23f17942433e13fad089fdb79449bd9d99b0324b1828791249b6789a09cdfb6ec40c0fbaf8b28ea4f72d3df5159bea7a7965b94beb1bb01d87d76ae7ce47fc333fc152038ab4e7ca64a802f96f2e92bcc53ad9cae0242c622c99b2daf005e554cd6ba127991d84841ffe3ba0674eb7930509045dd00ab91a7c6acd2f4a40e7ffc9959929851e40d417f488a29f7bb5af3847a8caa5daa0682aea870ac8b866ccfdc435971e3d862c2f651cc6eb8a33fca313a56ab8228ee9ac7dce14ea3c3fba4f58c70888ae558d8cd632a2723ba54a3d538f4e20936a2ee543e9b2141e06095c72d4ee19908febf7c248c03a78655420da644746e2d508c31ceb0b648800d95dceec72f7576502046e5dce54b5a097f625001bfc92d6e4633b293cdfa63b1fca5de9e26d03ba2f1cf3647dbdad5359ed76bf702f0621c057dea3617af678016aa13360ebb02c6cb2fa0d3f137a1a3c639c989e12383841ab7ca5a84f84c08af4b85416ce7ec3ed91636a79add207bedf9dfb2ff626387f20cb3315502b2b06f361cbf6a51fb507598af41c5a5b9cd95ba1894ca372c5e1851e62a0d3d78dab6f92bd43ba6fcd71230b6cfd843d89268872b75e3c5b471db530b7ab5451dbe63fa0bdaa7d74907cb376643e129febbe6ce10b5dffbf323dc973f097d2081e06aad65e674c5a41bb81b80556fd78691fe6b5bfad47fd1b64db577f27f22f17973cbff3a7c4aa43569bbe6843d773a2f933f472650e88e0ec6643f87dfd37e7fba915c7386a130b8d4f0ff4d0e99a633d1f863f3e8ce4e1ac5e31438d89c3b6d5ace3aa6e14e7073164ea01e853958bece389316023127f9916297a47c5d6ab5513bab874c1ae3bf2850cfab9018cbf50a7febe03ff3e8e4e55ae5632812b6a147edf051b461bfe56f01a6ab571e0553e37a57a3a9811f4fda2e189d79b74215d6fe199595d18c6543c747572f8cdc61a53ce09d9ca96b43a5af5b56b53148dd4fdfc1e22c9958caa783f2d112d8d5fd39e6955df75d35c59a1967fc0d8d3293e39a6cdf82d6846b39a74b1a538372c266b3f12d7ccf464ff7e32fe54342994f51d344302b3b2e11eed2187a741eec99ef0a79a19a854c03d8bd3fcd557b9d8bfb35f0976da327fc7e8d95fb43db8e66be5b373385fc1b68099566c7e88aefe92c7c521d084c15c8d403d87bbc975e8d687e2a51e5ce53191e3db5bdc50f475853cda7cc5a7365c41035aecb61444c2a48492a600b58300b2805be97b4e9e30526e9e62bb3248a17c3809219307ca85351495c943a865359c783cf615a809c739cce0786c6045d9c8071797001434cbae571d42cef415e28ed6adab09ed10e0713dc1412ed80b8d26d549964321559137483c81b19203080b36abcd68e841f4c78b5302da79fd6e555f390322ae67e54c55749491889d79eb2982fc4428086bd1060c4113137ddb4dd7c9b690b802e805999d4f5127f66f6b1d397dc3509504e2196513b5787407b45b928cfc3c437523daa4f876dfe061e351cb3bad99ea205ab276c4f2a5ccee1027104f09adaf55cd282d4e9e44ac2b65f7e423da1cebb0ac70691347e7a7bd0de8bc9fb2e7a08afc0075a0e85902316cd6ec9a5802c51a6d65bf3251ae712ae0f66de6cba1e51efbad53ad7e769f851799caf5fb81ef35b4da814915dcfa67553f1c67158154707d16804be27af2115559e4758b313b9da4a1131718b29a75970b3f0a5e2f2c11a0a1ed47f238c145dc4fe9e8e963d8395c67dfa94a232b8133a0d953b05455f79e0bdff0bc3de9c04d93d97084ab99229622cfe3958ac5fda6757de1696b575f6250b441e6368386751b1d2f6007d254d152fe76578fbbe164af49cda805b9325f7ea47f5e18f3de1ce38006ae1bf027d3e354d6f923d8bc6286aaf9b9a7b9e7a7fbd36a31db0d88166dc68e7eb567d8164bed1e279a8810fc21656621ff7cb42a21ee04e6086924bb62dddd16c3343db69250f7ed95aba953202640bef18dfb6c00f1ee03c670a5cc6c0f3cd7cb006590dddffa6f19d450860e289f85edb4fb0dbbd2f992eebba09cddc1b20a3c98d8739ad1875a514b09b1f23cf406c4c55cc4266e0b8b283fa445849316c30bd19254e9d035756d2773cab7f5fd56d6d3a094a717ccca43251201cfddf80ba1aa0dad34f5a3acf8476b784fd53a1aff1307a7838705112650bd25dfea21b991d801f018a5dae26edb9dd5a0ab940a94b7bbb90fd1f30f9d1dd2ea3aad6d0a2a3c42fd2641233c7d624314c3a54ce616d2ca5683d04f6fc0924f0b667be32f4de8820f9cfab963a287a1c708857ebabed9b5bcc35d539ef9bc170636cd528ba86a620195134cacbc2b8e742376124b67ed8155ab53979e281f97b184c60355b008f15f45c8b7a506b1c1f511e4aaf0bc32fee27b656b01ed6afaa4053ed674a60175b6c89a77d42963111d0940730db02ff67534fe6a296e0e01e2db6b3f0fe9648286a0f3420cd4393163662751deed6457abbb370f83ed92e9da86a0181df13b8ef33e5718ce524a700ba5f2b40f3f973a67c1c412dc251c19e6b7ceb279dc1dfc36a3567e3a98a9d96ef52b0d0734f57bd9edebedd925167f230b1c81ca938e94ceebe43d2573735873a436331a8b76c1169c6a869889cb74e5d33721bbb99ec87f160c025f570f1d11c2e3ae6a52580785d854790139510179b003418dbcee1f4fd4fa39fc134521ffd7f29cee650472638dd04d8331ee439eaa32c57b56c4fd9c9ba87516a8236dc99b8d6e4c2a48e53a6779d5e13bbd73cc7917f0cfb8e231218bf33bc3c213599eb76476558f0e38a3979cdaad6ac6b03bd0ef0aefec634fbe0e1e87bd78123a19b7352326b9def856ecfc02b06622f94e8cb2a1cb6cf10d020f789a7db775063030f15b463f08878219636f2bb94ed11a3ed9689d797a3253809c7f2e0c60672e8476a9e272075c7f808258901e611c4d535a11bfe01daccaec3a26a187ab45a9fd0bb9a7ecf2e9c4aa3177ddaca1449f19f78ebe26be2e25bca012a10649b56899339f5418925648f3253bd716336dcf65e6b4f16d2ae51fed1acbc8335c103f721f46023cc2043f568ddb033aa5f2157e52b89eed4571cb523fcc66ef5cddc90679633c2a46f45f1a86c975db4f6f37f9fcfe54809ccf75305bc9f242f26f30a0ad5f3cd71cbd31ac45ceed2dc8571142a09b7d3091a4838727b9a067927e17b7559076649b405dfd480627881489d52339d4a8943ca396e92b92066e45d525acf7785a944345d25d721d6a354b1a9f3e2afd379d1c341badd0dd913a3471a5b78a81c0b338a2984e115d003b1deec1b44fd19824279d742017248fb4434cf47ad07fc87df86e634b2d8f6e0aa572088678b9a9f767404f06c84ea8cbf65d46effbde7de1f090d3d4b9e7c7c3b2b1dfa9e591efe12ffe0fc82c9eeb7fcd9f25fe438b39c46614438d0be7e1dad11bce8b91396f867531e8c45d8c01119abc2b20be253779b5e651bd80536854e2aabccddc5f4fbfb3497111fe9a8f8a417ab4dd806745c82126524ec325c931ac1f31a3cea19e159e1dbfbfcff761cccabefad38062872fe8a45a14781ba12551befb31c21150a56ccacf9815d8f458b1f591c71ba7b0459e7c09a4eac5c9e5b2984314ecd2f7054ed055ba082204f7ed62b1d513cd0992bc10c28bc745e30b27f6ca28ac84dec6cf0ef73c971ce12b2ddcc0d6264d8f7dfbba0a20f8ff1d7387cd9d9872f4b345b409950d66ababa9852f7f5ee634dad6085666956b97e4c9142dbdce96bf42d1334c61d04ffed5ac8f12a5075ac87a7416fd52579a876c89e22008759a93ebc57279215e178662a064bca65670089ec688532468c07161f56bbafbfa5655768123e713c7aff52852978e9d6004ab3a434d9b5c73f0d90dd1fe742a169a84f0e96a189bfc5265d8c5e2d9e42f5503d04ce01f9a912bf8b9bd8c282a4d40bbeca55d14971d1d305a16eb85d02b4edd8d35baea56156ba12f4e344dc4cb34509fc780ee97d24173a75e49960ec32055710bf8119d005447c6c391365737a0cff68d9f44868b97b2357dc051ed7fcf590b32292624545935e87f25e56b3e4a2b9c39c4936b5be9030b4711f246623264e0370291b675e75e1ce9cb425e5fabcfb55e25f084ea8a1b84870135ad997f7b700876691939cf268204669790a10ddd3d38cd22252226a09fddd395482deb561ee834ba452750d5b8e0de63c77c85a7446dd5bb29df2620f98e07bdac4cb59af8b9dc64d427dab780257e252e8d6793fd1b99f7c3162b4233a418526ab227d40b9deadc943d0f108a38d7a6b075465a44c920c0146338504eadf826cae345e864452e94706c8dceac5cca87469f2183a9c918295c09eef65f747b7a3d7fb3d259c4f531ffe48a5c338717ceb45efb557a47a593fac85cfaa4c263c109d385c01a3193a6ad1be5923d6a53e6c369a2b5e704cd6ac3ac255954c3fca1079895c596596873c1309fdcc5f36fe039d06806dd16cb00bd028edd6b44fb1e9ce4a020362824bef6a59502cce4e1d3d3884d7d865823deb092916a215ee73bdae1d4baf7f294caac7f63a36c2a15a40517438b8cecb93a5da3e11c25ff228ef3e7281360a2ce3ac66e69a2f136a83fbdbc44dd1737e9a31bdce16df9e118345ec1d9a9c47bfa60502722c9813d31c9f1b0364e2e25d77a0816db52f7e86bade9aff644df50b1cea9a339e76e869fa1fa50101f8182a2a6aee2e90d242d4b4d6b999d1c358a8d9297b6e0e2ec141c2b3692d70b141a213d477e87c52a2c87a5c6d1f0fb091f35f50915878ac70000000000000000000000000000000009111b212a32363b",
|
||
+ "raw": "0x50f91c64826d6180843b9aca00847735940083045f289400000000000000000000000000000000000000010180c003b90a20fd3c43f5fc7807747a73e1d8e78cd9e611ad6bbba9b264534594174b49082aeab827927b335526cc50c2f0368fc666efb79c34af8ee90427d1718736acaad47f5959b9b26457619c07c2dda553d55a7498e30a37c92909f6b37c246dca4e8fd24d4cccd811396d276e5d11f1e8d14bb9eb4d5ec49798202422edd57ea4d8c0e8c6388e9c93a0ff2e52f7ca2303e40300c50c926a7da22919be462e2dcbdb3ec235b14290a282ee76a04f4bf7c5e2ec5c8fc0aaac72ce4f8fcf0d42b9fc3c4049ab6dfdfa12623d89c0d96434a8e13cb6f79ad6f4a8102f9a0bfe582d967372d8928ff9d7d7393b22ec1386ee91dd196eb9c349a6a12f7504e66a096eec0a8ae98e62275f6b84fb40a81a390c6ef0102c8fd2c11d303745b8fc49e638e6f3004961724a977a18d81efc67e37d0d44558e28cf9015dfa08eff82004c4a53dfa40c2451fa03a987f70c855dbee37e36480863044165e6d46d4c43278091317beab6f301d61c8f54f94ee88fa358c9aed6e55b80b4196e79a3d7251ede25c4baef8129882a69789df3a8262941199ded7bd381de00c257199c18e9086d9ce3f72c6d95c0a4d109a3a15474805f0dc06649a16a7805e8d74bd1af7658f5f9ef726d560595ff9f072d4cfaaf61283087843b904b0f5670ca551079c759d4a2839a71505e007cb5d49b0437b87a080fab5e2efdedd1d01f0f1ab72f0e6129a2525fc6e9829b56ce9d9f287a5bd80be8b1556e4ca82eafc60ec22315448768a72e45d4d956c16ee48a0658e307f81ee0f695f1b1b747d1d533d8da720f088b64608b1edb2d4d27247b2cd35e3d94e1256a3c5c944bbafe07b55ca74df4ec0b869733ddb466717a16e98af4ec310d046c90046c024fb33fbb2ffbb105d41bdd0e0af27b1239aa4d92b6ef8d727e51372fefc3b5c8bc6eb585a0ae2dd9970009555c2c2ced5e5a1e97c659565b6139dc4f3bae788e21f9658affa8fdb6f4733f7fa83fefab91a030f8ec976b8263c17abcef46dc22456d5347eea7c30dd25bdc3caad7cb2010f06573d56b6e5d28e6e847d8df8f18d6a2655ea66fe3c8e7e4ef192b5a8aeb35f8469277657b77155142c7b1653d5eb9cf9c4d69bbc5746e0c1876e330f9016a2f5343ec60b2f35ea380169a2bdf102888e6aae7e797d0bce73834f418018e8e55492da8236a542a999d9eea55bd52ee2e59feb0329d716c78c0bfcd79dc27cd9639399d2fd99d2fc9c4900ad60bdb8221501038ec4baadd2ac4830b2bfe1e20804c818c8e089661e7d842bc4e566fa0bc2d7968a44f8df0d4e88e494fc7bebdb695d3a8edf6a2703817b0f8c1a55569ac4a8ff0931137f075797e9744135a3fec6c767af26d4592a9022271a4052b1f1f24f072bd5ceb1d19e02b0bbf31251a7bb8b723bd3da02f59ca1c0c91bc10896970a1e0f8e0fd5b755da58d70be8935f65661629a9f833b35810113ce80125f8ed7a031cfd5eb1475b597856b4ce7629a9429d840a3457bbd70c05c73c6ce84dd59f917a24d06ca8743225ab8c266e209fbadf57cdb587df96eedf54c04fb3f83ec0dddd1d8bf9051c6de4db3aa099f1779f3f30f61f432e5c8f6b7ac4ee6c6dd6fce667556df155ddb2002735fb7addd8acf74863ccfe04a3088317634eb47e56b18c79f31318ac5e448a9094b5c2c70b44dbbbff7c235cef4701d504723b032726d009c6d7f527e645a23fc1ab478e6e2699211694d575bd436d778e7ae53868c63dfb78f591d82b979585cec8bbcde61f375e783e97e8f787fb392fa4f0bc3e9010aa9ec3cf6471bb16355c3ed3fdf2ee5b95ade86371d60fb0699a851770a212d0e0eeb3f20df78ab180343fd79a9d04d8dc56d9fe3d820b27d98d12275a40d270f4181aa1a18305c8d3469a954b2e85405a394684cc234702a6cb01c04ccc941a4392cf64ba31bea700d339152fce6abb0dbe84823b8d3b18258a29414fd52c91ccbc198e101287b79d8bd0e5f4b05a14a07055e66ea37d781934840a204638bffda400113bb1344126fe1c2ac1e57bb861c3d35349b1fba0c11e12921262ae52fb2e0bee444f8197e2817b9356e10af67e794a7967055936bfcb51f4be6fc5602a8df97ddcd73afe83c02f00d4f1d8302bd2e826d4c50fd3ded9a74debd0e807b694e912a8a3a800f5b983e171898874b77ea305ede4abdf0db5ca84a8a60b184374c08066537b08d42a609b97039ff8905bccc4454188b051c5d1e574e1e8b74cc5cbded064a5374c55f17002ee9b17447fdc324a12e3f2f414b491cccf20c9f98820461f4c7d61355a30f1a6cbb2fe7403b90587298fcc9500519451e44225c750b8b32a649ea288eda389e596390a5386652dea5d0e096ee270bcab9da0c3c4ba464f44172732a748e339cbfc8f0c1ee3187225e2fb29e67ffbd84df8acf759c817d628e03a245e9ae0cf00939fa12964e8dc124659eea8798b097ba52480532fa11194e4623ff63f6cc1d17c7080bb2c1459fe8cc9b197b89ba91986b7bfa61e514bf5c60f981e63baffd9fce44af87ad73fba197e46790fc03f8a46aa6d7590f47e08daedd7f564685208ee87da84b04b11cdc0c020bb26b0abdad3c1340649130e26af9c7651533313301e8b517a84c807d86a4c0cff68566d34da4111d67bdc77ef5f49ec7d83af24a143bceaee020acce02499c725ebc341a86d91c7f63dd962ffcc09fc0b5673873ee55cea4bba69b5058e4b364fb3802832d5118774790dd12eed78330412dc877cc034309a7e292ebee955a431fd46faf7884cf3bd5ab03d02b8784af2a84bb907ba5f021fc332f638a2d4b6451ea0a2cdee6ff1621d698eadfc99d6f405003f300e321a9e80ed3b577a899fa7dd891b53cab8acaa9fd3ce02640eaa75646f134c190817675b9e4a688d0668528fa3b378749bb6b1a0bd16873e89dfc927dcf568fc3cf94ac49d289ba1fb9c58a74574c8fbac321db256bf919e9432d6a8ae9a0dae900901f436b13d0c2b753a5eb6fcef03301d7faa15ff32ec0730335b13394bff66ea83a7043f9e1df5962671ff2d2759db234a4a4fa47fd3a9359bb14ef5b5fc398836d42afcc5d5f252b1b061afc6a0815b3a7586d25eed5ee52c56d2389b8f2438649ee652b431d3cc4262c6e5ea1c0ccec21aa6123e88b4bc933098576bd78cf5bcbbc278ee682029e05e91aac2043ad3ec1d3d97f6ebc6bd5faffa5bc71328cd4351bcb9a0d8d1ea9253b97b08c8c53b20e29703568d5d7dfa2bfa6aeb3a93043e4123116a125311695a11c8538658210971d7763ed7870c1309893909e306df22fe968612531e58a91d19dfe2c658ade19c8e0900c779af8ec333d19552e42cdedbe13ff85d99b10baf8daf70951290db56bc7ea049e6b468b6546a7f3ae77c2e14770eed1ea345f0d139336af4eee686ac2e73bd4262cb802e0173fb872a77cd2c0f3421c497b0260be79ae29d04d9a9da9d7bc101ae3ec9dace1133332f05b7b82aaee577c06c0d2a8eaa8a96db8b899cb3240cc4dca4f8eab513ad5b3529063b5df3664dde0db1e0ae5c29e69f011076fc7edc4261d043f38f1c68645466c9a5e685a07393b7e2f8f74db86742ba5ac089b45a42df3f943842747674c1653aa2a8ef282f64e7ec2ce1fada994288a5f9b95da4bc083ea008308b91213c74a08868ea0fdad9fbb1b485b793bce6e4fa945668b2351232a7c8a084fb2d87a5c83e7dced6bde3743617a7c4babcbf9381694b64d7e0feeb6615440e927a63293c6b695900b1e7afad1ae612c324a88e6761c3b6fdc41d18f514be1ba3a1ca53fdbcf8c19f95bcd60223abe52d07fd7c4114dad9f347cf122f6241429da7e598959c22692910323a0a699595398f518c58deea7159920d89e3e65702bc2cabea7e9ca0bbb7002fb7be5243bba6a08a12238ead443ff4394510d25eb279885d9112c44529f294c5a2bf493a74ba8f4e38744e632680b3ce055a897d2a5468ef52e6e70dc5af55a9fb83739f6cfc6994871662b8263f2e07e21a6514624909369e0138755165dd2af5a791da63c0604b68ff160fad82a578a06e76f62bb7e951b81d8fde2dade6c3a314eec5913151c16a93a5abd5ceb59ad96197a349721ab123b42f799dbde36d7965e0e5dfcf43d8d1ae13f4a00afd8dde36137d3de87f4e2c0366c18f4b3a449ffd9afc7c742c50456f6e642f7d09e86d5aef224b20ce5d8a2bf164484df8fc87daf69e459fc78c6b974cdb8fb1dccbd5290f560e3114302886e2828ad73ce71b06186254206743076c6af0c3d1facc36695dc28db1d026686b141247e1c7a9323d544b0079023cd2adedc0479ceefc8e0c34782603d0c27d18768eb5485a85bc385ffdfd25f735688a3b9a0c6f532b2a7989c751804de0163582293a17f635fdde14e9067f12929b079f89a53dfc87b986f89f718320ede83cf4086d0d095b24b66d5e3f1bfdb08b79cd5b25657cf2b20faff1d199c16bb7f631b33970b34c12997637447e4127db1bf580b339807637a86e0248cbcf8e1d30ae6fe053e2f9b7b3d0f9e3f4813af908b633560779012f9e06af00e252bb0df9f0caf7d1e82f8deb2ede21d13f406dd9ea69445d50844c95c921d8d1cbc8afbc5ddcd4157e65cbfbbafe2670e9146a5643db049a8d696f0eae07c3d4099447ef78bdb90fc05d7cc97bf9b9dee8719464ec6b9e6de866f73914a80396dea3900a9f7b43a47e648e20a9504da92c47ac65368813e5453e82020f8861aba2534346e6137e71adb28a5ff080365d6ea26dfc30ef5500d0760749d6e4e0f93aaebed544832308b19f72e92ebb8eaec2492c6ea7972fd359a8b67a1f4053bfb1a3c6fb720b5925a7a827e59b3bd0651b8014c77b25d61db17eb169cc2fa2442c82f68fb42200c59baa468a9fc92f13273ff071124f8b31e2b4b2517ee622d29489997ecb5676fb52e3002371c01004c214757b1f510091c2377a08d058209d18feb9b524a41712b6df4b92f2b14c583d3196749f367b3bbc8ab5e9e2615c511f23ba5fb1bac2ee9436dd8d162bd96f1fb663d2b520ba7e8ddfc2a4d549b63714654cfbb37ee1dca5f723139187ada8f8d5b42ad09ff196b70720d2527b4466d44f33cce486ef2e86311c75ead31a17b16989dc63bacf0d465379d9138df7ea2ebc71f4cc3b6662e24895050e2553dbc160a567d6722964a904d43bf2684206cee3562256e98addf3038e968cf6c09c921e2c89c9c249f6ba7afd20dd27587b4143f704f2738315a91c2d40c467111b4f3bae4f77bae402145e742ba83a527aeffca13ee2290988df882feaf5a3c24b416d59e06cf4f8832a016ce55419b7bd2028545557528a0af23f17942433e13fad089fdb79449bd9d99b0324b1828791249b6789a09cdfb6ec40c0fbaf8b28ea4f72d3df5159bea7a7965b94beb1bb01d87d76ae7ce47fc333fc152038ab4e7ca64a802f96f2e92bcc53ad9cae0242c622c99b2daf005e554cd6ba127991d84841ffe3ba0674eb7930509045dd00ab91a7c6acd2f4a40e7ffc9959929851e40d417f488a29f7bb5af3847a8caa5daa0682aea870ac8b866ccfdc435971e3d862c2f651cc6eb8a33fca313a56ab8228ee9ac7dce14ea3c3fba4f58c70888ae558d8cd632a2723ba54a3d538f4e20936a2ee543e9b2141e06095c72d4ee19908febf7c248c03a78655420da644746e2d508c31ceb0b648800d95dceec72f7576502046e5dce54b5a097f625001bfc92d6e4633b293cdfa63b1fca5de9e26d03ba2f1cf3647dbdad5359ed76bf702f0621c057dea3617af678016aa13360ebb02c6cb2fa0d3f137a1a3c639c989e12383841ab7ca5a84f84c08af4b85416ce7ec3ed91636a79add207bedf9dfb2ff626387f20cb3315502b2b06f361cbf6a51fb507598af41c5a5b9cd95ba1894ca372c5e1851e62a0d3d78dab6f92bd43ba6fcd71230b6cfd843d89268872b75e3c5b471db530b7ab5451dbe63fa0bdaa7d74907cb376643e129febbe6ce10b5dffbf323dc973f097d2081e06aad65e674c5a41bb81b80556fd78691fe6b5bfad47fd1b64db577f27f22f17973cbff3a7c4aa43569bbe6843d773a2f933f472650e88e0ec6643f87dfd37e7fba915c7386a130b8d4f0ff4d0e99a633d1f863f3e8ce4e1ac5e31438d89c3b6d5ace3aa6e14e7073164ea01e853958bece389316023127f9916297a47c5d6ab5513bab874c1ae3bf2850cfab9018cbf50a7febe03ff3e8e4e55ae5632812b6a147edf051b461bfe56f01a6ab571e0553e37a57a3a9811f4fda2e189d79b74215d6fe199595d18c6543c747572f8cdc61a53ce09d9ca96b43a5af5b56b53148dd4fdfc1e22c9958caa783f2d112d8d5fd39e6955df75d35c59a1967fc0d8d3293e39a6cdf82d6846b39a74b1a538372c266b3f12d7ccf464ff7e32fe54342994f51d344302b3b2e11eed2187a741eec99ef0a79a19a854c03d8bd3fcd557b9d8bfb35f0976da327fc7e8d95fb43db8e66be5b373385fc1b68099566c7e88aefe92c7c521d084c15c8d403d87bbc975e8d687e2a51e5ce53191e3db5bdc50f475853cda7cc5a7365c41035aecb61444c2a48492a600b58300b2805be97b4e9e30526e9e62bb3248a17c3809219307ca85351495c943a865359c783cf615a809c739cce0786c6045d9c8071797001434cbae571d42cef415e28ed6adab09ed10e0713dc1412ed80b8d26d549964321559137483c81b19203080b36abcd68e841f4c78b5302da79fd6e555f390322ae67e54c55749491889d79eb2982fc4428086bd1060c4113137ddb4dd7c9b690b802e805999d4f5127f66f6b1d397dc3509504e2196513b5787407b45b928cfc3c437523daa4f876dfe061e351cb3bad99ea205ab276c4f2a5ccee1027104f09adaf55cd282d4e9e44ac2b65f7e423da1cebb0ac70691347e7a7bd0de8bc9fb2e7a08afc0075a0e85902316cd6ec9a5802c51a6d65bf3251ae712ae0f66de6cba1e51efbad53ad7e769f851799caf5fb81ef35b4da814915dcfa67553f1c67158154707d16804be27af2115559e4758b313b9da4a1131718b29a75970b3f0a5e2f2c11a0a1ed47f238c145dc4fe9e8e963d8395c67dfa94a232b8133a0d953b05455f79e0bdff0bc3de9c04d93d97084ab99229622cfe3958ac5fda6757de1696b575f6250b441e6368386751b1d2f6007d254d152fe76578fbbe164af49cda805b9325f7ea47f5e18f3de1ce38006ae1bf027d3e354d6f923d8bc6286aaf9b9a7b9e7a7fbd36a31db0d88166dc68e7eb567d8164bed1e279a8810fc21656621ff7cb42a21ee04e6086924bb62dddd16c3343db69250f7ed95aba953202640bef18dfb6c00f1ee03c670a5cc6c0f3cd7cb006590dddffa6f19d450860e289f85edb4fb0dbbd2f992eebba09cddc1b20a3c98d8739ad1875a514b09b1f23cf406c4c55cc4266e0b8b283fa445849316c30bd19254e9d035756d2773cab7f5fd56d6d3a094a717ccca43251201cfddf80ba1aa0dad34f5a3acf8476b784fd53a1aff1307a7838705112650bd25dfea21b991d801f018a5dae26edb9dd5a0ab940a94b7bbb90fd1f30f9d1dd2ea3aad6d0a2a3c42fd2641233c7d624314c3a54ce616d2ca5683d04f6fc0924f0b667be32f4de8820f9cfab963a287a1c708857ebabed9b5bcc35d539ef9bc170636cd528ba86a620195134cacbc2b8e742376124b67ed8155ab53979e281f97b184c60355b008f15f45c8b7a506b1c1f511e4aaf0bc32fee27b656b01ed6afaa4053ed674a60175b6c89a77d42963111d0940730db02ff67534fe6a296e0e01e2db6b3f0fe9648286a0f3420cd4393163662751deed6457abbb370f83ed92e9da86a0181df13b8ef33e5718ce524a700ba5f2b40f3f973a67c1c412dc251c19e6b7ceb279dc1dfc36a3567e3a98a9d96ef52b0d0734f57bd9edebedd925167f230b1c81ca938e94ceebe43d2573735873a436331a8b76c1169c6a869889cb74e5d33721bbb99ec87f160c025f570f1d11c2e3ae6a52580785d854790139510179b003418dbcee1f4fd4fa39fc134521ffd7f29cee650472638dd04d8331ee439eaa32c57b56c4fd9c9ba87516a8236dc99b8d6e4c2a48e53a6779d5e13bbd73cc7917f0cfb8e231218bf33bc3c213599eb76476558f0e38a3979cdaad6ac6b03bd0ef0aefec634fbe0e1e87bd78123a19b7352326b9def856ecfc02b06622f94e8cb2a1cb6cf10d020f789a7db775063030f15b463f08878219636f2bb94ed11a3ed9689d797a3253809c7f2e0c60672e8476a9e272075c7f808258901e611c4d535a11bfe01daccaec3a26a187ab45a9fd0bb9a7ecf2e9c4aa3177ddaca1449f19f78ebe26be2e25bca012a10649b56899339f5418925648f3253bd716336dcf65e6b4f16d2ae51fed1acbc8335c103f721f46023cc2043f568ddb033aa5f2157e52b89eed4571cb523fcc66ef5cddc90679633c2a46f45f1a86c975db4f6f37f9fcfe54809ccf75305bc9f242f26f30a0ad5f3cd71cbd31ac45ceed2dc8571142a09b7d3091a4838727b9a067927e17b7559076649b405dfd480627881489d52339d4a8943ca396e92b92066e45d525acf7785a944345d25d721d6a354b1a9f3e2afd379d1c341badd0dd913a3471a5b78a81c0b338a2984e115d003b1deec1b44fd19824279d742017248fb4434cf47ad07fc87df86e634b2d8f6e0aa572088678b9a9f767404f06c84ea8cbf65d46effbde7de1f090d3d4b9e7c7c3b2b1dfa9e591efe12ffe0fc82c9eeb7fcd9f25fe438b39c46614438d0be7e1dad11bce8b91396f867531e8c45d8c01119abc2b20be253779b5e651bd80536854e2aabccddc5f4fbfb3497111fe9a8f8a417ab4dd806745c82126524ec325c931ac1f31a3cea19e159e1dbfbfcff761cccabefad38062872fe8a45a14781ba12551befb31c21150a56ccacf9815d8f458b1f591c71ba7b0459e7c09a4eac5c9e5b2984314ecd2f7054ed055ba082204f7ed62b1d513cd0992bc10c28bc745e30b27f6ca28ac84dec6cf0ef73c971ce12b2ddcc0d6264d8f7dfbba0a20f8ff1d7387cd9d9872f4b345b409950d66ababa9852f7f5ee634dad6085666956b97e4c9142dbdce96bf42d1334c61d04ffed5ac8f12a5075ac87a7416fd52579a876c89e22008759a93ebc57279215e178662a064bca65670089ec688532468c07161f56bbafbfa5655768123e713c7aff52852978e9d6004ab3a434d9b5c73f0d90dd1fe742a169a84f0e96a189bfc5265d8c5e2d9e42f5503d04ce01f9a912bf8b9bd8c282a4d40bbeca55d14971d1d305a16eb85d02b4edd8d35baea56156ba12f4e344dc4cb34509fc780ee97d24173a75e49960ec32055710bf8119d005447c6c391365737a0cff68d9f44868b97b2357dc051ed7fcf590b32292624545935e87f25e56b3e4a2b9c39c4936b5be9030b4711f246623264e0370291b675e75e1ce9cb425e5fabcfb55e25f084ea8a1b84870135ad997f7b700876691939cf268204669790a10ddd3d38cd22252226a09fddd395482deb561ee834ba452750d5b8e0de63c77c85a7446dd5bb29df2620f98e07bdac4cb59af8b9dc64d427dab780257e252e8d6793fd1b99f7c3162b4233a418526ab227d40b9deadc943d0f108a38d7a6b075465a44c920c0146338504eadf826cae345e864452e94706c8dceac5cca87469f2183a9c918295c09eef65f747b7a3d7fb3d259c4f531ffe48a5c338717ceb45efb557a47a593fac85cfaa4c263c109d385c01a3193a6ad1be5923d6a53e6c369a2b5e704cd6ac3ac255954c3fca1079895c596596873c1309fdcc5f36fe039d06806dd16cb00bd028edd6b44fb1e9ce4a020362824bef6a59502cce4e1d3d3884d7d865823deb092916a215ee73bdae1d4baf7f294caac7f63a36c2a15a40517438b8cecb93a5da3e11c25ff228ef3e7281360a2ce3ac66e69a2f136a83fbdbc44dd1737e9a31bdce16df9e118345ec1d9a9c47bfa60502722c9813d31c9f1b0364e2e25d77a0816db52f7e86bade9aff644df50b1cea9a339e76e869fa1fa50101f8182a2a6aee2e90d242d4b4d6b999d1c358a8d9297b6e0e2ec141c2b3692d70b141a213d477e87c52a2c87a5c6d1f0fb091f35f50915878ac70000000000000000000000000000000009111b212a32363b",
|
||
+ "hash": "0xe37a3c437aacfb3f7abe9bd9da80fb8a50398a56e6b60e6fd29f08abd049d9d7",
|
||
+ "intrinsicGasEstimate": "236504"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-1.json b/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-1.json
|
||
new file mode 100755
|
||
index 000000000..2ad914461
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-1.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "wrong-chain-ml-dsa-1",
|
||
+ "expect": "WRONG_CHAIN_ID (when validated on 28001)",
|
||
+ "alg": 1,
|
||
+ "raw": "0x50f90ec5820af080843b9aca0084773594008302d5709400000000000000000000000000000000000000010180c001b90520372c0f4874450fb92ace74d41bc0326c7f739589f9b86a97afa87ef65d5939e608c81a44909e41f41931349f744b7aedff8d5270b91c4a2f61192e2bb6e3e6d12231deab235359e78ccada386becb6a6a1105afc0999243ab8b363f7cd2c19b2b741c9969dcf20252f20d130dc05d9244f58d6de9b4fb4b6f0125c43b60ebe3c7272b6ae7578f1abb4bb5e2dcb31eebf4aa7089aa2bf40a0ba5eb73aaa90e45472168738cb0e866547e079075d0341c4728ed794cd449d0cdeceaf64d09173a2677e3f2621b56014df58ee8de2bbcf8cb2bf369e57a28e40b24df6d0b15d3417b7b7fce3c49230b3bb7c7080c4f1344380db37299d8c0c29a7c9e95bfc4f3ec70b767895be6ad798449f94c92f320696f8f9ec844fc9451f5ab30874e6c78673b932e24a918d5bc03f4fa647c8679631ad8b30ba4f9a1a790a535104f5079f781fa4c4aad807777327e08bd6e14b957e527650d39e2de7d30da7b2b27457d3539c2f99903054bd1a6d6301b2f83249db80dedc911059b047b5552407ed32b79b57ea4968198decf978fed532277fb189841d0c17f261f1a7c4618c33b258a71cb6b2b921c48735c1fbc375a80fe2d702e9f70db34547147f6d65153f1c508ff90aaf57dfde59ce6e56c5c52049b10fbc2640cd937bf5027d755444cd5e84aad66be4ccf04f710f0b970cbe7fc5e4e7a44f5d8fc2af94ec6df87862dabe0d85dd17e43728800d5dc8ff9e9e1fd349b9d6431f264836a447646a1ee2d73e6a4d1803d71b98510d94d53b5d07764400f413b7837f463e273980296ad5e78a62c83fb91354c25c2e28bfa19480ca41b0ca2d8beed456029eabc0ba69cf3504cf1207ab21bed0e3a60795f5b066019132212a9bd20e98b43bb32484454b7693bc63764d0ba8768da4336ad16a979b1d3e8b06e89afc4caafaddead83ad861a4596814062468d8cb2e131e71cf38c4e335bb3d1d9629251fd50a4273999a20e11d9a881fa2465c2ef32301fa8805ccb38b4656e3c815b54ef42f292d05847c0e5149b0a2ffd1719fcad10730b763406e9e453d2e4a556c397a984a7d8622466522e79f715f980279cb2d1d74d5fd15f8beb8df9c0a1fb93f0d5494ab701cd60cf2b613b484a191d873449c4815f44eebb62658ef90f7033a5e48d40c8f4ec9a25d4f1b73a150e5b03a4feec9142362e77d74d364bb8a40f9873efa2d9f458d84277fdb0063642d9ebc794356368a0b4e53f6ab0d9acf4418fa42d05c11db12cb67d6c4cbbfde4d85358abaf8042510db53c1540fcb40045b334bc54a17608e82433d1e9e53c99769b86b69b8cf1914584cdef479061718a2cc5bec5c31272e0463139721c0c3523a6ea31832b5c15aa59819304c217fbc51a2636bfff331e6dc1037e89be15c17d6708762976329353612f312b828e525c09b81afafa5ae5c25d82b70b6e55f892429a93e5eb4048ade675583e828da988f9d253123a06c0ed047adf4d93d20cc6c865f5a761fec27811305165cd4bda05f563215d0612944b88ade9d64477ae8fb441978720e70b0d77e2edafd3a2c571cd28a42cca2f289d157cec813c24e7f56051b4f28c153adfbb2c1ff90ea1fbc03cb89603387169072442f5d3081140e2256ebadcd775d2f1da92c15a9ff1ce6e980b3b1e91a7e379081ed46a4259fada21536af318eb2043ea16cece60b73acd415d239389cad9212e15bad1b1ae38f93c756635a9b87417faa844e4f43bae1f1ae68641a04f0ff1d55f9045cf7e3ed59fde5c07219b9113329356d4300885ee19c9955c5757db33c6ae75b49d035003171d02ccbd7321d6a14db0bd011d4877f04070dbda3b67bf22d083eb90974dbb3fe4443f9160a432bb4e436b97eb1dddeb445ac5e99b3ecb7573e7d8306ca2c9ca81e4c0b9cb4bc8a19222f0f45910a0982bd3c78abccf395a5d87c9ee78cfd7d902808c21483a0e99137edc77073a35ad680dfe59c284e489272a85481bbbdd14158024750fb2762a931e06a16079056458fe2bb97ed55419da0798f94ec35767c7511ce7ccc0e626152f8b566bd71377dace697520cfa5aff622276c0e5cb0a970cc3795c889258daa614042dbe34dcf258b8aa52423035182399130f3b140164baf8caef8e9767f31db5beac2872907bce2550f448ebd74184f8bd28fc2ef9aa9e2e6625895fca23bc190983377c16b98ffb338e78ca6d64bc95fa90258a375240d11fc8cbbd8ea8f18ea28567ac02184342e61d6c6dcb3fe04cdb8ce967cec1c9e205114304839c81d5af6895401ba809bb81cac66062bb5159cdbb36b644927d99bd2ad337ef7fde1850b6b4776b7f484f4aa0b9a2a3bc69b4ae541bb6adc3cd5d8f9de83a5543941a97b2e0ff61700f834e90a74c2de3a0e02066685c94e3e08964b9f876772aa3e04be45979dc7e1df55e8c81d45bd07379d3f672509fd5faec33122e17f08c158948dc23a1bce964f6f665e7cb41e8994ddd2f01e8d5552227925c85985517e703dd10c79f4d77721bc28872048f7feda6197ccbfb0560be1e013953c76b9262a178642b0be5628880950fdb8bea2ed6b301b2751a8fe1876b8ab4d5f34dec3bc95b3d01dd1c53897c8cca238b7b7ce99175e3bb8547daef19d7399db5029106cb37b67d70dd131d6cbf97ccadff5fd2bdf83b0210d94ec7b1ee8c1efdc5646d704fc79544026b62c176259f3bb3de1d0a0be8ccd9d95370083a78fe4a0269484907e88051f16ed1e9da53180f28980e0951b897e3ab2694412ef3fab73ecf4ccaa14b236d4aac95b1d943d563c0194b6fdbccef0c92bded1d856684b98e76ee8832c64921f999f1908c5d8ebb9d5895ac48f976e60d636b99f327532932b44170e94db91b268e5e1024e2e15ed126800e7cef347cc58743fd57a9b7511e4e95d422a8e6b1022cd6ab7816a6afe1fcdedba4915ebf5a459e8b26d3c848276ee3b0a8202a3140e968a2686506d34960d96e86b309864754fcbfd128b816346fdcc04b8d14faff7cf5ea31c7422ebea74a7a524548bc57cb38bcc8d8689c90a469d8f0105a6f0cf2e7c24933a7993988389f5066bb7385e1ed75992c75c3df24c0a08c3f2162f5bab574b13dae648904d6754f92e1354190e706f1bc45ac71473c465fa73d784c09fe7fcab408e1d808dc5c318a0a6db8219121958f35046abcfed9d874f60dd18376fcd844c333ae7dc13353449082c79f46e9d7a2eaf71a7c54867b04dccef0e3593ce939e12e395e5b69a9a133e4a2f3140f17f89894b70bb7f21082621742249f544464f1995693f37ade71ead1de00701beade7e60d857c7c00c5431a4129c42803d00cce4f3765a9dff1ca90fbd27ee23f3a75baa049fe6205a24aa0a621ac5126649644c4b0cd3cb78d5db9460dff55761e5ffbae250c6365e632d953291efb1f891a614d52c8f882a7c867725c427eeeea2229c424bfc00ee7f4b186c8c68daff492d317733795f6674a44e3bc276e013f28c75fd176c53d8f6fe39675562bf7e0957a631587c0e76112da49f057786a976110ec3fa93e589117f1346180af06f2954b49ac60b4369e49b53b8ac068aac4e107294791eec204ac6ad869342cd55e90257893f92e3ae3c598be9cce120d674a8c128e46951a6b8817033aeebf46c55a1c9aa23d48c03b24ce63786fd7946c4be1f1dde7e6beb733f8f3a8ac8363ed03e1434669e7aa048ae77176b393c9ee6dc5febb7b8ca0b343e78601ca958f87600561c3bc4d32cbc0a31c0c026ab7b5f7659c15ea8d71709b9c5d3d377702097345ef51efc9c9384cddadae853e0d889cb835cbac3ac59370fa6395f9ca44a4a6250fb55181c83d14c1e4b5ec25ba3211abe634fac46163998739787b76a9f253eb83d0e9a9955859748cc42503b95624516bc41bdc12fce27d495c7326cce0e25d831261ebb157954913fefefc24021d90dfb342749507a899441028a24c5a678b636b26c8389737dd40c10f37c0d07ec8655247f149cc9dbb3567b2c81507c07f17944cf617477d692b6024d2000416fd75de3463eab6752130eef9d3400362c82c44fdc950ea47ac75ae25bc133b8c48f8bb9bdc6d0c7c109aadd7965b87a122544a14e72e219d58d237e7795cd3132e7802b8c370e8c14c170ec3026b5572e393e62cedb243a376d302e6573d75397c72b507a0e39a4b9c87c8fd6f49330e35248724217cc9782bcb408f5ec6f1510d334e31978c6ef5baac79444fb7ed56bd6eaf034d0dc32a66e3827886aa3c10327cb9bb7c9fab27bcd9a97c4d4181d06b7fe82204a369a079c6bbe454de03b87daee2b76390c701a26372cead63e99513d354dedea2a0b5f1788302ace68679fb52d6f11a17ea658616d4f625c1d3da587949e048acf37c4980125ea1e8666f85e37ef13af70c2a4219d9cc12fc0855713ec9c139f1bf41f34f0b787a08afc33814ff0e7530c22946d0b33ecba6d7be579e0a5644f6a4ee5a4088bbec8ab100faba7edbee3238a8fe55f4a19b45babb17d10cad5919a01839e67c256b66c84571a460f2ef287c367562be9e02bcf5e2a2bf1036b4a61e0393d58acc5554691847f8d972f48cedd46902b7c4711841bcd9d6186cfa462df62a78cb924429994a56f8edc2466fe9de98bb87c75d771cf41528174d7e0858b00b3398e59a7cd32a64ab4958b03724dd05f00915d08ae5356d605494a2728bd06fdbabbcb6b1bedbb83239a91a5ea9132f1aff725414898b5a848279c0f789900ad0c57b9a8c8aa3f10a19095b77e14f08389423411c59651ccf228fc0c0e94d0a057a894acdf7280c05fd56c7171659686383ebc6b19a93c47139f3ed455c0e642a49bea837a451cb0c6ab2073ce13f6b72eb71cb138ffaf668d41b8a6e94f1a9c216a33bf0532f9e9b4ed22944599f90ccc7162a0132113359dacb2793aa80c1077dfda1799414bf3dd0d2ebf84663c0f5762429c9ac94755562a7c62d90eb6b99233531d3bb7115b346c4644e94e78ea0a11ec4b1d18ee61891aa47bcf3988bae06fc01428dc32d5012ff32d1d2c17e1a7e23bfba427ac10a5462d6fecd35161296da85d00e3a59d5e6a68a38dd0e3f3f03b157321ab52d551bdadf30223f81df4d9a477bbf25c8ba80bf835f3e1012783270bbabc02b4f29ddb269784ae6d1323416f8a9799a1a9afc8e2e3e7f5fe0d1d2e4b4f5a858d9c9fa9b6bdbfd0d405091112383b44a3acb5bdcbccdef2f6475867838bb2c6e5eef4f9fa00000000000000000000000000000000000000001020303c"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-2.json b/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-2.json
|
||
new file mode 100755
|
||
index 000000000..cf1ebcd49
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-2.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "wrong-chain-ml-dsa-2",
|
||
+ "expect": "WRONG_CHAIN_ID (when validated on 28001)",
|
||
+ "alg": 2,
|
||
+ "raw": "0x50f914be820af080843b9aca008477359400830383209400000000000000000000000000000000000000010180c002b907a05424000ae9a496294dd6b99046cfdbb235ae71031b379ce274c13b0c96411740cb61021a5390fbe8fb56b642b4e5e5abb7aeab143e0037f8db283b9f2febd650265ed6b05f1b867c124aef245c1811422f92414447fd0b20844e0f1b1cb4eec052400aad52b9d773aae0015c0c390bfdde3d367bd8ef9c3c73bca3164b9d418ecbb2d25303bbd12739a858c5fac4cbfa0203b9f3c319e9bc89d17a7a244b57d6613b5caabdb528f077eff9727015b9c266d777c0ba11920118c7ec4dd59b380c40e361a5b23ce04be4c61e12a1c21e091fa0d890687cbf588944db3e34253c75cdf797378de79162e0b4ca309f550365a289f652dd6d559478912cff70a5417589f73f14640970694d7b5a6bd8f000a65c632f0326ed3d128fda96dbea68cb812634dd75e9f63813a5645336681378b6a63220c066550aba43a5b937131d41f08752d13949a115a74bf96fa1925ff4338e10df0301abe40aaa49e14a1a1d58eef005a0f1d0299267002cebeda20cadcea7419cd0c365c53aede1aa36efaf764d3d36169747cdc8ee9a09e0a0ac6bcaeaeded0cd303c965d705d1b91a8b35f408ad8a033b02ff57610bddbfa60e2114e53f20f8fcad15dffac6a494c3f4f631590f2be3422af14cba7c900c9c38796952e20c3069bea2ab54bf0edf9315903aa5cf68549f878eafcc77561b36f8b78d950871ed4914417316f868a2bc54c72d3c9929f0138a2f0cbccb7c4141e94bb8a7ae11f660861cbbe498697d7327709271460a75bd4e024de3d4d6fe5af066944c96ba87459fa948a95eeb61abbaf643190ccaa9cd18591eb6f249a6eb92db89fc95616d21b41d7d15424b80a750938a12cd57d50ef95aaf222025dc4d81df320d9bc32c608b1c5a1aac8bd14c0f7a4c4380cdd65c793a6287050ff4d609102fd91e47e7365fb55513aeca273618528c199f7bb151e9c11a0bf202147734d1be9d5d0e9318096fa567317ed9fa6a8efe201b915b9aa05ca0d19e15c9a80449cc130b398ebbac3d938f55eea8f74e024b0e33dfecdbea02b920ddc5b277146685916194bfa1f8ac7784c7ed76923d4ff9ed97d3ceac283f9b26977df0133c5fa4fb5fcec577bc152e926529f06ff50c204c083c0b4d6b8d474cf5cf7cfcf7acf76921225443eb0abf5e4c76d0a3f524243ee4e372e80ff0f76dd9d135f240114a2ebe6d69609b6c60d275f251d7dceadc600d18e0cf8bc8fa8392e61fa32b8f7481c4883e19d820b51af0f87d3f7faae44e3b908fc759c6de59361487d8e424ffbd662d57a68801110e9cb099214143253949cc479eaae0e321fecab90c63b06819ce3cf56fc2fc1419408075c658024a28950aa47d549bcdb8b5bc9aeab463466c7834ca7d73058c206a95a023f0c8ac95badd383e63041e1f0ef69f51634f5ce2f48d80f8f2e92f4a1fb5322930141fc50e1e20bd235a8b8d768d473b46711257d028e710f82f0b6bd923da05ca64ae805f708577e125b3fca2feb5656f61ded034eaae481a195628801c82db85345f9ffdc72c860cffe2264ba4be2a08fdb37a4f5f80276baba4ea637847335c89dbd35504389f68b2d61ea66d4eac5fd0057d9e757d929214a7d83daf2fc2b3f840e083792d20d772584b252ba955ae8ae8c36af648c59ae0b25d3bca19413fbd749077b6969db5847409d13e4a67387e59116fe3836a733f3253d47f9919f49618fac8edf5fd711a4239447655d6c40f479f86ef3c9d4dc1a6f9683a3f1bc5c9730025e76ea1588d43494f59823f42c207e34412f73c7e2a126501b8fb810f12995c213063d909a5a9c2653d3511ceb809efa69c638f4c977d46a2a305cc831ecc0feebf5d9356ede6c780da78fe2ad683b3312282d5142612c0d1f85108de04de5c3d5414b62826d5b75f8887dc2d932c40f306c08e5d4f69ef4d344fe4317552df9890d0961e3d857bd9b2c5b44536d8606f62f66d14ddd43b0e5d3379cf66d664616df12b1c62385a57f6a562c34e120b79d64ca39d8b23e1e07b2c03910d711f09df5b54cb0e133dd751bea7832fdb38de2f1dafae69fbdf82b6887ff0a92940299020a835b958bb01b25b8699a0846614cb256a6621ef92e4a0947df9141ed4f91eca527aef25862158a8fa712dd60dda947f6a16e077810e29542a56f9244c34a73454b9ad0d8e8c40bd503efe12c4e5bf7d0ff8e6ab642a039f4e8b575d33c0c3de77a1abfa60b0252d7a549dd791d9630c8b848988157608448d77938bfb27beaea8f9b4a259263797c5b2fbdc7f469b2769f7dcb7b9478cdf5f109322eb2f0a83163469b72d8121fe8e01df227563cbd941a1f63961e2a010c6322a812a014279583a0066492a17d1a15c07024f6b8b1561041b3db608ec1c7475ce4d086e60523e85d7a955841558a35535d6e52cb166669a69049646b94d2fdb901ffbb1446a2d7f58696bce000ccbbb6942b0ad6480d006602c228218d3a2f0bc6a5d5c73acda9fc4b0b496a7d527050f8d77b71641f030368e9494bfe8e9dbf6dd4040426da1b0423739b40450273f4a8d551637e5fe3ca8d54fc476e6278e75cebf4a4ac3ac8ef3807041c4b274568797c8caaffae7df08c6c158d92411db981ea02cc212064c3ad6a9cd1cc02087acce5ceb8d7cddaec429d199c3d90670288be6e88e6826d1f6c417df5f35139c71a62c0267adfce7cb3aa49e827165b28c8cc157a691cb52ef103d8d7ca0ebfc628904d0b2d365dd3401b620d6d93cef670e2fb90ced0f4116f56457e97077c6728c16d27e9876b13275f1e5fdaacdf89ed7d20f7d53cc974910a84cdc1aa3c1289de7ce0a80dd983de4463d77f3390e4a9c64baa94cd0f8e31cb21844698ec396abb704d0886c9ef5239451d5a9c328564fdcf5203a0f6cca322d20e25a21a6d96246cd64ac993e175af68aa3ed24b210cb1822e8526257427552a8a896fc3ad77ac0a87bb1d574405d7ced0467b62c49470365adf9e16c492eb671ccfc637e4b9dd0a32f9de2a51a8970d431d8ad92e0cc265d8c6d165469da63fca1f189d70c51e911f624c3786b42e3b3a8c372842cbae99d6afdd2281251c28adeefde311b8bfd0c45e67ce6a6ec16193fd9bbeaff975331eb112c326b303748bd0d28535b73bb1a179b4ef4eba08f42c2dda78366631dfcd78944bdc9058169461baf34386bfd505b119ab6b2c9b84b9b130bb7723e601ce99257925bf06fa80f5ac9f0bd3d00044f71451e72354c0e20408548cbf68de3efdcf93b4383820d93c5fcbae49ecf9fa027660bd9f91613be07d7eb3cf2153588094db67c578447d1302b402283a05e03265d33c0f0a7bd7fffc77c2092a67a4a0983d0a6539bed110abca2a292c7c8f5eec9ad3cfc085708394705bd63d386eea1aa4b22daae2ed1685f17161b7df3ede14455504195692c683908273d73f0503ed4cc7c1c61288a17193923780fb50f9b020e08977c6d25ef33373ba13ebda30c38fc1a2d87d79b846f2ec4511e2fe77eb60fdc46811f055a646bd93de0b342177919f009be73913e21a9171584a1b5051f258fcf079fd474bcdb731b003a37403826cdee0e8ed0dbc9ca9b56cdc7e6d47c653561b47f3b3542a2c8c28777c13c72f4290e832452decb15cc5dd8c06283750af8c67694b40a8902e8f631d7b9447c84ff2122bf310f86cae68147e2357f8af55bbeff3d80b74f55c3e097681e593d0aa6a11ef2c3f55832f21f21bcefda9ebd539e4a11960ee8af8c609b7cdbda9580b278094058a30c5047f7a90b5b87aafb222afb7b80570cec0e3dac70d56592cce38ff1c4ae0b588f6cccd46ca44c77381a529aa712c8e4a806b1938ac1f1363912762be173e7d3f9e1c2dc2ca36ce29038463fa8697c268e68bb614e40ab18084c27746eb8b6b4a71ff53d509b877ac2532807d57694c7cbb1bc095092728374272e29dfb865393b9fedfb9ff0e67fec861da566318a65937254e65889cfe4c506e72e05db17c6094c7ee6ba48af6882582f5928d885daa934ceeedb494fcb8012f10253368df32f5951d8c6f319dd7800ac3fa437234265efb3fae1559aac30295de2d0c3e191551adea1d5da29bdb0fb81d8e1f6ff0e4579c31c8d5d958b06b2c9be37de43fe83317e079c18805836d72eda19cf86a97912187b39c0350bc790e0b760361c3b1558bae5fe841932dea5b84ac413661da37af425631c5f68ff4040d3c3f7b4bae3c74b0764d776d39cbde0b3c5d75f142ba111d4f604227900c3fa913b6d78d5fcd20df306b8b8f6dcf2321b1f90f55f81cec1b2599bbad1adabec95a2c4b0cfe0d429e056878af68871308cd2e21f94f6d6fef8b29fc9273aa97e6150d20c916e68710baa9b3de541b1022135151b61ce965d87d850eeccd4d74e201312d9ddf6952cb11f756f96558947f31adbf036179029c62dbc27815ddfee70b6652f257702a449381e1a7b66b5f550bf83cf23baac996f0b66fb405f5ed1400b5937d89e897dd40d70973bf716c97c81c1f9e36f83273e63cf489b26772a6d582fe3675137b934d1251cbb3d5bd4ab78ba886103ebe9864367a3048c3c0995e2bd2b76c97bb2e5c1d9e9c51244c202d33cd6a706f6958eff96bb47996a36f19e95350a4b2cd5a5d9a3e4c5240b5c6daa2bea47d43b4a10c767767ef81cab30be74d4891c6b64f0528d82a1e3053ea34231a2d10efa129d8d42ac32f9d8d0cdb559043cfcbc38968c8b031e40da7bc4add0f003c7e50216ad414ca3badb380de9c45713eb46965f8ccf77eae0beeb62529f21431597682605f4e07210a9ab9790b4614917c7b8f4db754cd57a031d03365317d6126de0a89ebe6ef2f877a64a9ec824ca8e6d0017c5249fcad3df09bdf09ced66cd6f840f151ec8a4db239bba62385779742ade58fbe56c4c79c0e8b271f77880953b8a39be239e729bc5fcc831993ae3fe8eb687527956a451dc7031428ebc64c9c426f77827adadd46b9384028a12bbbc4ec7cf7280f2d3fb2dffed142f13aa17f7d42405049d80dbb6ac9762ef56b947baff7012cf08c416935629de0ca1bd8a6f637d7416b780e898413284b16da24bf585eb288c85cac3520927bbcd07a1dfb8373b12ac7ab31f894074a15db8b033659c8e6160e743dc42228594e1db9f8b69f7d8334e75ec6288ab0da7cff63435ca2405f3d1e94b235dea4d61865f5e5ef73b3e86e28e624cab6fee2dd09d01f62d72d18a9fed6f77e660ac1cb3049a6cf0856d5373cda997bff223b10f59d76d6707fa7afc8c2dffe7a5a967f1340a18abfe9b64e3fc0822651a6c52c28b342842b830630c65c5e8cc82e8d06cba10b394207e72a4711d991e5851b3b5ca8e479c445b8c951d759b731b88ed7646f742a276cb4aedb8916c298a22c46103924f0b785febbc0d67acc5a869ba1fa1afda456fdd1a7bed9b29bcb5982fa0ee7eb2da5682f62e16b3a9754ac227df6b703e1b929d3b1142c6c616329d8a564e4a525a0e84194b365d1bd011c5bcac9812195ae3f60f6ec946f46cc2ad0ec7adade8ec2e5f70f1d6e65b20de2714f118ddd25dfa24c1b9c821af013cd54d363c0881a0295cf7129feead0336e2ff7df676665a392f57faf8bf1581715f3634049b2431c077709b3edba503de7a238eafc0c616f29ca4ed0b526ce819a6372f8e25e3f902e1fd7f7387b341948bd79bf3a1f81559138cdd455a098e49a68e64869b15806d363e7a5cd10c8e04ef7c7c28a2281e29daa999bf2aafcfdadf5d55b97c0dbf1b8e77a5351b26069b2eece2515fc08799a6f30896360b3eed3ca9056d5f2c1d8f761458fcc6d9e82091f6f0b3e954f73b9dc682c1b2e2be3d86c6da5b586ecb6d5ec9a57210e1c69467be07c9ebd1e363359274b27fdee6896043272af11e89ca047c388aa35d594d004c580fa87a46744f4f8be181ff374a362e753c8a48a9cf1060d176c08f01cef66e49b2ffc9b2280041ca8bd9cfcd10bc8e0058798ad72a45ed4566a9eed14aa4d03b6f691090515522b9466ee017f38cfdea83c92476f6640f7506862004d1a29c78575b8960cc50aac4092764ea5694dc21d84d65902f5c89384b687b9021ef3e66ed6d45a2f13c198ca722845f1d24b8729a766d2d1383573888b3405a30952c17e90cc6d4a9174bee6f1b0cbc8b449a36dea4593005938735ab45992733414e1bef4ec12368e575f5edd51a7b414fe67ad2c4fbdedb93bd350242fd4e285684e75ab4710982193459f779f7bd5ac12804098b53205bdfef7ae96f7615a52e35227ff29b8a1bd3ca54bfa1eaeaf2e84324119864ed4483fd9ca40fbc00fd5f72d7ca00ff9abfcbade3a8085392e70425691f8158c1ef9e173c10666843f3e14ba2fd5c78bd516e4a6503a11e06f39f6a5bbd657765317b1163f2ed9cbc687ec95515ec56ae75b64cc743c02442d02915e47b8c706ac70b0b5901fb61a5aa8bdc9057eaa42d43b37a5381266ecddd7510dd2a18138805758c2d41e896934cab73c61370ac959447e43bf5b629b904e7bba5ae8f959f923aa7844a898d150df35672635f304f8c55177e9185de1ef8ba82516d56bd27c7e7ba2b139a570f44f4085b275fa05d8f8e65b87a6e30570fa6846d227584ab63ae6293c0d0b8299fb53979a6e796eae7fe8f3439aa3a51889a8a5b1a4514ce597365a27cf5bec9e91558393ebfeeccc6462b7c25f6c03e251546d9fb603b1c25ab756044e042e2f325af8fc2cbb79fcf6f414bad1217cf96f21bb0d48c95c35abee171486d8bd0fa0b485b32f0e73dcf6f05a5475f95f3359634c4de53f44d1c53e4ec3264a82f635258c5b4d8bc912ba3b5503c53b1b239d44d3799a62dd3913871b0ed6fc87f186db1a40b2fe81ed197ab0df57c63de250f72ad592da936177e9f154b90625f76e86cbc2cd2f310d427330559b8b26f685a0a81d652562a3e3c70dd17e31b10b1c55208a551daec05aad5c5dfb32eb37a9dbfb4e43afdeb2d2dd27528c8dac2d043b0548ea7c2b0ca74ebf7dc4da83a8205d227e813d21808b11dec1ed78cc9fb489a0149eccc352e5d22f69b0c65993ec5de6f0ad0c20c936d35c26eb0f4cc61a0f64a376bd91ef980392fe99ef9e1845f1ccffd52b13679d164c7e917816daaee828a733ce4baeb1763ad59e9309ad1f6569dc7882b947032ce67ff0bb1f80362779455ce5741708931b8972ad67943161f6d2a9e4b376b07e3f5cdaff63b769b463be0c2e0a848211071e38709ce089d0413bf7bf9464fcccd03f16ae31c3a607716ff8f52eedabfc4f645c2ed293dee63f3434fb12b5024bb5cc16b0c03ebb2e8c2af1ef088e863cb75ecdcfbbb61ccd394954357e3baf7f7f2a137416073d0dbec002a60a5cadb5d678cbfe91d84bcd31b2144454c5677e64f9ff400000000000000000000000000000000000000000000070d12161e21"
|
||
+}
|
||
diff --git a/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-3.json b/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-3.json
|
||
new file mode 100755
|
||
index 000000000..85f6fec1b
|
||
--- /dev/null
|
||
+++ b/ethereum/core/src/test/resources/aere/pqtx/wrong-chain-ml-dsa-3.json
|
||
@@ -0,0 +1,6 @@
|
||
+{
|
||
+ "id": "wrong-chain-ml-dsa-3",
|
||
+ "expect": "WRONG_CHAIN_ID (when validated on 28001)",
|
||
+ "alg": 3,
|
||
+ "raw": "0x50f91c64820af080843b9aca00847735940083045f289400000000000000000000000000000000000000010180c003b90a20fd3c43f5fc7807747a73e1d8e78cd9e611ad6bbba9b264534594174b49082aeab827927b335526cc50c2f0368fc666efb79c34af8ee90427d1718736acaad47f5959b9b26457619c07c2dda553d55a7498e30a37c92909f6b37c246dca4e8fd24d4cccd811396d276e5d11f1e8d14bb9eb4d5ec49798202422edd57ea4d8c0e8c6388e9c93a0ff2e52f7ca2303e40300c50c926a7da22919be462e2dcbdb3ec235b14290a282ee76a04f4bf7c5e2ec5c8fc0aaac72ce4f8fcf0d42b9fc3c4049ab6dfdfa12623d89c0d96434a8e13cb6f79ad6f4a8102f9a0bfe582d967372d8928ff9d7d7393b22ec1386ee91dd196eb9c349a6a12f7504e66a096eec0a8ae98e62275f6b84fb40a81a390c6ef0102c8fd2c11d303745b8fc49e638e6f3004961724a977a18d81efc67e37d0d44558e28cf9015dfa08eff82004c4a53dfa40c2451fa03a987f70c855dbee37e36480863044165e6d46d4c43278091317beab6f301d61c8f54f94ee88fa358c9aed6e55b80b4196e79a3d7251ede25c4baef8129882a69789df3a8262941199ded7bd381de00c257199c18e9086d9ce3f72c6d95c0a4d109a3a15474805f0dc06649a16a7805e8d74bd1af7658f5f9ef726d560595ff9f072d4cfaaf61283087843b904b0f5670ca551079c759d4a2839a71505e007cb5d49b0437b87a080fab5e2efdedd1d01f0f1ab72f0e6129a2525fc6e9829b56ce9d9f287a5bd80be8b1556e4ca82eafc60ec22315448768a72e45d4d956c16ee48a0658e307f81ee0f695f1b1b747d1d533d8da720f088b64608b1edb2d4d27247b2cd35e3d94e1256a3c5c944bbafe07b55ca74df4ec0b869733ddb466717a16e98af4ec310d046c90046c024fb33fbb2ffbb105d41bdd0e0af27b1239aa4d92b6ef8d727e51372fefc3b5c8bc6eb585a0ae2dd9970009555c2c2ced5e5a1e97c659565b6139dc4f3bae788e21f9658affa8fdb6f4733f7fa83fefab91a030f8ec976b8263c17abcef46dc22456d5347eea7c30dd25bdc3caad7cb2010f06573d56b6e5d28e6e847d8df8f18d6a2655ea66fe3c8e7e4ef192b5a8aeb35f8469277657b77155142c7b1653d5eb9cf9c4d69bbc5746e0c1876e330f9016a2f5343ec60b2f35ea380169a2bdf102888e6aae7e797d0bce73834f418018e8e55492da8236a542a999d9eea55bd52ee2e59feb0329d716c78c0bfcd79dc27cd9639399d2fd99d2fc9c4900ad60bdb8221501038ec4baadd2ac4830b2bfe1e20804c818c8e089661e7d842bc4e566fa0bc2d7968a44f8df0d4e88e494fc7bebdb695d3a8edf6a2703817b0f8c1a55569ac4a8ff0931137f075797e9744135a3fec6c767af26d4592a9022271a4052b1f1f24f072bd5ceb1d19e02b0bbf31251a7bb8b723bd3da02f59ca1c0c91bc10896970a1e0f8e0fd5b755da58d70be8935f65661629a9f833b35810113ce80125f8ed7a031cfd5eb1475b597856b4ce7629a9429d840a3457bbd70c05c73c6ce84dd59f917a24d06ca8743225ab8c266e209fbadf57cdb587df96eedf54c04fb3f83ec0dddd1d8bf9051c6de4db3aa099f1779f3f30f61f432e5c8f6b7ac4ee6c6dd6fce667556df155ddb2002735fb7addd8acf74863ccfe04a3088317634eb47e56b18c79f31318ac5e448a9094b5c2c70b44dbbbff7c235cef4701d504723b032726d009c6d7f527e645a23fc1ab478e6e2699211694d575bd436d778e7ae53868c63dfb78f591d82b979585cec8bbcde61f375e783e97e8f787fb392fa4f0bc3e9010aa9ec3cf6471bb16355c3ed3fdf2ee5b95ade86371d60fb0699a851770a212d0e0eeb3f20df78ab180343fd79a9d04d8dc56d9fe3d820b27d98d12275a40d270f4181aa1a18305c8d3469a954b2e85405a394684cc234702a6cb01c04ccc941a4392cf64ba31bea700d339152fce6abb0dbe84823b8d3b18258a29414fd52c91ccbc198e101287b79d8bd0e5f4b05a14a07055e66ea37d781934840a204638bffda400113bb1344126fe1c2ac1e57bb861c3d35349b1fba0c11e12921262ae52fb2e0bee444f8197e2817b9356e10af67e794a7967055936bfcb51f4be6fc5602a8df97ddcd73afe83c02f00d4f1d8302bd2e826d4c50fd3ded9a74debd0e807b694e912a8a3a800f5b983e171898874b77ea305ede4abdf0db5ca84a8a60b184374c08066537b08d42a609b97039ff8905bccc4454188b051c5d1e574e1e8b74cc5cbded064a5374c55f17002ee9b17447fdc324a12e3f2f414b491cccf20c9f98820461f4c7d61355a30f1a6cbb2fe7403b90587298fcc9500519451e44225c750b8b32a649ea288eda389e596390a5386652dea5d0e096ee270bcab9da0c3c4ba464f44172732a748e339cbfc8f0c1ee3187225e2fb29e67ffbd84df8acf759c817d628e03a245e9ae0cf00939fa12964e8dc124659eea8798b097ba52480532fa11194e4623ff63f6cc1d17c7080bb2c1459fe8cc9b197b89ba91986b7bfa61e514bf5c60f981e63baffd9fce44af87ad73fba197e46790fc03f8a46aa6d7590f47e08daedd7f564685208ee87da84b04b11cdc0c020bb26b0abdad3c1340649130e26af9c7651533313301e8b517a84c807d86a4c0cff68566d34da4111d67bdc77ef5f49ec7d83af24a143bceaee020acce02499c725ebc341a86d91c7f63dd962ffcc09fc0b5673873ee55cea4bba69b5058e4b364fb3802832d5118774790dd12eed78330412dc877cc034309a7e292ebee955a431fd46faf7884cf3bd5ab03d02b8784af2a84bb907ba5f021fc332f638a2d4b6451ea0a2cdee6ff1621d698eadfc99d6f405003f300e321a9e80ed3b577a899fa7dd891b53cab8acaa9fd3ce02640eaa75646f134c190817675b9e4a688d0668528fa3b378749bb6b1a0bd16873e89dfc927dcf568fc3cf94ac49d289ba1fb9c58a74574c8fbac321db256bf919e9432d6a8ae9a0dae900901f436b13d0c2b753a5eb6fcef03301d7faa15ff32ec0730335b13394bff66ea83a7043f9e1df5962671ff2d2759db234a4a4fa47fd3a9359bb14ef5b5fc398836d42afcc5d5f252b1b061afc6a0815b3a7586d25eed5ee52c56d2389b8f2438649ee652b431d3cc4262c6e5ea1c0ccec21aa6123e88b4bc933098576bd78cf5bcbbc278ee682029e05e91aac2043ad3ec1d3d97f6ebc6bd5faffa5bc71328cd4351bcb9a0d8d1ea9253b97b08c8c53b20e29703568d5d7dfa2bfa6aeb3a93043e4123116a125311695a11c8538658210971d7763ed7870c1309893909e306df22fe968612531e58a91d19dfe2c658ade19c8e0900c779af8ec333d19552e42cdedbe13ff85d99b10baf8daf70951290db56bc7ea049e6b468b6546a7f3ae77c2e14770eed1ea345f0d139336af4eee686ac2e73bd4262cb802e0173fb872a77cd2c0f3421c497b0260be79ae29d04d9a9da9d7bc101ae3ec9dace1133332f05b7b82aaee577c06c0d2a8eaa8a96db8b899cb3240cc4dca4f8eab513ad5b3529063b5df3664dde0db1e0ae5c29e69f011076fc7edc4261d043f38f1c68645466c9a5e685a07393b7e2f8f74db86742ba5ac089b45a42df3f943842747674c1653aa2a8ef282f64e7ec2ce1fada994288a5f9b95da4bc083ea008308b91213821ea6fa73a5016d6bbd3227853ecb797d9d49be7e4f6fa69ba1f84c4f509491e1a07ad0af5fad203717c10931dbc67c1c1a9d90591f8951f595dc96357d91e202ebae7955f0e45245936c750840ffd8df89e0f2789e427c79ac48d58982a6e087bf4235920efc666854459d6e4979a308594b7284181a9cdc011b48e1520454c48443228ba54f286952331533db7bcfb04df5e4cde37ff417dc4444adf86a4c4cb15be04b0fc9cf292ff313ff1ab5d1ecbffd14fe67526d4b6bc29c838ccbb2a442d08df1f8686da94e80867f9cef8b96b62656778cbad55c43f24b0915e6ace48353025c135a5c33bce233363ded2753716e61f213b04f2c429a797460e1e4166fed83575632b70540218afe616cd89fb77a981f60952c58a2246bbecf6606c005fe50caa3c3669c5b019e3ba52773aecf0fdf06d570d4ebe10241fd5694127365088a8045523fa639f6df29c6ed9ecb839c27582b133867f2f4b9395cae52c2606176d8ef04d32ce7bd563fbd3f2f3b9f7fc0468bbb8c770a563c278e22acb2d8a59e5e37538f07b98fbcadee17f23e625e93e76188bd1ea77152cf39cf05e568b95a3f5188920c0e8ab46e4ad9d9e6533de563334cf5ed7cd4e62b43a8e9455d4d232903dda4774c7dd9bcd39b01c2744ad47b361469c54aa589a35c798365bf8e6748465c7fffa0b688007f5f814953f87c03c6b3bf682ba6e70adc817596410d1e581e8c0f237e889bb4d4a09be8514707573b6299414845ef8ba7c9fade369afd8b1d7078031ad82bea47e516a2e5827a67591e85e628930bc81f20a5733270b8285922eb6fdd1f23cbc47f34563578db8433eeb007c428e5815e15bf6232d1801a39deabbb77a1a2bef02d16cc88b975e1835c105bdc813f7faaf6eecf601a4a67e30053c7fc92aae3cfc52900e471c3e8b70da92395c6f46cb6930f1ca80fcbffe73d5c02208b62d5f5368d0c7fb25ee9229284e10ac2278556f7026ba0d3bd5fcd1e04120b728a2f308366757fe15d176f72df5e566a31aaa809a97745a20352d4d698d945da8476defb6052414fe086e326b558b64447e3c9dac0b1f4ce5a06e678426d48f3436597cba43cf8af80b94c3813832bacbcd5d7c167fdaa1ad13afdc0ced8c3da011c695a33724bcdd9902eb545ec9aaf7038cf39600b9dad3091adc79a8b0e6b2fb457260f7ff789dbf78431ac839802a8f435e0b29b3c236a4cf8c7c138896b6724ae5b3690503ca21977bc6c5e29506702292a120e59ef8269682389ecbd41fb5aae0f6f04d0bd1942a527bb5152eb57843c6f64944996972eee48cce5d8a69ced00b240345dea932b5e32e4056f959b77051f10da85b06e6b6b6e4e191463e5105f55f1772d8117448f4b5511a2423475130ce26bdec44150b872116667791aea4c083f3b0abe44f19f841019911236179d280653dab71efc7fcd82bbeb56e5ede3bd7958a94b9a1ff082d82586ea876f6f3f059dec352b6c69ea86043137e547b62937e7a806a445528fa15b71e8cc987c587d3382ac00bd307b2c2ae5ff99f30bd1d1deb08976f9214788735d772b2ef04d827280e6dd836de156d1ac3a4eb530cb4c701ca69d51de13a6681de8d57dda2787a14bb5ebd934993596f6a98fcbd50339f0222da1df81247c5a0d620f6cb4f5ef311bdc66546bd3a5e2a5af0efa3c6158d7a6bb493ea89d8eaca4c07ec56189283118b7cadf32abbe1f65293973a1a55bae933f09feaaa3c6058083bec065f15fc795dc8e824f1ce941fa09f4d3512f4edd6fcc4c5b2f10d059087638d2bfcdd3f9e24383fd7466a1982226f8696abc5df1e51648fc165c46a0012c49e33a0de4ed6ba6215889cc923c8746407d38d856eee5c6f81ddd1b12d0511c79c0c6d0e88d09fc5f2f16e3f09b4c1754e26aa554840e707836cf3cedce57e463e0aa1a7be552d07594f3dd77cb0e76d9412faa917abdd50b3ce779d8c81019ec9d947f5717cee5a4e98c3e30e60fd4f34c66b29be5dd96d0ec235f6340464948976334d47a0e49198e77980acb97bcf77243f5c9eafdb8e742120065b8eb4348027a7dd251e9244ff3a2776d1783a449bcfb4dc4b3370362bb68ae3a61f842def75fcdb248634441092e25530db3b7bc2ce203231387d34c8195dbf293a2e680a2dff9b74e30f2f00ce4e84a309f1255ab55af3b2ce5b7a50712cd1d13ebcbb48dfa08b5edda1621ad30eb3e72562a2d3baeeb741514ddba8234d365e67ee35adc7a7902df9ac3f3f885da7a9fc4b6580d97f2dfbfd110b2fe313dd2b023ae1e98488742cad89bf33303ea235ce1bfb87577a04dfd3c1e1f952422bec2c5ef6a90aef6c39777d2c1fc283261b734fe19ff85777a63ddf6da7b6434e2ea8a2f6d0db84fff632a1d8e596fdb92b8d93a7a9a9d2a113032f96b1ba8ccc804c797f9ea6f65453c0ac308d10113abdab820817805547c0f1c392eacdf950a1bb88a85679461d2e2dff041037822062476311fd328173a9718934c3f2eeb8e6cff5316d44d5a870bb90407936c8188b9f8d4a26e92124a220f64dba55fd4ca34c39fc575899f8bba24d846fdd53ea0c0be00a9a5079406fbee0e83cdf8f360238e2e2c36b1c61b525c42a60d86bb79240bffc2fe6e0f5d46b09bc745ca7919a872461409298c61deb8648ed88774eb701ef565a0e1fa69bbefb87157441546e21371b98925e06d51124161b7ae678b84ce504360206a84f388557b99ee7774fdd0f411f300198c9abf5dc20a4f97d675dfa194e77266b7d8d47b101a8cac292d8b9945d1ad42d1878e8f5f35b0ec80281f02d7bfeb65226ad77704d7f6bc30fbcc6a4be54c8d162fe9529af1370f44ceb0da10ea36d389b6936fc9957f04a19ea796d2c5face0c8ee7bb23ff2db8a0b77a1cff4b169ece8d636663a3bcfd2d35bf44c251b8689338b76914d17f968ceff5e8de1719631729429371e5faf9cbb2067e891c658d0cb98276b16851b432b885d94d8efaa43e40ce4d09a97c1b7dca5d94d595629c44b41e75d2cda9bbcfef02adee54b5367a687428f005a1324eb8411f4468b0565ffc6b17953fc42a015e9acd9ae1e078a54ddd3b7355109c0eb56ab28263a02ec012993ebefa4060e1dd6347414681e634843baf9ee268fdbe7d00f22d05356231488042d08658f350b47c525d468bf63517758bad63c83821375d1c9f1165d7a3c829ac39a41200aabfbf03e8bde55c379e0f8ea8f81f59784212ec997612fa1aaed3f3ab82035cb761365982d4acb7e4713b9850511c3ad88b0844910e0968333ea3dba07068ad671208d1f4704e8d4d5b55b6b3ea7a4a70d2cffea0e8927bb215c1c628fbdaa6ea2d62d9fbcf274b56d7ffd5639ff2626b37ebba7f7add88dd978a5743d673e4ec7c82836de153d84ead5d378d290b2fffb2e5095496e7ca773d2db364896700ca09f0148df30d7c9ad70448503849831a428f602182eef6353db3c68f3100501e2575e31f658ad8fbe6f6f21f6d7dd369ecd1aab3f944d25ccb12c5fb2cecc39d32587b479f787482e38d60da3b15757816c4d0de0ac1dbfa4f6feab2e15be5b343227dbcc11fda877e9231d0d4cce4fdb0e9b73d0946fb60241613d51b658a2fd828d0931b1d2b7cdd50ee00c6aa454b0483747647b33d3eb9a4ce5f46755ea957202286a0e414940c570f7b8da652f3c7a0ebb28dcdfbc0a922f9f19bde6101563f898877ae298a51264cf5c692d97c62efab162d6265ea36aa59ffc86ba42d9f17979df28eb2f77045dbbd99d53e3d4553a9b8d4c7cec4d74f4f3d6a24129f7d48ef74dabd2804acaceb715fae1462446a06da637d196f19d02830a3f7ba8f0de5df1d080dfca719d6992317284a5d250c644e9dfd86930fd7224f199c4f52b7dfffc9767c003d066c43e980516a1bb2fcc92a3d5de9787b5f34e3bfee0ae38b97f84bc9f521b2f4e5c34787a8ea0a4c4daae98753a15af3481c41caa45b78cf98452cb7ec13ece08355d16be12f2c5cfc6aab958cb6273117bcff01a34940ef94ee8afa76360afac39aaeed3f54e7de726c3dc224de85cd92f57f3b105db6ad3e5f194fa33646984de36299958effd36bb1f9510b79f975bfdada10b334ab6a7f0f8337f084a7bc3db1e7af1b8d6b6a2e7061a80efb4ff5d7198175eba1c12e6acbf5092f0de03789a7de9b0cb0b385ed38f8db4c65628f674768ae91d256faa8152595d1270ca3d54249a3b1df84097f81d618297bb042750aca4f20d5a056689a5e8cebca0c3e36cc6333a16b9c7052517b5793552c1f625f8ec14a860cfdda306fafad0b77c47b47136f61ed8b9baf08ae974012c43bc00501f8044109125d5ebb450063fc6a954ab1bdee806882f8e04404ba28b6136c94f8f0a9fed264f5943e90d0c0edec69c668813d34d54bb6e43d90a9509d9dd7761431cf02109cefe77ff28cbd8915c116023f38e8457638dc11e9fef20ff2a6fb5623760981c8d267a18a64e19b1b58bf038a54dc90ea235346bd44ec79f37a20c6171ddbaab5276ca4dac6ebd79e5683727ed773ed29993b07de6905a295fb90d01f2f275d6a4cbcb1b6856593451083b988d1a0fb1bfd316e94e9f006a8011809413d695316d7477ee7dc327451aa7abfd1b91984ee887708153ffe1a4294aa561692db5d097dc9df1136c2bf29758760a422afb7e562d8be5769dd192c46aa95e3c8f9b6ec7d618b365137908987a75be43e511bb99f94936f1ab5fd6f5c93dcbaf8d0c017f6a24740b9cd49a1cb38a4e34397ce65265ed7276706d875a98adc60a7267a30e7fb39ee43fc930e697bc23972aecbe8c4c9059b8a43a26d4214d5162de2b80e8317b2877d2396164bd7240b411517ca0f57eed764e3319aee03e3e13570e75292ae6fb8c09a70f270325add11b3c7b0095ec721a35adf071b8db007d7b9a2408b62c1b17f0388250bfbee0dd7b9aef7eb8ce50df5bb18c441154a9da18773c57731a4345354ae6e03d4e863504e2adaffd618aa7aa44789269f83af69fb32a9cfc7fbdd6b316d03e2a9ce31509e05a07cb6c6ee6e127dd3b1c13d89e50f7407fc2e9ab99c1f6c7129589a1c77242392e1e08724fe2f6de96e87b4c4506a963e84eb3461bc9e0cab6094b7dd291e8e421823a6bc48d0d1a242fb8b0ca0a7b1f4124e4c262d5294b465eeaba288047cf6f24b26bf17dfdb70b09082384bad7c357a9ba33e7b97f290b540906b944240a88efbf89bc909a917f533d2bd3881847458dd8c58032949b43e21323af420a7d90c23977162d68627fa8f8f28659cbf497876b9dba0f2916b89f447d76167acf7ae5fa9769847feeef93deaa892e1e3ba4fbd3be85c9fad2ac7f403614c2a67d06ce3417529a8a866a22c5c10aa5bf07e195ad79556cc366ed3ab2d2f713d60e7e62a1af637aa9bec3ed96ff952fcd7162da28cbcc5999a38b926cee893a7704e325f0724ac383bb2d6e48e3c35d0bae557963a675674d3bcb058531b8b12d1c692b61078dd9bf9b2eeec94ce172b434941eafffb982dcc73e22812cabace33b2516fa45ec3eb82d2ce5b0204340f7f153d4ec65b2f42ce29e3dc5bb38531b666e4fed6485d2c3fecd536719bf758eade6c96086b258947dc694be765b3b9d8286852b18c25f15eca74ab745ac106bb91e2275b69b129cbd14b1c07348d0d157c90bbbfc11af6b4960fbc666cb3c9e4a3c408e6f595a67179e4ca2349c270ffa3d1581d8b9ebf6e9684067d358b6de326c0e6b890bc05e3175662f4c6f44e09ed3305ed04cb16d0635ee07377a106c24e42abeae5efa977446f88b7bb5def5aca2dbbf51e519521d018b5c668622e2b55e66b9b8fdfcde3b8491852907848ca86732810216ea19a9964842c6a3811078e6d1e73ac0d876d14272bd649dc6502816d2e20f7bbbc3026cbef63c6ae6ce07af82a832a06e634c59ca060b9b385a23a8c8bb2651a98f94ba138bf84e5f5a2e60c51962597df442438d9ff5447595d4919ccb4eb362fef3ba49fd94ab48a47f88e2ff009aa09f83ceb512524ea34ccbaf392492aa19ba75a480c16ea43beb1bfe8e1077f2735543aa1131daaf325e1895da07dd555f5a03d9387ee8d0ecdaa134950b7cb1a006587d3121060f97d3ca36e72dc9934a49f6fda29d7dd7fa6755379a0db48f97cd8bdf6ff252b08534b7d377a55bb91e616263467fd381ab0a12947c590cda2d43febbb45ba5fdd9a90d306c20e1b661e62c76232003ba0cde7da5e40e40b6b10cc9b9cca21e4f13daa7a05572e808b2205c37e0628566aef675caf08fa26ac299e866bb58c9fbc420acb2f02bfa6802da6fe81a065de34185dc38a6ec1ddd4b6aa188faa7f5c515614dd1c8bf6870eadf7d2595ddd56185b073be9f18f21285999c6c64a928572d7859e76520132b42398596d7f808392a2da2640546b6ea4c21d24520d59748ea4b2bdc10887a4cc15161acdd462639ab2cde2040e333543525f6c82dce50000000000000000000000000000000000000000000000080f121a1e232934"
|
||
+}
|
||
diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java
|
||
index 4c7a60bdc..077f2be57 100644
|
||
--- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java
|
||
+++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright contributors to Hyperledger Besu.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.eth.transactions;
|
||
|
||
import static org.hyperledger.besu.ethereum.core.kzg.CKZG4844Helper.CELL_PROOFS_PER_BLOB;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.ACCESS_LIST_ENTRY_SHALLOW_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.ACCESS_LIST_STORAGE_KEY_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.BLOBS_WITH_COMMITMENTS_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.BLOB_PROOF_BUNDLE_SIZE_V0;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.BLOB_PROOF_BUNDLE_SIZE_V1;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.CODE_DELEGATION_ENTRY_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.EIP1559_AND_EIP4844_SHALLOW_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.FRONTIER_AND_ACCESS_LIST_SHALLOW_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.KZG_PROOF_CONTAINER_SHALLOW_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.KZG_PROOF_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.OPTIONAL_ACCESS_LIST_SHALLOW_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.OPTIONAL_CHAIN_ID_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.OPTIONAL_CODE_DELEGATION_LIST_SHALLOW_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.OPTIONAL_SHALLOW_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.OPTIONAL_TO_SIZE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MemorySize.PAYLOAD_SHALLOW_SIZE;
|
||
@@ -143,77 +149,91 @@ public abstract class PendingTransaction
|
||
|
||
public void decrementScore() {
|
||
// use temp var to avoid non-atomic update of volatile var
|
||
final byte newScore = (byte) (score - 1);
|
||
|
||
// check to avoid underflow
|
||
if (newScore < score) {
|
||
score = newScore;
|
||
}
|
||
}
|
||
|
||
public abstract PendingTransaction detachedCopy();
|
||
|
||
private int computeMemorySize() {
|
||
return switch (transaction.getType()) {
|
||
case FRONTIER -> computeFrontierMemorySize();
|
||
case ACCESS_LIST -> computeAccessListMemorySize();
|
||
case EIP1559 -> computeEIP1559MemorySize();
|
||
case BLOB -> computeBlobMemorySize();
|
||
case DELEGATE_CODE -> computeDelegateCodeMemorySize();
|
||
+ case AERE_PQ -> computeAerePqMemorySize();
|
||
}
|
||
+ PENDING_TRANSACTION_SHALLOW_SIZE;
|
||
}
|
||
|
||
private int computeFrontierMemorySize() {
|
||
return FRONTIER_AND_ACCESS_LIST_SHALLOW_SIZE
|
||
+ computePayloadMemorySize()
|
||
+ computeToMemorySize()
|
||
+ computeChainIdMemorySize();
|
||
}
|
||
|
||
private int computeAccessListMemorySize() {
|
||
return FRONTIER_AND_ACCESS_LIST_SHALLOW_SIZE
|
||
+ computePayloadMemorySize()
|
||
+ computeToMemorySize()
|
||
+ computeChainIdMemorySize()
|
||
+ computeAccessListEntriesMemorySize();
|
||
}
|
||
|
||
private int computeEIP1559MemorySize() {
|
||
return EIP1559_AND_EIP4844_SHALLOW_SIZE
|
||
+ computePayloadMemorySize()
|
||
+ computeToMemorySize()
|
||
+ computeChainIdMemorySize()
|
||
+ computeAccessListEntriesMemorySize();
|
||
}
|
||
|
||
private int computeBlobMemorySize() {
|
||
return computeEIP1559MemorySize()
|
||
+ OPTIONAL_SHALLOW_SIZE // for the versionedHashes field
|
||
+ computeBlobWithCommitmentsMemorySize();
|
||
}
|
||
|
||
private int computeDelegateCodeMemorySize() {
|
||
return computeEIP1559MemorySize() + computeCodeDelegationListMemorySize();
|
||
}
|
||
|
||
+ // AIP-20: an EIP-1559 shape plus the post-quantum authorization (record + two Bytes wrappers + the
|
||
+ // raw key and signature bytes, up to 7,219 of them for ML-DSA-87).
|
||
+ private static final int AERE_PQ_AUTHORIZATION_SHALLOW_SIZE = 64;
|
||
+
|
||
+ private int computeAerePqMemorySize() {
|
||
+ return computeEIP1559MemorySize()
|
||
+ + OPTIONAL_SHALLOW_SIZE
|
||
+ + transaction
|
||
+ .getPqAuthorization()
|
||
+ .map(a -> AERE_PQ_AUTHORIZATION_SHALLOW_SIZE + a.authorizationByteCount())
|
||
+ .orElse(0);
|
||
+ }
|
||
+
|
||
private int computeBlobWithCommitmentsMemorySize() {
|
||
final int blobCount = transaction.getBlobCount();
|
||
|
||
return switch (transaction.getBlobsWithCommitments().get().getBlobType()) {
|
||
case KZG_PROOF ->
|
||
OPTIONAL_SHALLOW_SIZE
|
||
+ BLOBS_WITH_COMMITMENTS_SIZE
|
||
+ calculateListShallowSize(blobCount) // list of KZGProofBundle
|
||
+ BLOB_PROOF_BUNDLE_SIZE_V0 * blobCount;
|
||
case KZG_CELL_PROOFS ->
|
||
OPTIONAL_SHALLOW_SIZE
|
||
+ BLOBS_WITH_COMMITMENTS_SIZE
|
||
+ calculateListShallowSize(blobCount) // list of KZGProofBundle
|
||
+ (BLOB_PROOF_BUNDLE_SIZE_V1
|
||
+ KZG_PROOF_CONTAINER_SHALLOW_SIZE
|
||
+ KZG_PROOF_SIZE * CELL_PROOFS_PER_BLOB)
|
||
* blobCount;
|
||
};
|
||
}
|
||
|
||
diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
|
||
index fe525c431..1ad11b019 100644
|
||
--- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
|
||
+++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.eth.transactions;
|
||
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MAX_SCORE;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolStructuredLogUtils.logInvalid;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolStructuredLogUtils.logStart;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolStructuredLogUtils.logStop;
|
||
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.CHAIN_HEAD_NOT_AVAILABLE;
|
||
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE;
|
||
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.INTERNAL_ERROR;
|
||
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.TRANSACTION_ALREADY_KNOWN;
|
||
import static org.hyperledger.besu.ethereum.trie.pathbased.common.provider.WorldStateQueryParams.withBlockHeaderAndNoUpdateNodeHead;
|
||
|
||
import org.hyperledger.besu.datatypes.Address;
|
||
import org.hyperledger.besu.datatypes.Hash;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.datatypes.VersionedHash;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||
import org.hyperledger.besu.ethereum.chain.BlockAddedEvent;
|
||
@@ -432,40 +438,49 @@ public class TransactionPool implements BlockAddedObserver {
|
||
// Strict replay protection is enabled but the tx is not replay-protected
|
||
return ValidationResultAndAccount.invalid(
|
||
TransactionInvalidReason.REPLAY_PROTECTED_SIGNATURE_REQUIRED);
|
||
}
|
||
if (transaction.getGasLimit() > chainHeadBlockHeader.getGasLimit()) {
|
||
return ValidationResultAndAccount.invalid(
|
||
TransactionInvalidReason.EXCEEDS_BLOCK_GAS_LIMIT,
|
||
String.format(
|
||
"Transaction gas limit of %s exceeds block gas limit of %s",
|
||
transaction.getGasLimit(), chainHeadBlockHeader.getGasLimit()));
|
||
}
|
||
if (transaction.getType().equals(TransactionType.EIP1559) && !feeMarket.implementsBaseFee()) {
|
||
return ValidationResultAndAccount.invalid(
|
||
TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
|
||
"EIP-1559 transaction are not allowed yet");
|
||
} else if (transaction.getType().equals(TransactionType.BLOB)
|
||
&& transaction.getBlobsWithCommitments().isEmpty()) {
|
||
return ValidationResultAndAccount.invalid(
|
||
TransactionInvalidReason.INVALID_BLOBS, "Blob transaction must have at least one blob");
|
||
}
|
||
+ // AIP-20: not admitted to the pool before the activation height (the next block is judged).
|
||
+ if (transaction.getType().supportsPqAuthorization()
|
||
+ && !org.hyperledger.besu.ethereum.mainnet.AerePqTransactionSupport.isActiveAt(
|
||
+ chainHeadBlockHeader.getNumber() + 1)) {
|
||
+ return ValidationResultAndAccount.invalid(
|
||
+ TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
|
||
+ org.hyperledger.besu.ethereum.mainnet.AerePqTransactionSupport.inactiveMessage(
|
||
+ chainHeadBlockHeader.getNumber() + 1));
|
||
+ }
|
||
|
||
// Call the transaction validator plugin
|
||
final Optional<String> maybePluginInvalid =
|
||
configuration
|
||
.getTransactionPoolValidatorService()
|
||
.createTransactionValidator()
|
||
.validateTransaction(transaction, isLocal, hasPriority);
|
||
if (maybePluginInvalid.isPresent()) {
|
||
return ValidationResultAndAccount.invalid(
|
||
TransactionInvalidReason.PLUGIN_TX_POOL_VALIDATOR, maybePluginInvalid.get());
|
||
}
|
||
|
||
try (final var worldState =
|
||
protocolContext
|
||
.getWorldStateArchive()
|
||
.getWorldState(withBlockHeaderAndNoUpdateNodeHead(chainHeadBlockHeader))
|
||
.orElseThrow()) {
|
||
if (worldState instanceof BonsaiWorldState bonsaiWorldState) {
|
||
bonsaiWorldState.disableCacheMerkleTrieLoader();
|
||
}
|
||
diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java
|
||
index 86592933a..f3b958463 100644
|
||
--- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java
|
||
+++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright contributors to Hyperledger Besu.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.eth.transactions.layered;
|
||
|
||
import static org.assertj.core.api.Assertions.assertThat;
|
||
import static org.hyperledger.besu.ethereum.core.TransactionTestFixture.createSignedCodeDelegation;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MAX_SCORE;
|
||
import static org.mockito.ArgumentMatchers.any;
|
||
import static org.mockito.Mockito.mock;
|
||
import static org.mockito.Mockito.when;
|
||
|
||
import org.hyperledger.besu.crypto.KeyPair;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||
import org.hyperledger.besu.datatypes.Address;
|
||
import org.hyperledger.besu.datatypes.BlobType;
|
||
import org.hyperledger.besu.datatypes.CodeDelegation;
|
||
import org.hyperledger.besu.datatypes.TransactionType;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.ethereum.core.BlobTestFixture;
|
||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||
@@ -173,40 +179,43 @@ public class BaseTransactionPoolTest extends TrustedSetupClassLoaderExtension {
|
||
|
||
final TransactionType txType = TransactionType.values()[randomizeTxType.nextInt(4)];
|
||
|
||
return switch (txType) {
|
||
case FRONTIER, ACCESS_LIST, EIP1559 ->
|
||
createTransaction(txType, nonce, maxGasPrice, payloadSize, null, keys);
|
||
case BLOB ->
|
||
createTransaction(
|
||
txType,
|
||
nonce,
|
||
maxGasPrice,
|
||
maxGasPrice.divide(10),
|
||
payloadSize,
|
||
1,
|
||
BlobType.KZG_PROOF,
|
||
null,
|
||
keys);
|
||
case DELEGATE_CODE ->
|
||
createTransaction(
|
||
txType, nonce, maxGasPrice, payloadSize, List.of(CODE_DELEGATION_SENDER_1), keys);
|
||
+ case AERE_PQ ->
|
||
+ throw new IllegalArgumentException(
|
||
+ "AIP-20 transactions need ML-DSA keys and are not generated by this test");
|
||
};
|
||
}
|
||
|
||
protected Transaction createTransaction(
|
||
final TransactionType type,
|
||
final long nonce,
|
||
final Wei maxGasPrice,
|
||
final int payloadSize,
|
||
final List<CodeDelegation> codeDelegations,
|
||
final KeyPair keys) {
|
||
return createTransaction(
|
||
type,
|
||
nonce,
|
||
maxGasPrice,
|
||
maxGasPrice.divide(10),
|
||
payloadSize,
|
||
0,
|
||
BlobType.KZG_PROOF,
|
||
codeDelegations,
|
||
keys);
|
||
diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java
|
||
index 1b48609ac..ccbf03c38 100644
|
||
--- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java
|
||
+++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright contributors to Hyperledger Besu.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.ethereum.eth.transactions.layered;
|
||
|
||
import static org.assertj.core.api.Assertions.assertThat;
|
||
import static org.assertj.core.api.Assertions.fail;
|
||
import static org.awaitility.Awaitility.await;
|
||
import static org.hyperledger.besu.datatypes.TransactionType.ACCESS_LIST;
|
||
import static org.hyperledger.besu.datatypes.TransactionType.BLOB;
|
||
import static org.hyperledger.besu.datatypes.TransactionType.DELEGATE_CODE;
|
||
import static org.hyperledger.besu.datatypes.TransactionType.EIP1559;
|
||
import static org.hyperledger.besu.datatypes.TransactionType.FRONTIER;
|
||
import static org.hyperledger.besu.ethereum.core.TransactionTestFixture.createSignedCodeDelegation;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.INVALIDATED;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.AuthorityAndNonce.NO_DELEGATIONS;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.AuthorityAndNonce.delegation;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.AuthorityAndNonce.toCodeDelegations;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S1;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S2;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S3;
|
||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S4;
|
||
@@ -1789,40 +1795,43 @@ public class LayersTest extends BaseTransactionPoolTest {
|
||
return this;
|
||
}
|
||
|
||
private PendingTransaction create(
|
||
final Sender sender,
|
||
final TransactionType type,
|
||
final AuthorityAndNonce[] authorityAndNonces,
|
||
final long nonce) {
|
||
if (liveTxsBySender.get(sender).containsKey(nonce)) {
|
||
fail(
|
||
"Transaction for sender " + sender.name() + " with nonce " + nonce + " already exists");
|
||
}
|
||
final var newPendingTx =
|
||
switch (type) {
|
||
case FRONTIER -> createFrontierPendingTransaction(sender, nonce);
|
||
case ACCESS_LIST -> createAccessListPendingTransaction(sender, nonce);
|
||
case EIP1559 -> createEIP1559PendingTransaction(sender, nonce);
|
||
case BLOB -> createBlobPendingTransaction(sender, nonce);
|
||
case DELEGATE_CODE ->
|
||
createEIP7702PendingTransaction(sender, nonce, authorityAndNonces);
|
||
+ case AERE_PQ ->
|
||
+ throw new IllegalArgumentException(
|
||
+ "AIP-20 transactions need ML-DSA keys and are not generated by this test");
|
||
};
|
||
liveTxsBySender.get(sender).put(nonce, newPendingTx);
|
||
return newPendingTx;
|
||
}
|
||
|
||
private PendingTransaction replace(final Sender sender, final PendingTransaction pendingTx) {
|
||
final var replaceTx =
|
||
createRemotePendingTransaction(
|
||
createTransactionReplacement(pendingTx.getTransaction(), sender.key),
|
||
sender.hasPriority);
|
||
liveTxsBySender.get(sender).replace(pendingTx.getNonce(), replaceTx);
|
||
return replaceTx;
|
||
}
|
||
|
||
private Optional<PendingTransaction> getMaybe(final Sender sender, final long nonce) {
|
||
return Optional.ofNullable(liveTxsBySender.get(sender).get(nonce));
|
||
}
|
||
|
||
private PendingTransaction get(final Sender sender, final long nonce) {
|
||
return getMaybe(sender, nonce).get();
|
||
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java
|
||
index 52771a088..4dd3f52d5 100644
|
||
--- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java
|
||
+++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java
|
||
@@ -1,33 +1,39 @@
|
||
/*
|
||
* Copyright ConsenSys AG.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations under the License.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
+ *
|
||
+ * Modifications Copyright contributors to the Aere Network.
|
||
+ *
|
||
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
||
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
||
+ * found, as section 4(c) requires. The change itself is in patches/0006-aere-pq-transactions.patch.
|
||
*/
|
||
package org.hyperledger.besu.evm.gascalculator;
|
||
|
||
import static org.hyperledger.besu.evm.internal.Words.clampedAdd;
|
||
import static org.hyperledger.besu.evm.internal.Words.clampedMultiply;
|
||
import static org.hyperledger.besu.evm.internal.Words.clampedToInt;
|
||
import static org.hyperledger.besu.evm.internal.Words.numWords;
|
||
|
||
import org.hyperledger.besu.datatypes.Address;
|
||
import org.hyperledger.besu.datatypes.Transaction;
|
||
import org.hyperledger.besu.datatypes.Wei;
|
||
import org.hyperledger.besu.evm.account.Account;
|
||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||
import org.hyperledger.besu.evm.operation.ExpOperation;
|
||
|
||
import java.util.function.Supplier;
|
||
|
||
import org.apache.tuweni.bytes.Bytes;
|
||
import org.apache.tuweni.units.bigints.UInt256;
|
||
|
||
@@ -139,40 +145,53 @@ public class FrontierGasCalculator implements GasCalculator {
|
||
return clampedAdd(getMinimumTransactionCost(), dynamicIntrinsicGasCost);
|
||
}
|
||
|
||
/**
|
||
* Calculates the dynamic part of the intrinsic gas cost
|
||
*
|
||
* @param transaction the transaction
|
||
* @param baselineGas how much gas is used by access lists and code delegations
|
||
* @return the dynamic part of the intrinsic gas cost
|
||
*/
|
||
protected long dynamicIntrinsicGasCost(final Transaction transaction, final long baselineGas) {
|
||
final int payloadSize = transaction.getPayload().size();
|
||
|
||
long cost =
|
||
clampedAdd(callDataCost(payloadSize, transaction.getPayloadZeroBytes()), baselineGas);
|
||
|
||
if (cost == Long.MIN_VALUE || cost == Long.MAX_VALUE) {
|
||
return cost;
|
||
}
|
||
|
||
+ // AIP-20: the post-quantum authorization bytes are charged like non-zero calldata (16 per byte)
|
||
+ // and the verification itself at the algorithm's flat cost. Zero for every other type.
|
||
+ final long pqCost =
|
||
+ transaction
|
||
+ .getPqAuthorization()
|
||
+ .map(a -> clampedAdd(16L * a.authorizationByteCount(), a.algorithm().verifyGas()))
|
||
+ .orElse(0L);
|
||
+ cost = clampedAdd(cost, pqCost);
|
||
+
|
||
+ if (cost == Long.MIN_VALUE || cost == Long.MAX_VALUE) {
|
||
+ return cost;
|
||
+ }
|
||
+
|
||
if (transaction.isContractCreation()) {
|
||
cost = clampedAdd(cost, contractCreationCost(payloadSize));
|
||
|
||
if (cost == Long.MIN_VALUE || cost == Long.MAX_VALUE) {
|
||
return cost;
|
||
}
|
||
}
|
||
|
||
return cost;
|
||
}
|
||
|
||
/**
|
||
* Calculates the cost of the call data
|
||
*
|
||
* @param payloadSize the total size of the payload
|
||
* @param zeroBytes the number of zero bytes in the payload
|
||
* @return the cost of the call data
|
||
*/
|
||
protected long callDataCost(final long payloadSize, final long zeroBytes) {
|
||
return clampedAdd(
|