diff --git a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java index ab2dbce3f..7961305c4 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.controller; import static com.google.common.base.Preconditions.checkNotNull; +import org.hyperledger.besu.config.BftConfigOptions; import org.hyperledger.besu.config.BftFork; import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.config.QbftFork; @@ -103,6 +104,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { private ForksSchedule qbftForksSchedule; private ValidatorPeers peers; private TransactionValidatorProvider transactionValidatorProvider; + private BftConfigOptions bftConfigOptions; /** Default Constructor. */ public QbftBesuControllerBuilder() {} @@ -120,6 +122,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { qbftConfig = genesisConfigOptions.getQbftConfigOptions(); bftEventQueue = new BftEventQueue(qbftConfig.getMessageQueueLimit()); qbftForksSchedule = QbftForksSchedulesFactory.create(genesisConfigOptions); + bftConfigOptions = qbftConfig; } @Override @@ -132,7 +135,8 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { protocolContext, protocolSchedule, miningParameters, - createReadOnlyValidatorProvider(protocolContext.getBlockchain())); + createReadOnlyValidatorProvider(protocolContext.getBlockchain()), + bftConfigOptions); } private ValidatorProvider createReadOnlyValidatorProvider(final Blockchain blockchain) { diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java index 366d1c560..ce8ce388f 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java @@ -14,11 +14,13 @@ */ package org.hyperledger.besu.consensus.qbft.jsonrpc; +import org.hyperledger.besu.config.BftConfigOptions; import org.hyperledger.besu.consensus.common.BlockInterface; import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftDiscardValidatorVote; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetPendingVotes; +import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetRequestTimeoutSeconds; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetSignerMetrics; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBlockHash; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBlockNumber; @@ -40,6 +42,7 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods { private final ValidatorProvider readOnlyValidatorProvider; private final ProtocolSchedule protocolSchedule; private final MiningParameters miningParameters; + private final BftConfigOptions bftConfig; /** * Instantiates a new Qbft json rpc methods. @@ -48,16 +51,19 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods { * @param protocolSchedule the protocol schedule * @param miningParameters the mining parameters * @param readOnlyValidatorProvider the read only validator provider + * @param bftConfig the BFT config options, containing QBFT-specific settings */ public QbftJsonRpcMethods( final ProtocolContext context, final ProtocolSchedule protocolSchedule, final MiningParameters miningParameters, - final ValidatorProvider readOnlyValidatorProvider) { + final ValidatorProvider readOnlyValidatorProvider, + final BftConfigOptions bftConfig) { this.context = context; this.readOnlyValidatorProvider = readOnlyValidatorProvider; this.protocolSchedule = protocolSchedule; this.miningParameters = miningParameters; + this.bftConfig = bftConfig; } @Override @@ -77,12 +83,16 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods { final BlockInterface blockInterface = bftContext.getBlockInterface(); final ValidatorProvider validatorProvider = bftContext.getValidatorProvider(); - return mapOf( - new QbftProposeValidatorVote(validatorProvider), - new QbftGetValidatorsByBlockNumber(blockchainQueries, readOnlyValidatorProvider), - new QbftDiscardValidatorVote(validatorProvider), - new QbftGetValidatorsByBlockHash(context.getBlockchain(), readOnlyValidatorProvider), - new QbftGetSignerMetrics(readOnlyValidatorProvider, blockInterface, blockchainQueries), - new QbftGetPendingVotes(validatorProvider)); + Map methods = + mapOf( + new QbftProposeValidatorVote(validatorProvider), + new QbftGetValidatorsByBlockNumber(blockchainQueries, readOnlyValidatorProvider), + new QbftDiscardValidatorVote(validatorProvider), + new QbftGetValidatorsByBlockHash(context.getBlockchain(), readOnlyValidatorProvider), + new QbftGetSignerMetrics(readOnlyValidatorProvider, blockInterface, blockchainQueries), + new QbftGetPendingVotes(validatorProvider), + new QbftGetRequestTimeoutSeconds(bftConfig)); + + return methods; } } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSeconds.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSeconds.java new file mode 100644 index 000000000..0cd12c95e --- /dev/null +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSeconds.java @@ -0,0 +1,51 @@ +/* + * 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 + */ +package org.hyperledger.besu.consensus.qbft.jsonrpc.methods; + +import org.hyperledger.besu.config.BftConfigOptions; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; + +/** + * Implements the qbft_getRequestTimeoutSeconds RPC method to retrieve the QBFT request timeout in + * seconds. + */ +public class QbftGetRequestTimeoutSeconds implements JsonRpcMethod { + + private final BftConfigOptions bftConfig; + + /** + * Constructs a new QbftGetRequestTimeoutSeconds instance. + * + * @param bftConfig The BFT configuration options + */ + public QbftGetRequestTimeoutSeconds(final BftConfigOptions bftConfig) { + this.bftConfig = bftConfig; + } + + @Override + public String getName() { + return RpcMethod.QBFT_GET_REQUEST_TIMEOUT_SECONDS.getMethodName(); + } + + @Override + public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { + return new JsonRpcSuccessResponse( + requestContext.getRequest().getId(), bftConfig.getRequestTimeoutSeconds()); + } +} diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSecondsTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSecondsTest.java new file mode 100644 index 000000000..bc7e4b8e2 --- /dev/null +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSecondsTest.java @@ -0,0 +1,68 @@ +/* + * 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 + */ +package org.hyperledger.besu.consensus.qbft.jsonrpc.methods; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.config.BftConfigOptions; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class QbftGetRequestTimeoutSecondsTest { + + private static final String JSON_RPC_VERSION = "2.0"; + private static final String METHOD_NAME = "qbft_getRequestTimeoutSeconds"; + + @Mock private BftConfigOptions bftConfigOptions; + + private QbftGetRequestTimeoutSeconds method; + + @BeforeEach + public void setUp() { + this.method = new QbftGetRequestTimeoutSeconds(bftConfigOptions); + } + + @Test + public void shouldReturnCorrectMethodName() { + assertThat(method.getName()).isEqualTo(METHOD_NAME); + } + + @Test + public void shouldReturnCorrectRequestTimeout() { + final int expectedTimeout = 5; + when(bftConfigOptions.getRequestTimeoutSeconds()).thenReturn(expectedTimeout); + JsonRpcRequestContext request = requestWithParams(); + + JsonRpcResponse response = method.response(request); + + assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class); + JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; + assertThat(successResponse.getResult()).isEqualTo(expectedTimeout); + } + + private JsonRpcRequestContext requestWithParams(final Object... params) { + return new JsonRpcRequestContext(new JsonRpcRequest(JSON_RPC_VERSION, METHOD_NAME, params)); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 75da09048..79d33ffba 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -153,6 +153,7 @@ public enum RpcMethod { QBFT_GET_VALIDATORS_BY_BLOCK_NUMBER("qbft_getValidatorsByBlockNumber"), QBFT_PROPOSE_VALIDATOR_VOTE("qbft_proposeValidatorVote"), QBFT_GET_SIGNER_METRICS("qbft_getSignerMetrics"), + QBFT_GET_REQUEST_TIMEOUT_SECONDS("qbft_getRequestTimeoutSeconds"), MINER_CHANGE_TARGET_GAS_LIMIT("miner_changeTargetGasLimit"), MINER_SET_COINBASE("miner_setCoinbase"), MINER_SET_ETHERBASE("miner_setEtherbase"),