Update RPCs for yParity (#6119)

Update the GraphQL and JSON-RPC endpoints to provide `yParity` instead
of `v` for non-legacy transactions.
Update the JSON-RPC tests to use the Hive data. Add tests for Shanghai
and Cancun Blocks.

Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
pull/6136/head
Danno Ferrin 1 year ago committed by GitHub
parent 83ae69a6fa
commit 228424215c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 17
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/01_cancun_send_blob_tx.json
  3. 45
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/02_cancun_get_blob_tx.json
  4. 15
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/03_cancun_send_blob_tx.json
  5. 15
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/04_cancun_send_blob_tx.json
  6. 15
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/05_cancun_send_blob_tx.json
  7. 15
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/06_cancun_send_blob_tx.json
  8. 15
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/07_cancun_send_blob_tx.json
  9. 15
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/08_cancun_send_blob_tx.json
  10. 43
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/09_cancun_get_chainhead.json
  11. 94
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/10_cancun_build_on_genesis.json
  12. 7
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/11_cancun_tx_count.json
  13. 74
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/cancun/test-cases/block-production/12_cancun_get_built_block.json
  14. 10
      datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java
  15. 3
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/Scalars.java
  16. 17
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java
  17. 27
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java
  18. 27
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionPendingResult.java
  19. 29
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDetailResult.java
  20. 3
      ethereum/api/src/main/resources/schema.graphqls
  21. 5
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/AbstractEthGraphQLHttpServiceTest.java
  22. 7
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java
  23. 29
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHashTest.java
  24. 15
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/graphql/eth_getBlock_cancun.json
  25. 7
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/graphql/eth_getTransaction_byHash.json
  26. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_blockNumber.json
  27. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_contractDeploy.json
  28. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract.json
  29. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_insufficientGas.json
  30. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_noParams.json
  31. 24
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_feeHistory_fieldNamesWithReward.json
  32. 12
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_feeHistory_fieldNamesWithoutReward.json
  33. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_illegalRangeGreaterThan.json
  34. 71
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockByNumber_complete_cancun.json
  35. 78
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockByNumber_complete_shanghai.json
  36. 38
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByTag_latest.json
  37. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByNumber_illegalRangeGreaterThan.json
  38. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_illegalRangeGreaterThan.json
  39. 19
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_latest.json
  40. 19
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_pending.json
  41. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_illegalRangeGreaterThan.json
  42. 33
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockNumberAndIndex_latest.json
  43. 33
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockNumberAndIndex_pending.json
  44. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_latest.json
  45. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_pending.json
  46. 94
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
  47. 9
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java

@ -16,6 +16,7 @@
- Implement new `miner_setMinPriorityFee` and `miner_getMinPriorityFee` RPC methods [#6080](https://github.com/hyperledger/besu/pull/6080) - Implement new `miner_setMinPriorityFee` and `miner_getMinPriorityFee` RPC methods [#6080](https://github.com/hyperledger/besu/pull/6080)
- Clique config option `createemptyblocks` to not create empty blocks [#6082](https://github.com/hyperledger/besu/pull/6082) - Clique config option `createemptyblocks` to not create empty blocks [#6082](https://github.com/hyperledger/besu/pull/6082)
- Upgrade EVM Reference Tests to v13 (Cancun) [#6114](https://github.com/hyperledger/besu/pull/6114) - Upgrade EVM Reference Tests to v13 (Cancun) [#6114](https://github.com/hyperledger/besu/pull/6114)
- Add `yParity` to GraphQL and JSON-RPC for relevant querise. [6119](https://github.com/hyperledger/besu/pull/6119)
### Bug fixes ### Bug fixes

@ -1,5 +1,44 @@
{ {
"request" : {"jsonrpc":"2.0","id":34,"method":"eth_getBlockByNumber","params":["latest",false]}, "request": {
"response" : {"jsonrpc":"2.0","id":34,"result":{"number":"0x0","hash":"0x33235e7b7a78302cdb54e5ddba66c7ae49b01c1f5498bb00cd0c8ed5206784bf","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","stateRoot":"0x11045a28efc7c00a52a201e55b8d4c312971a930432e2b5380c20d2ce217385e","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","miner":"0x0000000000000000000000000000000000000000","difficulty":"0x0","totalDifficulty":"0x0","extraData":"0x","baseFeePerGas":"0x3b9aca00","size":"0x244","gasLimit":"0x2fefd8","gasUsed":"0x0","timestamp":"0x1234","uncles":[],"transactions":[],"withdrawalsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","withdrawals":[],"blobGasUsed":"0x0","excessBlobGas":"0x0","parentBeaconBlockRoot":"0x0000000000000000000000000000000000000000000000000000000000000000"}}, "jsonrpc": "2.0",
"id": 34,
"method": "eth_getBlockByNumber",
"params": [
"latest",
false
]
},
"response": {
"jsonrpc": "2.0",
"id": 34,
"result": {
"number": "0x0",
"hash": "0x33235e7b7a78302cdb54e5ddba66c7ae49b01c1f5498bb00cd0c8ed5206784bf",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x0000000000000000",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot": "0x11045a28efc7c00a52a201e55b8d4c312971a930432e2b5380c20d2ce217385e",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"miner": "0x0000000000000000000000000000000000000000",
"difficulty": "0x0",
"totalDifficulty": "0x0",
"extraData": "0x",
"baseFeePerGas": "0x3b9aca00",
"size": "0x244",
"gasLimit": "0x2fefd8",
"gasUsed": "0x0",
"timestamp": "0x1234",
"uncles": [],
"transactions": [],
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"withdrawals": [],
"blobGasUsed": "0x0",
"excessBlobGas": "0x0",
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"statusCode": 200 "statusCode": 200
} }

@ -1,5 +1,95 @@
{ {
"request" : {"jsonrpc":"2.0","id":1,"method":"engine_forkchoiceUpdatedV3","params":[{"headBlockHash":"0x33235e7b7a78302cdb54e5ddba66c7ae49b01c1f5498bb00cd0c8ed5206784bf","safeBlockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","finalizedBlockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"},{"timestamp":"0x1235","prevRandao":"0x31a3b9b03c64172b39b7fa7d35d86eaa0f9cbac30e2abbf9895a32b80ae1cd76","suggestedFeeRecipient":"0x0000000000000000000000000000000000000000","withdrawals":[{"index":"0x1","validatorIndex":"0x0","address":"0x0000000000000000000000000000000000000000","amount":"0x64"},{"index":"0x2","validatorIndex":"0x1","address":"0x0100000000000000000000000000000000000000","amount":"0x64"},{"index":"0x3","validatorIndex":"0x2","address":"0x0200000000000000000000000000000000000000","amount":"0x64"},{"index":"0x4","validatorIndex":"0x3","address":"0x0300000000000000000000000000000000000000","amount":"0x64"},{"index":"0x5","validatorIndex":"0x4","address":"0x0400000000000000000000000000000000000000","amount":"0x64"},{"index":"0x6","validatorIndex":"0x5","address":"0x0500000000000000000000000000000000000000","amount":"0x64"},{"index":"0x7","validatorIndex":"0x6","address":"0x0600000000000000000000000000000000000000","amount":"0x64"},{"index":"0x8","validatorIndex":"0x7","address":"0x0700000000000000000000000000000000000000","amount":"0x64"},{"index":"0x9","validatorIndex":"0x8","address":"0x0800000000000000000000000000000000000000","amount":"0x64"},{"index":"0xa","validatorIndex":"0x9","address":"0x0900000000000000000000000000000000000000","amount":"0x64"}],"parentBeaconBlockRoot":"0x169630f535b4a41330164c6e5c92b1224c0c407f582d407d0ac3d206cd32fd52"}]}, "request": {
"response" : {"jsonrpc":"2.0","id":1,"result":{"payloadStatus":{"status":"VALID","latestValidHash":"0x33235e7b7a78302cdb54e5ddba66c7ae49b01c1f5498bb00cd0c8ed5206784bf","validationError":null},"payloadId":"0x78d3b312ed5adeb5"}}, "jsonrpc": "2.0",
"id": 1,
"method": "engine_forkchoiceUpdatedV3",
"params": [
{
"headBlockHash": "0x33235e7b7a78302cdb54e5ddba66c7ae49b01c1f5498bb00cd0c8ed5206784bf",
"safeBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
},
{
"timestamp": "0x1235",
"prevRandao": "0x31a3b9b03c64172b39b7fa7d35d86eaa0f9cbac30e2abbf9895a32b80ae1cd76",
"suggestedFeeRecipient": "0x0000000000000000000000000000000000000000",
"withdrawals": [
{
"index": "0x1",
"validatorIndex": "0x0",
"address": "0x0000000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x2",
"validatorIndex": "0x1",
"address": "0x0100000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x3",
"validatorIndex": "0x2",
"address": "0x0200000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x4",
"validatorIndex": "0x3",
"address": "0x0300000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x5",
"validatorIndex": "0x4",
"address": "0x0400000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x6",
"validatorIndex": "0x5",
"address": "0x0500000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x7",
"validatorIndex": "0x6",
"address": "0x0600000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x8",
"validatorIndex": "0x7",
"address": "0x0700000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0x9",
"validatorIndex": "0x8",
"address": "0x0800000000000000000000000000000000000000",
"amount": "0x64"
},
{
"index": "0xa",
"validatorIndex": "0x9",
"address": "0x0900000000000000000000000000000000000000",
"amount": "0x64"
}
],
"parentBeaconBlockRoot": "0x169630f535b4a41330164c6e5c92b1224c0c407f582d407d0ac3d206cd32fd52"
}
]
},
"response": {
"jsonrpc": "2.0",
"id": 1,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0x33235e7b7a78302cdb54e5ddba66c7ae49b01c1f5498bb00cd0c8ed5206784bf",
"validationError": null
},
"payloadId": "0x78d3b312ed5adeb5"
}
},
"statusCode": 200 "statusCode": 200
} }

@ -1,8 +1,9 @@
{ {
"request": { "request": {
"jsonrpc":"2.0","method":"txpool_besuStatistics","params":[],"id":1 "jsonrpc": "2.0",
"method": "txpool_besuStatistics",
"params": [],
"id": 1
}, },
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",

@ -109,7 +109,15 @@ public interface Transaction {
Quantity getValue(); Quantity getValue();
/** /**
* Value corresponding to the 'V' component of the signature of the transaction. * Value corresponding to the 'yParity' component of non-legacy signatures.
*
* @return the 'yParity' component of the signature
*/
BigInteger getYParity();
/**
* Value corresponding to the 'v' component of legacy signatures, which encodes chainId and
* yParity.
* *
* @return the 'V' component of the signature * @return the 'V' component of the signature
*/ */

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.graphql.internal;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import java.math.BigInteger;
import java.util.Locale; import java.util.Locale;
import graphql.GraphQLContext; import graphql.GraphQLContext;
@ -118,6 +119,8 @@ public class Scalars {
return convertImpl(stringValue.getValue()); return convertImpl(stringValue.getValue());
} else if (input instanceof IntValue intValue) { } else if (input instanceof IntValue intValue) {
return UInt256.valueOf(intValue.getValue()).toShortHexString(); return UInt256.valueOf(intValue.getValue()).toShortHexString();
} else if (input instanceof BigInteger bigInteger) {
return "0x" + bigInteger.toString(16);
} else { } else {
return null; return null;
} }

@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -235,6 +236,22 @@ public class TransactionAdapter extends AdapterBase {
return results; return results;
} }
public BigInteger getR() {
return transactionWithMetadata.getTransaction().getR();
}
public BigInteger getS() {
return transactionWithMetadata.getTransaction().getS();
}
public Optional<BigInteger> getV() {
return Optional.ofNullable(transactionWithMetadata.getTransaction().getV());
}
public Optional<BigInteger> getYParity() {
return Optional.ofNullable(transactionWithMetadata.getTransaction().getYParity());
}
public List<AccessListEntryAdapter> getAccessList() { public List<AccessListEntryAdapter> getAccessList() {
return transactionWithMetadata return transactionWithMetadata
.getTransaction() .getTransaction()

@ -46,6 +46,7 @@ import org.apache.tuweni.bytes.Bytes;
"transactionIndex", "transactionIndex",
"type", "type",
"value", "value",
"yParity",
"v", "v",
"r", "r",
"s", "s",
@ -82,6 +83,7 @@ public class TransactionCompleteResult implements TransactionResult {
private final String transactionIndex; private final String transactionIndex;
private final String type; private final String type;
private final String value; private final String value;
private final String yParity;
private final String v; private final String v;
private final String r; private final String r;
private final String s; private final String s;
@ -114,12 +116,20 @@ public class TransactionCompleteResult implements TransactionResult {
this.nonce = Quantity.create(transaction.getNonce()); this.nonce = Quantity.create(transaction.getNonce());
this.to = transaction.getTo().map(Bytes::toHexString).orElse(null); this.to = transaction.getTo().map(Bytes::toHexString).orElse(null);
this.transactionIndex = Quantity.create(tx.getTransactionIndex().get()); this.transactionIndex = Quantity.create(tx.getTransactionIndex().get());
this.type = if (transactionType == TransactionType.FRONTIER) {
transactionType.equals(TransactionType.FRONTIER) this.type = Quantity.create(0);
? Quantity.create(0) this.yParity = null;
: Quantity.create(transactionType.getSerializedType());
this.value = Quantity.create(transaction.getValue());
this.v = Quantity.create(transaction.getV()); this.v = Quantity.create(transaction.getV());
} else {
this.type = Quantity.create(transactionType.getSerializedType());
this.yParity = Quantity.create(transaction.getYParity());
this.v =
(transactionType == TransactionType.ACCESS_LIST
|| transactionType == TransactionType.EIP1559)
? this.yParity
: null;
}
this.value = Quantity.create(transaction.getValue());
this.r = Quantity.create(transaction.getR()); this.r = Quantity.create(transaction.getR());
this.s = Quantity.create(transaction.getS()); this.s = Quantity.create(transaction.getS());
this.versionedHashes = transaction.getVersionedHashes().orElse(null); this.versionedHashes = transaction.getVersionedHashes().orElse(null);
@ -210,6 +220,13 @@ public class TransactionCompleteResult implements TransactionResult {
return value; return value;
} }
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonGetter(value = "yParity")
public String getYParity() {
return yParity;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonGetter(value = "v") @JsonGetter(value = "v")
public String getV() { public String getV() {
return v; return v;

@ -44,6 +44,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
"to", "to",
"transactionIndex", "transactionIndex",
"value", "value",
"yParity",
"v", "v",
"r", "r",
"s", "s",
@ -77,6 +78,7 @@ public class TransactionPendingResult implements TransactionResult {
private final String to; private final String to;
private final String type; private final String type;
private final String value; private final String value;
private final String yParity;
private final String v; private final String v;
private final String r; private final String r;
private final String s; private final String s;
@ -104,12 +106,20 @@ public class TransactionPendingResult implements TransactionResult {
TransactionEncoder.encodeOpaqueBytes(transaction, EncodingContext.POOLED_TRANSACTION) TransactionEncoder.encodeOpaqueBytes(transaction, EncodingContext.POOLED_TRANSACTION)
.toString(); .toString();
this.to = transaction.getTo().map(Address::toHexString).orElse(null); this.to = transaction.getTo().map(Address::toHexString).orElse(null);
this.type = if (transactionType == TransactionType.FRONTIER) {
transactionType.equals(TransactionType.FRONTIER) this.type = Quantity.create(0);
? Quantity.create(0) this.yParity = null;
: Quantity.create(transactionType.getSerializedType());
this.value = Quantity.create(transaction.getValue());
this.v = Quantity.create(transaction.getV()); this.v = Quantity.create(transaction.getV());
} else {
this.type = Quantity.create(transactionType.getSerializedType());
this.yParity = Quantity.create(transaction.getYParity());
this.v =
(transactionType == TransactionType.ACCESS_LIST
|| transactionType == TransactionType.EIP1559)
? this.yParity
: null;
}
this.value = Quantity.create(transaction.getValue());
this.r = Quantity.create(transaction.getR()); this.r = Quantity.create(transaction.getR());
this.s = Quantity.create(transaction.getS()); this.s = Quantity.create(transaction.getS());
this.versionedHashes = transaction.getVersionedHashes().orElse(null); this.versionedHashes = transaction.getVersionedHashes().orElse(null);
@ -195,6 +205,13 @@ public class TransactionPendingResult implements TransactionResult {
return value; return value;
} }
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonGetter(value = "yParity")
public String getYParity() {
return yParity;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonGetter(value = "v") @JsonGetter(value = "v")
public String getV() { public String getV() {
return v; return v;

@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Transaction;
import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
@ -33,6 +34,7 @@ import org.apache.tuweni.bytes.Bytes;
"to", "to",
"type", "type",
"value", "value",
"yParity",
"v", "v",
"r", "r",
"s" "s"
@ -47,11 +49,13 @@ public class PendingTransactionDetailResult implements JsonRpcResult {
private final String to; private final String to;
private final String type; private final String type;
private final String value; private final String value;
private final String yParity;
private final String v; private final String v;
private final String r; private final String r;
private final String s; private final String s;
public PendingTransactionDetailResult(final Transaction tx) { public PendingTransactionDetailResult(final Transaction tx) {
TransactionType transactionType = tx.getType();
this.from = tx.getSender().toString(); this.from = tx.getSender().toString();
this.gas = Quantity.create(tx.getGasLimit()); this.gas = Quantity.create(tx.getGasLimit());
this.gasPrice = tx.getGasPrice().map(Quantity::create).orElse(null); this.gasPrice = tx.getGasPrice().map(Quantity::create).orElse(null);
@ -59,12 +63,20 @@ public class PendingTransactionDetailResult implements JsonRpcResult {
this.input = tx.getPayload().toString(); this.input = tx.getPayload().toString();
this.nonce = Quantity.create(tx.getNonce()); this.nonce = Quantity.create(tx.getNonce());
this.to = tx.getTo().map(Bytes::toHexString).orElse(null); this.to = tx.getTo().map(Bytes::toHexString).orElse(null);
this.type = if (transactionType == TransactionType.FRONTIER) {
tx.getType().equals(TransactionType.FRONTIER) this.type = Quantity.create(0);
? Quantity.create(0) this.yParity = null;
: Quantity.create(tx.getType().getSerializedType());
this.value = Quantity.create(tx.getValue());
this.v = Quantity.create(tx.getV()); this.v = Quantity.create(tx.getV());
} else {
this.type = Quantity.create(transactionType.getSerializedType());
this.yParity = Quantity.create(tx.getYParity());
this.v =
(transactionType == TransactionType.ACCESS_LIST
|| transactionType == TransactionType.EIP1559)
? this.yParity
: null;
}
this.value = Quantity.create(tx.getValue());
this.r = Quantity.create(tx.getR()); this.r = Quantity.create(tx.getR());
this.s = Quantity.create(tx.getS()); this.s = Quantity.create(tx.getS());
} }
@ -114,6 +126,13 @@ public class PendingTransactionDetailResult implements JsonRpcResult {
return value; return value;
} }
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonGetter(value = "yParity")
public String getyParity() {
return yParity;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonGetter(value = "v") @JsonGetter(value = "v")
public String getV() { public String getV() {
return v; return v;

@ -555,7 +555,8 @@ type Transaction {
logs: [Log!] logs: [Log!]
r: BigInt! r: BigInt!
s: BigInt! s: BigInt!
v: BigInt! v: BigInt
yParity: BigInt
"""Envelope transaction support""" """Envelope transaction support"""
type: Long type: Long

@ -36,7 +36,6 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat; import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.plugin.data.SyncStatus; import org.hyperledger.besu.plugin.data.SyncStatus;
import org.hyperledger.besu.testutil.BlockTestUtil;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
@ -74,9 +73,7 @@ public abstract class AbstractEthGraphQLHttpServiceTest {
@BeforeAll @BeforeAll
public static void setupConstants() { public static void setupConstants() {
blockchainSetupUtil = blockchainSetupUtil = BlockchainSetupUtil.forHiveTesting(DataStorageFormat.BONSAI);
BlockchainSetupUtil.createForEthashChain(
BlockTestUtil.getHiveTestChainResources(), DataStorageFormat.BONSAI);
blockchainSetupUtil.importAllBlocks(); blockchainSetupUtil.importAllBlocks();
} }

@ -103,7 +103,7 @@ public abstract class AbstractJsonRpcHttpServiceTest {
} }
protected BlockchainSetupUtil getBlockchainSetupUtil(final DataStorageFormat storageFormat) { protected BlockchainSetupUtil getBlockchainSetupUtil(final DataStorageFormat storageFormat) {
return BlockchainSetupUtil.forTesting(storageFormat); return BlockchainSetupUtil.forHiveTesting(storageFormat);
} }
protected BlockchainSetupUtil createBlockchainSetupUtil( protected BlockchainSetupUtil createBlockchainSetupUtil(
@ -121,8 +121,7 @@ public abstract class AbstractJsonRpcHttpServiceTest {
setupBlockchain(); setupBlockchain();
} }
protected BlockchainSetupUtil startServiceWithEmptyChain(final DataStorageFormat storageFormat) protected BlockchainSetupUtil startServiceWithEmptyChain(final DataStorageFormat storageFormat) {
throws Exception {
final BlockchainSetupUtil emptySetupUtil = getBlockchainSetupUtil(storageFormat); final BlockchainSetupUtil emptySetupUtil = getBlockchainSetupUtil(storageFormat);
startService(emptySetupUtil); startService(emptySetupUtil);
return emptySetupUtil; return emptySetupUtil;
@ -199,7 +198,7 @@ public abstract class AbstractJsonRpcHttpServiceTest {
startService(blockchainSetupUtil); startService(blockchainSetupUtil);
} }
private void startService(final BlockchainSetupUtil blockchainSetupUtil) throws Exception { private void startService(final BlockchainSetupUtil blockchainSetupUtil) {
final JsonRpcConfiguration config = JsonRpcConfiguration.createDefault(); final JsonRpcConfiguration config = JsonRpcConfiguration.createDefault();
final Map<String, JsonRpcMethod> methods = getRpcMethods(config, blockchainSetupUtil); final Map<String, JsonRpcMethod> methods = getRpcMethods(config, blockchainSetupUtil);

@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -48,7 +47,7 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class EthGetTransactionByHashTest { class EthGetTransactionByHashTest {
private static final String VALID_TRANSACTION = private static final String VALID_TRANSACTION =
"0xf86d0485174876e800830222e0945aae326516b4f8fe08074b7e972e40a713048d62880de0b6b3a7640000801ba05d4e7998757264daab67df2ce6f7e7a0ae36910778a406ca73898c9899a32b9ea0674700d5c3d1d27f2e6b4469957dfd1a1c49bf92383d80717afc84eb05695d5b"; "0xf86d0485174876e800830222e0945aae326516b4f8fe08074b7e972e40a713048d62880de0b6b3a7640000801ba05d4e7998757264daab67df2ce6f7e7a0ae36910778a406ca73898c9899a32b9ea0674700d5c3d1d27f2e6b4469957dfd1a1c49bf92383d80717afc84eb05695d5b";
@ -66,12 +65,12 @@ public class EthGetTransactionByHashTest {
} }
@Test @Test
public void returnsCorrectMethodName() { void returnsCorrectMethodName() {
assertThat(method.getName()).isEqualTo(ETH_METHOD); assertThat(method.getName()).isEqualTo(ETH_METHOD);
} }
@Test @Test
public void shouldReturnErrorResponseIfMissingRequiredParameter() { void shouldReturnErrorResponseIfMissingRequiredParameter() {
final JsonRpcRequest request = new JsonRpcRequest("2.0", method.getName(), new Object[] {}); final JsonRpcRequest request = new JsonRpcRequest("2.0", method.getName(), new Object[] {});
final JsonRpcRequestContext context = new JsonRpcRequestContext(request); final JsonRpcRequestContext context = new JsonRpcRequestContext(request);
@ -84,12 +83,12 @@ public class EthGetTransactionByHashTest {
} }
@Test @Test
public void shouldReturnNullResultWhenTransactionDoesNotExist() { void shouldReturnNullResultWhenTransactionDoesNotExist() {
final String transactionHash = final String transactionHash =
"0xf9ef5f0cf02685711cdf687b72d4754901729b942f4ea7f956e7fb206cae2f9e"; "0xf9ef5f0cf02685711cdf687b72d4754901729b942f4ea7f956e7fb206cae2f9e";
when(transactionPool.getTransactionByHash(eq(Hash.fromHexString(transactionHash)))) when(transactionPool.getTransactionByHash(Hash.fromHexString(transactionHash)))
.thenReturn(Optional.empty()); .thenReturn(Optional.empty());
when(blockchainQueries.transactionByHash(eq(Hash.fromHexString(transactionHash)))) when(blockchainQueries.transactionByHash(Hash.fromHexString(transactionHash)))
.thenReturn(Optional.empty()); .thenReturn(Optional.empty());
final JsonRpcRequest request = final JsonRpcRequest request =
@ -105,12 +104,12 @@ public class EthGetTransactionByHashTest {
} }
@Test @Test
public void shouldReturnPendingTransactionWhenTransactionExistsAndIsPending() { void shouldReturnPendingTransactionWhenTransactionExistsAndIsPending() {
final org.hyperledger.besu.ethereum.core.Transaction transaction = final org.hyperledger.besu.ethereum.core.Transaction transaction =
org.hyperledger.besu.ethereum.core.Transaction.readFrom( org.hyperledger.besu.ethereum.core.Transaction.readFrom(
Bytes.fromHexString(VALID_TRANSACTION)); Bytes.fromHexString(VALID_TRANSACTION));
when(transactionPool.getTransactionByHash(eq(transaction.getHash()))) when(transactionPool.getTransactionByHash(transaction.getHash()))
.thenReturn(Optional.of(transaction)); .thenReturn(Optional.of(transaction));
verifyNoInteractions(blockchainQueries); verifyNoInteractions(blockchainQueries);
@ -128,17 +127,16 @@ public class EthGetTransactionByHashTest {
} }
@Test @Test
public void shouldReturnCompleteTransactionWhenTransactionExistsInBlockchain() { void shouldReturnCompleteTransactionWhenTransactionExistsInBlockchain() {
final org.hyperledger.besu.ethereum.core.Transaction transaction = final org.hyperledger.besu.ethereum.core.Transaction transaction =
org.hyperledger.besu.ethereum.core.Transaction.readFrom( org.hyperledger.besu.ethereum.core.Transaction.readFrom(
Bytes.fromHexString(VALID_TRANSACTION)); Bytes.fromHexString(VALID_TRANSACTION));
final TransactionWithMetadata transactionWithMetadata = final TransactionWithMetadata transactionWithMetadata =
new TransactionWithMetadata(transaction, 1, Optional.empty(), Hash.ZERO, 0); new TransactionWithMetadata(transaction, 1, Optional.empty(), Hash.ZERO, 0);
when(transactionPool.getTransactionByHash(eq(transaction.getHash()))) when(transactionPool.getTransactionByHash(transaction.getHash())).thenReturn(Optional.empty());
.thenReturn(Optional.empty());
verifyNoMoreInteractions(transactionPool); verifyNoMoreInteractions(transactionPool);
when(blockchainQueries.transactionByHash(eq(transaction.getHash()))) when(blockchainQueries.transactionByHash(transaction.getHash()))
.thenReturn(Optional.of(transactionWithMetadata)); .thenReturn(Optional.of(transactionWithMetadata));
final JsonRpcRequest request = final JsonRpcRequest request =
@ -156,7 +154,7 @@ public class EthGetTransactionByHashTest {
} }
@Test @Test
public void validateResultSpec() { void validateResultSpec() {
PendingTransaction pendingTx = getTransactionPool().stream().findFirst().get(); PendingTransaction pendingTx = getTransactionPool().stream().findFirst().get();
Hash hash = pendingTx.getHash(); Hash hash = pendingTx.getHash();
@ -183,6 +181,7 @@ public class EthGetTransactionByHashTest {
assertThat(result.getRaw()).isNotNull(); assertThat(result.getRaw()).isNotNull();
assertThat(result.getTo()).isNotNull(); assertThat(result.getTo()).isNotNull();
assertThat(result.getValue()).isNotNull(); assertThat(result.getValue()).isNotNull();
assertThat(result.getYParity()).isNotNull();
assertThat(result.getV()).isNotNull(); assertThat(result.getV()).isNotNull();
assertThat(result.getR()).isNotNull(); assertThat(result.getR()).isNotNull();
assertThat(result.getS()).isNotNull(); assertThat(result.getS()).isNotNull();
@ -194,7 +193,7 @@ public class EthGetTransactionByHashTest {
Transaction pendingTransaction = gen.transaction(); Transaction pendingTransaction = gen.transaction();
System.out.println(pendingTransaction.getHash()); System.out.println(pendingTransaction.getHash());
return gen.transactionsWithAllTypes(4).stream() return gen.transactionsWithAllTypes(4).stream()
.map(transaction -> new PendingTransaction.Local(transaction)) .map(PendingTransaction.Local::new)
.collect(Collectors.toUnmodifiableSet()); .collect(Collectors.toUnmodifiableSet());
} }
} }

@ -1,5 +1,5 @@
{ {
"request": "{block (number: 34) { baseFeePerGas difficulty extraData miner { address } mixHash nonce stateRoot totalDifficulty withdrawalsRoot withdrawals { address amount index validator } blobGasUsed excessBlobGas transactions { maxFeePerBlobGas blobGasUsed blobGasPrice } }} ", "request": "{block (number: 34) { baseFeePerGas difficulty extraData miner { address } mixHash nonce stateRoot totalDifficulty withdrawalsRoot withdrawals { address amount index validator } blobGasUsed excessBlobGas transactions { maxFeePerBlobGas blobGasUsed blobGasPrice type yParity v r s} }} ",
"response": { "response": {
"data": { "data": {
"block": { "block": {
@ -17,7 +17,18 @@
"withdrawals": [], "withdrawals": [],
"blobGasUsed": "0x40000", "blobGasUsed": "0x40000",
"excessBlobGas": "0x0", "excessBlobGas": "0x0",
"transactions":[{"maxFeePerBlobGas":"0x3b9aca00","blobGasUsed":"0x40000","blobGasPrice":"0x1"}] "transactions": [
{
"maxFeePerBlobGas": "0x3b9aca00",
"blobGasUsed": "0x40000",
"blobGasPrice": "0x1",
"type": "0x3",
"yParity": "0x0",
"v": null,
"r": "0x6ae0612cfda43a9b464b10b4881c6fc2e4c24533cf89bbe07934da65c3ae49ce",
"s": "0x125387aeb222ec51130cf99cbdabf24bd4a881914faed69f254e4a3f4bc507fc"
}
]
} }
} }
}, },

@ -1,5 +1,5 @@
{ {
"request": "{transaction (hash : \"0x9cc6c7e602c56aa30c554bb691377f8703d778cec8845f4b88c0f72516b304f4\") { block{hash} gas gasPrice hash inputData nonce index value from {address} to {address} logs{index} status createdContract{address} } } ", "request": "{transaction (hash : \"0x9cc6c7e602c56aa30c554bb691377f8703d778cec8845f4b88c0f72516b304f4\") { block{hash} gas gasPrice hash inputData nonce index value from {address} to {address} logs{index} type yParity v r s status createdContract{address} } } ",
"response": { "response": {
"data": { "data": {
"transaction": { "transaction": {
@ -24,6 +24,11 @@
"index": "0x0" "index": "0x0"
} }
], ],
"type": "0x0",
"yParity": null,
"v": "0x1c",
"r": "0x11232cac2f935ab8dd5d5972438fde90e05d0dd620860b42886e7d54dc5c4a0c",
"s": "0x3dd467b5faa6e5a0f3c22a5396fefa5b03f07d8114d8434e0e1493736aad8d0e",
"status": null, "status": null,
"createdContract": null "createdContract": null
} }

@ -8,7 +8,7 @@
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 2, "id": 2,
"result": "0x20" "result": "0x22"
}, },
"statusCode": 200 "statusCode": 200
} }

@ -13,7 +13,7 @@
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 3, "id": 3,
"result": "0x1b551" "result": "0x1f099"
}, },
"statusCode": 200 "statusCode": 200
} }

@ -14,7 +14,7 @@
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 3, "id": 3,
"result": "0x52d4" "result": "0x5238"
}, },
"statusCode": 200 "statusCode": 200
} }

@ -5,6 +5,8 @@
"method": "eth_estimateGas", "method": "eth_estimateGas",
"params": [ "params": [
{ {
"to": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"from": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"gas": "0x1" "gas": "0x1"
} }
] ]

@ -10,7 +10,7 @@
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 3, "id": 3,
"result": "0x5208" "result": "0xcf08"
}, },
"statusCode": 200 "statusCode": 200
} }

@ -17,26 +17,26 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 28, "id": 28,
"result": { "result": {
"oldestBlock": "0x1f", "oldestBlock": "0x21",
"baseFeePerGas": [ "baseFeePerGas": [
"0x0", "0x3b9aca00",
"0x0", "0x3437004a",
"0x0" "0x2dbc88c1"
], ],
"gasUsedRatio": [ "gasUsedRatio": [
0.00773588677333021, 0.004079142040086682,
0.007545537421791245 0.003713085594819442
], ],
"reward": [ "reward": [
[ [
"0x1", "0x3b9aca00",
"0x1", "0x3b9aca00",
"0x1" "0x3b9aca00"
], ],
[ [
"0x1", "0x3b9aca00",
"0x1", "0x3b9aca00",
"0x1" "0x3b9aca00"
] ]
] ]
} }

@ -12,15 +12,15 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 28, "id": 28,
"result": { "result": {
"oldestBlock": "0x1f", "oldestBlock": "0x21",
"baseFeePerGas": [ "baseFeePerGas": [
"0x0", "0x3b9aca00",
"0x0", "0x3437004a",
"0x0" "0x2dbc88c1"
], ],
"gasUsedRatio": [ "gasUsedRatio": [
0.00773588677333021, 0.004079142040086682,
0.007545537421791245 0.003713085594819442
] ]
} }
}, },

@ -5,7 +5,7 @@
"method": "eth_getBalance", "method": "eth_getBalance",
"params": [ "params": [
"0x8888f1f195afa192cfee860698584c030f4c9db1", "0x8888f1f195afa192cfee860698584c030f4c9db1",
"0x21" "0x120"
] ]
}, },
"response": { "response": {

@ -0,0 +1,71 @@
{
"request": {
"id": 174,
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": [
"0x22",
true
]
},
"response": {
"jsonrpc": "2.0",
"id": 174,
"result": {
"number": "0x22",
"hash": "0x4859ea10d276f6df988eabd48a02e0696cfd3deb769d2a5e0e416a5f3191028a",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x30e688f50392780a71899dcb4c35997f5c1d168cf90306d8e6919ea805097810",
"nonce": "0x0000000000000000",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionsRoot": "0x16661f63605269a46ad0c5ad8596e5417310a641563d3aa9b74f70cea0e48b49",
"stateRoot": "0x34727aff24d1c51cd63fdc14515b15ddaa156fa0671c58a96c72b1553819945d",
"receiptsRoot": "0xb56f5313fa6822e1ee3f84487b5b2f12c5e1746778ad39f9a89e5f0239cc9b83",
"miner": "0x0000000000000000000000000000000000000000",
"difficulty": "0x0",
"totalDifficulty": "0x427c00",
"extraData": "0x",
"baseFeePerGas": "0x3437004a",
"size": "0x308",
"gasLimit": "0x5fdfb0",
"gasUsed": "0x5b22",
"timestamp": "0x561bc351",
"uncles": [],
"transactions": [
{
"accessList": [],
"blockHash": "0x4859ea10d276f6df988eabd48a02e0696cfd3deb769d2a5e0e416a5f3191028a",
"blockNumber": "0x22",
"chainId": "0x1",
"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"gas": "0xc350",
"gasPrice": "0x6fd1ca4a",
"maxPriorityFeePerGas": "0x3b9aca00",
"maxFeePerGas": "0xb2d05e00",
"maxFeePerBlobGas": "0x3b9aca00",
"hash": "0x7c80f35a47f1d432d46add30f262c45f9578e2b1352dbaca0256af1ff3235532",
"input": "0x12a7b914",
"nonce": "0x21",
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"transactionIndex": "0x0",
"type": "0x3",
"value": "0x0",
"yParity": "0x0",
"r": "0x6ae0612cfda43a9b464b10b4881c6fc2e4c24533cf89bbe07934da65c3ae49ce",
"s": "0x125387aeb222ec51130cf99cbdabf24bd4a881914faed69f254e4a3f4bc507fc",
"blobVersionedHashes": [
"0x0100000000000000000000000000000000000000000000000000000000000000",
"0x0102000000000000000000000000000000000000000000000000000000000000"
]
}
],
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"withdrawals": [],
"blobGasUsed": "0x40000",
"excessBlobGas": "0x0",
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"statusCode": 200
}

@ -0,0 +1,78 @@
{
"request": {
"id": 174,
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": [
"0x21",
true
]
},
"response": {
"jsonrpc": "2.0",
"id": 174,
"result": {
"number": "0x21",
"hash": "0x30e688f50392780a71899dcb4c35997f5c1d168cf90306d8e6919ea805097810",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53",
"nonce": "0x0000000000000000",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionsRoot": "0x319d63b103c713c43e4e9912731ea36906079597e53b128894e8c09d21a5ffad",
"stateRoot": "0x0d3c456bb68669bad05da3a1a766daab236c9df1da8f74edf5ebe9383f00084c",
"receiptsRoot": "0xd8f831982345c98e4189e8e76c303d833d1dc22f51efa20d717e31b9337a43cb",
"miner": "0x0000000000000000000000000000000000000000",
"difficulty": "0x0",
"totalDifficulty": "0x427c00",
"extraData": "0x",
"baseFeePerGas": "0x3b9aca00",
"size": "0x2f0",
"gasLimit": "0x5fdfb0",
"gasUsed": "0x641e",
"timestamp": "0x561bc347",
"uncles": [],
"transactions": [
{
"accessList": [
{
"address": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"storageKeys": [
"0x0000000000000000000000000000000000000000000000000000000000000000"
]
}
],
"blockHash": "0x30e688f50392780a71899dcb4c35997f5c1d168cf90306d8e6919ea805097810",
"blockNumber": "0x21",
"chainId": "0x1",
"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"gas": "0xc350",
"gasPrice": "0x77359400",
"maxPriorityFeePerGas": "0x3b9aca00",
"maxFeePerGas": "0xb2d05e00",
"hash": "0x3ecd2ca6cf26c864d0ea5f038a58d4cd4a46a3e242fe92f446f392fdc232dd98",
"input": "0x12a7b914",
"nonce": "0x20",
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"transactionIndex": "0x0",
"type": "0x2",
"value": "0x0",
"yParity": "0x0",
"v" : "0x0",
"r": "0x8abbfbd4c5f2a13a8d5ed394ac50bac7d678f83a23f645818492f76e8ee17ab3",
"s": "0x7bd38c6929235f775d68b45bd7dea7981264f9a265b6bea97b070e15be88389c"
}
],
"withdrawalsRoot": "0x37945ab58d2712a26df2a38d217e822694927e29b30d5993d7a53ccea618d1f3",
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0xa",
"address": "0x0000000000000000000000000000000000000dad",
"amount": "0x2540be400"
}
]
}
},
"statusCode": 200
}

@ -10,32 +10,26 @@
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 307, "id": 307,
"result": [ { "result": [
"blockHash" : "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53", {
"blockNumber" : "0x20", "blockHash": "0x4859ea10d276f6df988eabd48a02e0696cfd3deb769d2a5e0e416a5f3191028a",
"blockNumber": "0x22",
"contractAddress": null, "contractAddress": null,
"cumulativeGasUsed" : "0x5c99", "cumulativeGasUsed": "0x5b22",
"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"gasUsed" : "0x5c99", "gasUsed": "0x5b22",
"effectiveGasPrice" : "0x1", "effectiveGasPrice": "0x6fd1ca4a",
"logs" : [ { "logs": [],
"address" : "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"topics" : [ "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ], "status": "0x1",
"data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9000000000000000000000000000000000000000000000000000000000000002a",
"blockNumber" : "0x20",
"transactionHash" : "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310",
"transactionIndex" : "0x0",
"blockHash" : "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53",
"logIndex" : "0x0",
"removed" : false
} ],
"logsBloom" : "0x00000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000400000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000800000000040000000000000000000000000000000000000000010000000000000000000000000",
"root" : "0x6d54fb51c667e4cc4bd8f2633b675f831b35d7784a70b5df91cd58f593c5286e",
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"transactionHash" : "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310", "transactionHash": "0x7c80f35a47f1d432d46add30f262c45f9578e2b1352dbaca0256af1ff3235532",
"transactionIndex": "0x0", "transactionIndex": "0x0",
"type" : "0x0" "type": "0x3",
} ] "blobGasUsed": "0x40000",
"blobGasPrice": "0x1"
}
]
}, },
"statusCode": 200 "statusCode": 200
} }

@ -4,7 +4,7 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "eth_getBlockTransactionCountByNumber", "method": "eth_getBlockTransactionCountByNumber",
"params": [ "params": [
"0x21" "0x120"
] ]
}, },
"response": { "response": {

@ -6,7 +6,7 @@
"params": [ "params": [
"0x8888f1f195afa192cfee860698584c030f4c9db1", "0x8888f1f195afa192cfee860698584c030f4c9db1",
["0x0000000000000000000000000000000000000000000000000000000000000347"], ["0x0000000000000000000000000000000000000000000000000000000000000347"],
"0x21" "0x120"
] ]
}, },
"response": { "response": {

@ -5,7 +5,9 @@
"method": "eth_getProof", "method": "eth_getProof",
"params": [ "params": [
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
["0x0000000000000000000000000000000000000000000000000000000000000347"], [
"0x0000000000000000000000000000000000000000000000000000000000000347"
],
"latest" "latest"
] ]
}, },
@ -13,17 +15,24 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 28, "id": 28,
"result": { "result": {
"accountProof" : [ "0xf891a084e747fd6c2e7ca25d6f219938c2d9e3014c9e86e3fc3fb0014dcef9d10b6815a097699db78357681938d946074cafa3355e921261ba0bd5081bff15c4f17d0c7f8080808080808080a07ac9345327d90f69293f207fd3dbad91418e38cf6c663c97e8cda89c32448509808080a093e09806aca0b1db534f5e6940b2d43a717c47bf4dfc342a104d9945e82a221d8080", "0xf86ba03b8ec137a2f5a74ec3a73144b552caad890b18b5f725872fa212fff6d4d565bab848f84680820140a0dd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515ba035178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47" ], "accountProof": [
"0xf8b1a00f23b4d3c6c2980e929008edfaa3cac1d693711fb114c678d3a0e02af00f481fa097699db78357681938d946074cafa3355e921261ba0bd5081bff15c4f17d0c7f808080a04341a174820f23ab9c524d4f8bf0e8c2b6075aaf1c689775ef752f039ad2c6a480808080a07ac9345327d90f69293f207fd3dbad91418e38cf6c663c97e8cda89c32448509808080a093e09806aca0b1db534f5e6940b2d43a717c47bf4dfc342a104d9945e82a221d8080",
"0xf86ba03b8ec137a2f5a74ec3a73144b552caad890b18b5f725872fa212fff6d4d565bab848f84680820140a0dd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515ba035178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47"
],
"address": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "address": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"balance": "0x140", "balance": "0x140",
"codeHash": "0x35178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47", "codeHash": "0x35178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47",
"nonce": "0x0", "nonce": "0x0",
"storageHash": "0xdd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515b", "storageHash": "0xdd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515b",
"storageProof" : [ { "storageProof": [
{
"key": "0x0347", "key": "0x0347",
"value": "0x0", "value": "0x0",
"proof" : [ "0xf8b18080a0c7f91ee5ea67d593275fcc773a02a5e5fb37b0625ca5c5cdc783483d43f2d7c280a06672614c102b0f02e747250bae452ed105110e25761c15a2a459afbd9eb8cf2e808080a0f671e05fab19f512b16fdcbc938f5fbbfbbc2fa67fecb575bb7721c221f71cf78080a0ba2fc36b0235d7ea299126bd4d404cb38456f32a6c236b422a3868f98c69eda1a0d77552655c7b63916586a73350b1933836f2378789613b548b90fa0a44125df180808080"] "proof": [
} ] "0xf8b18080a0c7f91ee5ea67d593275fcc773a02a5e5fb37b0625ca5c5cdc783483d43f2d7c280a06672614c102b0f02e747250bae452ed105110e25761c15a2a459afbd9eb8cf2e808080a0f671e05fab19f512b16fdcbc938f5fbbfbbc2fa67fecb575bb7721c221f71cf78080a0ba2fc36b0235d7ea299126bd4d404cb38456f32a6c236b422a3868f98c69eda1a0d77552655c7b63916586a73350b1933836f2378789613b548b90fa0a44125df180808080"
]
}
]
} }
}, },
"statusCode": 200 "statusCode": 200

@ -5,7 +5,9 @@
"method": "eth_getProof", "method": "eth_getProof",
"params": [ "params": [
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
["0x0000000000000000000000000000000000000000000000000000000000000347"], [
"0x0000000000000000000000000000000000000000000000000000000000000347"
],
"pending" "pending"
] ]
}, },
@ -13,17 +15,24 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 28, "id": 28,
"result": { "result": {
"accountProof" : [ "0xf891a084e747fd6c2e7ca25d6f219938c2d9e3014c9e86e3fc3fb0014dcef9d10b6815a097699db78357681938d946074cafa3355e921261ba0bd5081bff15c4f17d0c7f8080808080808080a07ac9345327d90f69293f207fd3dbad91418e38cf6c663c97e8cda89c32448509808080a093e09806aca0b1db534f5e6940b2d43a717c47bf4dfc342a104d9945e82a221d8080", "0xf86ba03b8ec137a2f5a74ec3a73144b552caad890b18b5f725872fa212fff6d4d565bab848f84680820140a0dd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515ba035178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47" ], "accountProof": [
"0xf8b1a00f23b4d3c6c2980e929008edfaa3cac1d693711fb114c678d3a0e02af00f481fa097699db78357681938d946074cafa3355e921261ba0bd5081bff15c4f17d0c7f808080a04341a174820f23ab9c524d4f8bf0e8c2b6075aaf1c689775ef752f039ad2c6a480808080a07ac9345327d90f69293f207fd3dbad91418e38cf6c663c97e8cda89c32448509808080a093e09806aca0b1db534f5e6940b2d43a717c47bf4dfc342a104d9945e82a221d8080",
"0xf86ba03b8ec137a2f5a74ec3a73144b552caad890b18b5f725872fa212fff6d4d565bab848f84680820140a0dd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515ba035178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47"
],
"address": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "address": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"balance": "0x140", "balance": "0x140",
"codeHash": "0x35178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47", "codeHash": "0x35178fc0de1e7fc754dbd07360e6f80bed818b9e51c62682f312442c4838ac47",
"nonce": "0x0", "nonce": "0x0",
"storageHash": "0xdd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515b", "storageHash": "0xdd3fa56425f8195f314c22547243081293b3f5537cd98ed8f84d4fda3f9a515b",
"storageProof" : [ { "storageProof": [
{
"key": "0x0347", "key": "0x0347",
"value": "0x0", "value": "0x0",
"proof" : [ "0xf8b18080a0c7f91ee5ea67d593275fcc773a02a5e5fb37b0625ca5c5cdc783483d43f2d7c280a06672614c102b0f02e747250bae452ed105110e25761c15a2a459afbd9eb8cf2e808080a0f671e05fab19f512b16fdcbc938f5fbbfbbc2fa67fecb575bb7721c221f71cf78080a0ba2fc36b0235d7ea299126bd4d404cb38456f32a6c236b422a3868f98c69eda1a0d77552655c7b63916586a73350b1933836f2378789613b548b90fa0a44125df180808080"] "proof": [
} ] "0xf8b18080a0c7f91ee5ea67d593275fcc773a02a5e5fb37b0625ca5c5cdc783483d43f2d7c280a06672614c102b0f02e747250bae452ed105110e25761c15a2a459afbd9eb8cf2e808080a0f671e05fab19f512b16fdcbc938f5fbbfbbc2fa67fecb575bb7721c221f71cf78080a0ba2fc36b0235d7ea299126bd4d404cb38456f32a6c236b422a3868f98c69eda1a0d77552655c7b63916586a73350b1933836f2378789613b548b90fa0a44125df180808080"
]
}
]
} }
}, },
"statusCode": 200 "statusCode": 200

@ -6,7 +6,7 @@
"params": [ "params": [
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"0x0", "0x0",
"0x21" "0x120"
] ]
}, },
"response": { "response": {

@ -12,21 +12,30 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 482, "id": 482,
"result": { "result": {
"blockHash": "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53", "accessList": [],
"blockNumber": "0x20", "blockHash": "0x4859ea10d276f6df988eabd48a02e0696cfd3deb769d2a5e0e416a5f3191028a",
"blockNumber": "0x22",
"chainId": "0x1",
"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"gas": "0x4cb2f", "gas": "0xc350",
"gasPrice": "0x1", "gasPrice": "0x6fd1ca4a",
"hash": "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310", "maxPriorityFeePerGas": "0x3b9aca00",
"input": "0x9dc2c8f5", "maxFeePerGas": "0xb2d05e00",
"nonce": "0x1f", "maxFeePerBlobGas": "0x3b9aca00",
"hash": "0x7c80f35a47f1d432d46add30f262c45f9578e2b1352dbaca0256af1ff3235532",
"input": "0x12a7b914",
"nonce": "0x21",
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"transactionIndex": "0x0", "transactionIndex": "0x0",
"type" : "0x0", "type": "0x3",
"value": "0xa", "value": "0x0",
"v": "0x1b", "yParity": "0x0",
"r": "0x705b002a7df60707d33812e0298411721be20ea5a2f533707295140d89263b79", "r": "0x6ae0612cfda43a9b464b10b4881c6fc2e4c24533cf89bbe07934da65c3ae49ce",
"s": "0x78024390784f24160739533b3ceea2698289a02afd9cc768581b4aa3d5f4b105" "s": "0x125387aeb222ec51130cf99cbdabf24bd4a881914faed69f254e4a3f4bc507fc",
"blobVersionedHashes": [
"0x0100000000000000000000000000000000000000000000000000000000000000",
"0x0102000000000000000000000000000000000000000000000000000000000000"
]
} }
}, },
"statusCode": 200 "statusCode": 200

@ -12,21 +12,30 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 484, "id": 484,
"result": { "result": {
"blockHash": "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53", "accessList": [],
"blockNumber": "0x20", "blockHash": "0x4859ea10d276f6df988eabd48a02e0696cfd3deb769d2a5e0e416a5f3191028a",
"blockNumber": "0x22",
"chainId": "0x1",
"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"gas": "0x4cb2f", "gas": "0xc350",
"gasPrice": "0x1", "gasPrice": "0x6fd1ca4a",
"hash": "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310", "maxPriorityFeePerGas": "0x3b9aca00",
"input": "0x9dc2c8f5", "maxFeePerGas": "0xb2d05e00",
"nonce": "0x1f", "maxFeePerBlobGas": "0x3b9aca00",
"hash": "0x7c80f35a47f1d432d46add30f262c45f9578e2b1352dbaca0256af1ff3235532",
"input": "0x12a7b914",
"nonce": "0x21",
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"transactionIndex": "0x0", "transactionIndex": "0x0",
"type" : "0x0", "type": "0x3",
"value": "0xa", "value": "0x0",
"v": "0x1b", "yParity": "0x0",
"r": "0x705b002a7df60707d33812e0298411721be20ea5a2f533707295140d89263b79", "r": "0x6ae0612cfda43a9b464b10b4881c6fc2e4c24533cf89bbe07934da65c3ae49ce",
"s": "0x78024390784f24160739533b3ceea2698289a02afd9cc768581b4aa3d5f4b105" "s": "0x125387aeb222ec51130cf99cbdabf24bd4a881914faed69f254e4a3f4bc507fc",
"blobVersionedHashes": [
"0x0100000000000000000000000000000000000000000000000000000000000000",
"0x0102000000000000000000000000000000000000000000000000000000000000"
]
} }
}, },
"statusCode": 200 "statusCode": 200

@ -11,7 +11,7 @@
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 488, "id": 488,
"result": "0x20" "result": "0x22"
}, },
"statusCode": 200 "statusCode": 200
} }

@ -11,7 +11,7 @@
"response": { "response": {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 488, "id": 488,
"result": "0x20" "result": "0x22"
}, },
"statusCode": 200 "statusCode": 200
} }

@ -50,7 +50,6 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import com.google.common.primitives.Longs; import com.google.common.primitives.Longs;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
@ -488,18 +487,25 @@ public class Transaction
@Override @Override
public BigInteger getV() { 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()); 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) { if (transactionType != null && transactionType != TransactionType.FRONTIER) {
// EIP-2718 typed transaction, return yParity: // EIP-2718 typed transaction, return yParity:
return recId; return BigInteger.valueOf(signature.getRecId());
} else {
if (chainId.isEmpty()) {
return recId.add(REPLAY_UNPROTECTED_V_BASE);
} else { } else {
return recId.add(REPLAY_PROTECTED_V_BASE).add(TWO.multiply(chainId.get())); // legacy types never return yParity
} return null;
} }
} }
@ -532,14 +538,12 @@ public class Transaction
private void memoizeHashAndSize() { private void memoizeHashAndSize() {
final Bytes bytes = TransactionEncoder.encodeOpaqueBytes(this, EncodingContext.BLOCK_BODY); final Bytes bytes = TransactionEncoder.encodeOpaqueBytes(this, EncodingContext.BLOCK_BODY);
hash = Hash.hash(bytes); hash = Hash.hash(bytes);
if (transactionType.supportsBlob()) { if (transactionType.supportsBlob() && getBlobsWithCommitments().isPresent()) {
if (getBlobsWithCommitments().isPresent()) {
final Bytes pooledBytes = final Bytes pooledBytes =
TransactionEncoder.encodeOpaqueBytes(this, EncodingContext.POOLED_TRANSACTION); TransactionEncoder.encodeOpaqueBytes(this, EncodingContext.POOLED_TRANSACTION);
size = pooledBytes.size(); size = pooledBytes.size();
return; return;
} }
}
size = bytes.size(); size = bytes.size();
} }
@ -671,7 +675,7 @@ public class Transaction
* @return the list of transaction hashes * @return the list of transaction hashes
*/ */
public static List<Hash> toHashList(final Collection<Transaction> transactions) { public static List<Hash> toHashList(final Collection<Transaction> transactions) {
return transactions.stream().map(Transaction::getHash).collect(Collectors.toUnmodifiableList()); return transactions.stream().map(Transaction::getHash).toList();
} }
private static Bytes32 computeSenderRecoveryHash( private static Bytes32 computeSenderRecoveryHash(
@ -691,14 +695,10 @@ public class Transaction
if (transactionType.requiresChainId()) { if (transactionType.requiresChainId()) {
checkArgument(chainId.isPresent(), "Transaction type %s requires chainId", transactionType); checkArgument(chainId.isPresent(), "Transaction type %s requires chainId", transactionType);
} }
final Bytes preimage; final Bytes preimage =
switch (transactionType) { switch (transactionType) {
case FRONTIER: case FRONTIER -> frontierPreimage(nonce, gasPrice, gasLimit, to, value, payload, chainId);
preimage = frontierPreimage(nonce, gasPrice, gasLimit, to, value, payload, chainId); case EIP1559 -> eip1559Preimage(
break;
case EIP1559:
preimage =
eip1559Preimage(
nonce, nonce,
maxPriorityFeePerGas, maxPriorityFeePerGas,
maxFeePerGas, maxFeePerGas,
@ -708,10 +708,7 @@ public class Transaction
payload, payload,
chainId, chainId,
accessList); accessList);
break; case BLOB -> blobPreimage(
case BLOB:
preimage =
blobPreimage(
nonce, nonce,
maxPriorityFeePerGas, maxPriorityFeePerGas,
maxFeePerGas, maxFeePerGas,
@ -723,10 +720,7 @@ public class Transaction
chainId, chainId,
accessList, accessList,
versionedHashes); versionedHashes);
break; case ACCESS_LIST -> accessListPreimage(
case ACCESS_LIST:
preimage =
accessListPreimage(
nonce, nonce,
gasPrice, gasPrice,
gasLimit, gasLimit,
@ -738,11 +732,7 @@ public class Transaction
new IllegalStateException( new IllegalStateException(
"Developer error: the transaction should be guaranteed to have an access list here")), "Developer error: the transaction should be guaranteed to have an access list here")),
chainId); chainId);
break; };
default:
throw new IllegalStateException(
"Developer error. Didn't specify signing hash preimage computation");
}
return keccak256(preimage); return keccak256(preimage);
} }
@ -881,10 +871,9 @@ public class Transaction
@Override @Override
public boolean equals(final Object other) { public boolean equals(final Object other) {
if (!(other instanceof Transaction)) { if (!(other instanceof Transaction that)) {
return false; return false;
} }
final Transaction that = (Transaction) other;
return Objects.equals(this.chainId, that.chainId) return Objects.equals(this.chainId, that.chainId)
&& this.gasLimit == that.gasLimit && this.gasLimit == that.gasLimit
&& Objects.equals(this.gasPrice, that.gasPrice) && Objects.equals(this.gasPrice, that.gasPrice)
@ -926,9 +915,7 @@ public class Transaction
sb.append("type=").append(getType()).append(", "); sb.append("type=").append(getType()).append(", ");
sb.append("nonce=").append(getNonce()).append(", "); sb.append("nonce=").append(getNonce()).append(", ");
getGasPrice() getGasPrice()
.ifPresent( .ifPresent(gp -> sb.append("gasPrice=").append(gp.toHumanReadableString()).append(", "));
gasPrice ->
sb.append("gasPrice=").append(gasPrice.toHumanReadableString()).append(", "));
if (getMaxPriorityFeePerGas().isPresent() && getMaxFeePerGas().isPresent()) { if (getMaxPriorityFeePerGas().isPresent() && getMaxFeePerGas().isPresent()) {
sb.append("maxPriorityFeePerGas=") sb.append("maxPriorityFeePerGas=")
.append(getMaxPriorityFeePerGas().map(Wei::toHumanReadableString).get()) .append(getMaxPriorityFeePerGas().map(Wei::toHumanReadableString).get())
@ -981,8 +968,7 @@ public class Transaction
sb.append(getSender()).append(", "); sb.append(getSender()).append(", ");
sb.append(getType()).append(", "); sb.append(getType()).append(", ");
getGasPrice() getGasPrice()
.ifPresent( .ifPresent(gp -> sb.append("gp: ").append(gp.toHumanReadableString()).append(", "));
gasPrice -> sb.append("gp: ").append(gasPrice.toHumanReadableString()).append(", "));
if (getMaxPriorityFeePerGas().isPresent() && getMaxFeePerGas().isPresent()) { if (getMaxPriorityFeePerGas().isPresent() && getMaxFeePerGas().isPresent()) {
sb.append("mf: ") sb.append("mf: ")
.append(getMaxFeePerGas().map(Wei::toHumanReadableString).get()) .append(getMaxFeePerGas().map(Wei::toHumanReadableString).get())
@ -995,7 +981,7 @@ public class Transaction
} }
sb.append("gl: ").append(getGasLimit()).append(", "); sb.append("gl: ").append(getGasLimit()).append(", ");
sb.append("v: ").append(getValue().toHumanReadableString()).append(", "); sb.append("v: ").append(getValue().toHumanReadableString()).append(", ");
getTo().ifPresent(to -> sb.append("to: ").append(to)); getTo().ifPresent(t -> sb.append("to: ").append(t));
return sb.append("}").toString(); return sb.append("}").toString();
} }
@ -1019,26 +1005,18 @@ public class Transaction
* @return a copy of the transaction * @return a copy of the transaction
*/ */
public Transaction detachedCopy() { public Transaction detachedCopy() {
final Optional<Address> detachedTo = final Optional<Address> detachedTo = to.map(address -> Address.wrap(address.copy()));
to.isEmpty() ? to : Optional.of(Address.wrap(to.get().copy()));
final Optional<List<AccessListEntry>> detachedAccessList = final Optional<List<AccessListEntry>> detachedAccessList =
maybeAccessList.isEmpty() maybeAccessList.map(
? maybeAccessList accessListEntries ->
: Optional.of( accessListEntries.stream().map(this::accessListDetachedCopy).toList());
maybeAccessList.get().stream().map(this::accessListDetachedCopy).toList());
final Optional<List<VersionedHash>> detachedVersionedHashes = final Optional<List<VersionedHash>> detachedVersionedHashes =
versionedHashes.isEmpty() versionedHashes.map(
? versionedHashes hashes -> hashes.stream().map(vh -> new VersionedHash(vh.toBytes().copy())).toList());
: Optional.of(
versionedHashes.get().stream()
.map(vh -> new VersionedHash(vh.toBytes().copy()))
.toList());
final Optional<BlobsWithCommitments> detachedBlobsWithCommitments = final Optional<BlobsWithCommitments> detachedBlobsWithCommitments =
blobsWithCommitments.isEmpty() blobsWithCommitments.map(
? blobsWithCommitments withCommitments ->
: Optional.of( blobsWithCommitmentsDetachedCopy(withCommitments, detachedVersionedHashes.get()));
blobsWithCommitmentsDetachedCopy(
blobsWithCommitments.get(), detachedVersionedHashes.get()));
return new Transaction( return new Transaction(
true, true,
@ -1276,7 +1254,7 @@ public class Transaction
this.versionedHashes = this.versionedHashes =
kzgCommitments.stream() kzgCommitments.stream()
.map(c -> new VersionedHash(SHA256_VERSION_ID, Sha256Hash.sha256(c.getData()))) .map(c -> new VersionedHash(SHA256_VERSION_ID, Sha256Hash.sha256(c.getData())))
.collect(Collectors.toList()); .toList();
} }
this.blobsWithCommitments = this.blobsWithCommitments =
new BlobsWithCommitments(kzgCommitments, blobs, kzgProofs, versionedHashes); new BlobsWithCommitments(kzgCommitments, blobs, kzgProofs, versionedHashes);

@ -44,13 +44,13 @@ import org.hyperledger.besu.testutil.BlockTestUtil.ChainResources;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import com.google.common.base.Charsets;
import com.google.common.io.Resources; import com.google.common.io.Resources;
public class BlockchainSetupUtil { public class BlockchainSetupUtil {
@ -113,6 +113,10 @@ public class BlockchainSetupUtil {
return createForEthashChain(BlockTestUtil.getTestChainResources(), storageFormat); return createForEthashChain(BlockTestUtil.getTestChainResources(), storageFormat);
} }
public static BlockchainSetupUtil forHiveTesting(final DataStorageFormat storageFormat) {
return createForEthashChain(BlockTestUtil.getHiveTestChainResources(), storageFormat);
}
public static BlockchainSetupUtil forMainnet() { public static BlockchainSetupUtil forMainnet() {
return createForEthashChain(BlockTestUtil.getMainnetResources(), DataStorageFormat.FOREST); return createForEthashChain(BlockTestUtil.getMainnetResources(), DataStorageFormat.FOREST);
} }
@ -162,7 +166,8 @@ public class BlockchainSetupUtil {
final ProtocolContextProvider protocolContextProvider, final ProtocolContextProvider protocolContextProvider,
final EthScheduler scheduler) { final EthScheduler scheduler) {
try { try {
final String genesisJson = Resources.toString(chainResources.getGenesisURL(), Charsets.UTF_8); final String genesisJson =
Resources.toString(chainResources.getGenesisURL(), StandardCharsets.UTF_8);
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(genesisJson); final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(genesisJson);
final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfigFile); final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfigFile);

Loading…
Cancel
Save