Skip to content

Commit f2fde52

Browse files
fab-102fehee
andcommitted
Support chainId in CallParameters (hyperledger#7720)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>Signed-off-by: Chulhee lee <leefehee@naver.com>
1 parent 9e32b2b commit f2fde52

File tree

10 files changed

+157
-10
lines changed

10 files changed

+157
-10
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
- Add configuration of Consolidation Request Contract Address via genesis configuration [#7647](https://github.com/hyperledger/besu/pull/7647)
1919
- Interrupt pending transaction processing on block creation timeout [#7673](https://github.com/hyperledger/besu/pull/7673)
2020
- Align gas cap calculation for transaction simulation to Geth approach [#7703](https://github.com/hyperledger/besu/pull/7703)
21-
- Expose chainId in the `BlockchainService` [7702](https://github.com/hyperledger/besu/pull/7702)
21+
- Expose chainId in the `BlockchainService` [#7702](https://github.com/hyperledger/besu/pull/7702)
22+
- Add support for `chainId` in `CallParameters` [#7720](https://github.com/hyperledger/besu/pull/7720)
2223

2324
### Bug fixes
2425
- Fix mounted data path directory permissions for besu user [#7575](https://github.com/hyperledger/besu/pull/7575)

ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ public class JsonRpcTestMethodsFactory {
6868
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
6969
private static final String CLIENT_VERSION = "0.1.0";
7070
private static final String CLIENT_COMMIT = "12345678";
71-
private static final BigInteger NETWORK_ID = BigInteger.valueOf(123);
7271

7372
private final BlockchainImporter importer;
7473
private final MutableBlockchain blockchain;
7574
private final WorldStateArchive stateArchive;
7675
private final ProtocolContext context;
7776
private final BlockchainQueries blockchainQueries;
7877
private final Synchronizer synchronizer;
78+
private final ProtocolSchedule protocolSchedule;
7979

8080
public JsonRpcTestMethodsFactory(final BlockchainImporter importer) {
8181
this.importer = importer;
@@ -84,7 +84,7 @@ public JsonRpcTestMethodsFactory(final BlockchainImporter importer) {
8484
this.importer.getGenesisState().writeStateTo(stateArchive.getMutable());
8585
this.context = new ProtocolContext(blockchain, stateArchive, null, new BadBlockManager());
8686

87-
final ProtocolSchedule protocolSchedule = importer.getProtocolSchedule();
87+
this.protocolSchedule = importer.getProtocolSchedule();
8888
this.synchronizer = mock(Synchronizer.class);
8989

9090
for (final Block block : importer.getBlocks()) {
@@ -106,6 +106,7 @@ public JsonRpcTestMethodsFactory(
106106
this.blockchain = blockchain;
107107
this.stateArchive = stateArchive;
108108
this.context = context;
109+
this.protocolSchedule = importer.getProtocolSchedule();
109110
this.blockchainQueries =
110111
new BlockchainQueries(
111112
importer.getProtocolSchedule(),
@@ -126,6 +127,7 @@ public JsonRpcTestMethodsFactory(
126127
this.stateArchive = stateArchive;
127128
this.context = context;
128129
this.synchronizer = synchronizer;
130+
this.protocolSchedule = importer.getProtocolSchedule();
129131
this.blockchainQueries =
130132
new BlockchainQueries(
131133
importer.getProtocolSchedule(),
@@ -142,6 +144,10 @@ public WorldStateArchive getStateArchive() {
142144
return stateArchive;
143145
}
144146

147+
public BigInteger getChainId() {
148+
return protocolSchedule.getChainId().get();
149+
}
150+
145151
public Map<String, JsonRpcMethod> methods() {
146152
final P2PNetwork peerDiscovery = mock(P2PNetwork.class);
147153
final EthPeers ethPeers = mock(EthPeers.class);
@@ -183,7 +189,7 @@ public Map<String, JsonRpcMethod> methods() {
183189
CLIENT_NODE_NAME,
184190
CLIENT_VERSION,
185191
CLIENT_COMMIT,
186-
NETWORK_ID,
192+
getChainId(),
187193
new StubGenesisConfigOptions(),
188194
peerDiscovery,
189195
blockchainQueries,

ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java

+22
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
3131
import org.hyperledger.besu.testutil.BlockTestUtil;
3232

33+
import java.math.BigInteger;
3334
import java.util.Map;
3435

3536
import com.google.common.base.Charsets;
@@ -142,6 +143,7 @@ public void shouldReturnErrorWithGasPriceLessThanCurrentBaseFee() {
142143
public void shouldReturnSuccessWithValidMaxFeePerGas() {
143144
final JsonCallParameter callParameter =
144145
new JsonCallParameter.JsonCallParameterBuilder()
146+
.withChainId(BLOCKCHAIN.getChainId())
145147
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
146148
.withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"))
147149
.withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01"))
@@ -158,6 +160,26 @@ public void shouldReturnSuccessWithValidMaxFeePerGas() {
158160
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
159161
}
160162

163+
@Test
164+
public void shouldReturnErrorWithInvalidChainId() {
165+
final JsonCallParameter callParameter =
166+
new JsonCallParameter.JsonCallParameterBuilder()
167+
.withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE))
168+
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
169+
.withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"))
170+
.withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01"))
171+
.withInput(Bytes.fromHexString("0x2e64cec1"))
172+
.build();
173+
174+
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
175+
final JsonRpcResponse expectedResponse =
176+
new JsonRpcErrorResponse(null, RpcErrorType.WRONG_CHAIN_ID);
177+
178+
final JsonRpcResponse response = method.response(request);
179+
180+
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
181+
}
182+
161183
@Test
162184
public void shouldReturnSuccessWithValidMaxFeePerGasAndMaxPriorityFeePerGas() {
163185
final JsonCallParameter callParameter =

ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java

+30
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@
2525
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
2626
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
2727
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
28+
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
29+
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
2830
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
2931
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
32+
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
33+
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
3034
import org.hyperledger.besu.testutil.BlockTestUtil;
3135

36+
import java.math.BigInteger;
3237
import java.util.List;
3338
import java.util.Map;
3439

@@ -112,6 +117,7 @@ public void shouldReturnExpectedValueForContractDeploy() {
112117
public void shouldReturnExpectedValueForContractDeploy_WithAccessList() {
113118
final JsonCallParameter callParameter =
114119
new JsonCallParameter.JsonCallParameterBuilder()
120+
.withChainId(BLOCKCHAIN.getChainId())
115121
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
116122
.withInput(
117123
Bytes.fromHexString(
@@ -124,6 +130,30 @@ public void shouldReturnExpectedValueForContractDeploy_WithAccessList() {
124130
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
125131
}
126132

133+
@Test
134+
public void shouldReturnErrorWithInvalidChainId() {
135+
final JsonCallParameter callParameter =
136+
new JsonCallParameter.JsonCallParameterBuilder()
137+
.withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE))
138+
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
139+
.withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"))
140+
.withValue(Wei.ONE)
141+
.build();
142+
143+
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
144+
final JsonRpcResponse expectedResponse =
145+
new JsonRpcErrorResponse(
146+
null,
147+
JsonRpcError.from(
148+
ValidationResult.invalid(
149+
TransactionInvalidReason.WRONG_CHAIN_ID,
150+
"transaction was meant for chain id 1983 and not this chain id 1982")));
151+
152+
final JsonRpcResponse response = method.response(request);
153+
154+
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
155+
}
156+
127157
private List<AccessListEntry> createAccessList() {
128158
return List.of(
129159
new AccessListEntry(

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractEstimateGas.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ protected abstract Object resultByBlockHeader(
103103
protected CallParameter overrideGasLimitAndPrice(
104104
final JsonCallParameter callParams, final long gasLimit) {
105105
return new CallParameter(
106+
callParams.getChainId(),
106107
callParams.getFrom(),
107108
callParams.getTo(),
108109
gasLimit,
@@ -111,7 +112,9 @@ protected CallParameter overrideGasLimitAndPrice(
111112
callParams.getMaxFeePerGas(),
112113
callParams.getValue(),
113114
callParams.getPayload(),
114-
callParams.getAccessList());
115+
callParams.getAccessList(),
116+
callParams.getMaxFeePerBlobGas(),
117+
callParams.getBlobVersionedHashes());
115118
}
116119

117120
/**

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java

+19
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
import org.hyperledger.besu.datatypes.Address;
1919
import org.hyperledger.besu.datatypes.VersionedHash;
2020
import org.hyperledger.besu.datatypes.Wei;
21+
import org.hyperledger.besu.ethereum.core.json.ChainIdDeserializer;
2122
import org.hyperledger.besu.ethereum.core.json.GasDeserializer;
2223
import org.hyperledger.besu.ethereum.core.json.HexStringDeserializer;
2324
import org.hyperledger.besu.ethereum.transaction.CallParameter;
2425

26+
import java.math.BigInteger;
2527
import java.util.List;
2628
import java.util.Optional;
2729

@@ -41,6 +43,7 @@
4143
*
4244
* <pre>{@code
4345
* JsonCallParameter param = new JsonCallParameter.JsonCallParameterBuilder()
46+
* .withChainId(Optional.of(BigInteger.ONE))
4447
* .withFrom(Address.fromHexString("0x..."))
4548
* .withTo(Address.fromHexString("0x..."))
4649
* .withGas(21000L)
@@ -71,6 +74,7 @@ public class JsonCallParameter extends CallParameter {
7174
private final Optional<Boolean> strict;
7275

7376
private JsonCallParameter(
77+
final Optional<BigInteger> chainId,
7478
final Address from,
7579
final Address to,
7680
final Long gasLimit,
@@ -85,6 +89,7 @@ private JsonCallParameter(
8589
final Optional<List<VersionedHash>> blobVersionedHashes) {
8690

8791
super(
92+
chainId,
8893
from,
8994
to,
9095
gasLimit,
@@ -115,6 +120,7 @@ public Optional<Boolean> isMaybeStrict() {
115120
*/
116121
public static final class JsonCallParameterBuilder {
117122
private Optional<Boolean> strict = Optional.empty();
123+
private Optional<BigInteger> chainId = Optional.empty();
118124
private Address from;
119125
private Address to;
120126
private long gas = -1;
@@ -145,6 +151,18 @@ public JsonCallParameterBuilder withStrict(final Boolean strict) {
145151
return this;
146152
}
147153

154+
/**
155+
* Sets the optional "chainId" for the {@link JsonCallParameter}.
156+
*
157+
* @param chainId the chainId
158+
* @return the {@link JsonCallParameterBuilder} instance for chaining
159+
*/
160+
@JsonDeserialize(using = ChainIdDeserializer.class)
161+
public JsonCallParameterBuilder withChainId(final BigInteger chainId) {
162+
this.chainId = Optional.of(chainId);
163+
return this;
164+
}
165+
148166
/**
149167
* Sets the "from" address for the {@link JsonCallParameter}. This address represents the sender
150168
* of the call.
@@ -346,6 +364,7 @@ public JsonCallParameter build() {
346364
final Bytes payload = input != null ? input : data;
347365

348366
return new JsonCallParameter(
367+
chainId,
349368
from,
350369
to,
351370
gas,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright contributors to Hyperledger Besu.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*
13+
* SPDX-License-Identifier: Apache-2.0
14+
*/
15+
package org.hyperledger.besu.ethereum.core.json;
16+
17+
import java.io.IOException;
18+
import java.math.BigInteger;
19+
20+
import com.fasterxml.jackson.core.JsonParser;
21+
import com.fasterxml.jackson.databind.DeserializationContext;
22+
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
23+
import org.apache.tuweni.units.bigints.UInt256;
24+
25+
public class ChainIdDeserializer extends StdDeserializer<BigInteger> {
26+
27+
public ChainIdDeserializer() {
28+
this(null);
29+
}
30+
31+
public ChainIdDeserializer(final Class<?> vc) {
32+
super(vc);
33+
}
34+
35+
@Override
36+
public BigInteger deserialize(final JsonParser jsonparser, final DeserializationContext context)
37+
throws IOException {
38+
final var chainId =
39+
UInt256.fromHexString(jsonparser.getCodec().readValue(jsonparser, String.class))
40+
.toBigInteger();
41+
if (chainId.signum() <= 0) {
42+
throw new IllegalArgumentException("Non positive chain id: " + chainId);
43+
}
44+
return chainId;
45+
}
46+
}

0 commit comments

Comments
 (0)