From 8d3b7da99c50e776f1ffcc7cd6fb25b5d153c819 Mon Sep 17 00:00:00 2001 From: Sunny Jiao <> Date: Mon, 15 Sep 2025 14:44:01 +0800 Subject: [PATCH 1/5] add GetPaginatedNowWitnessList into SolidityNodeHttpApiService --- .../services/http/solidity/SolidityNodeHttpApiService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java index ea08d2d42cf..359adfc2b39 100644 --- a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java @@ -44,6 +44,7 @@ import org.tron.core.services.http.GetNodeInfoServlet; import org.tron.core.services.http.GetNowBlockServlet; import org.tron.core.services.http.GetPaginatedAssetIssueListServlet; +import org.tron.core.services.http.GetPaginatedNowWitnessListServlet; import org.tron.core.services.http.GetRewardServlet; import org.tron.core.services.http.GetTransactionCountByBlockNumServlet; import org.tron.core.services.http.GetTransactionInfoByBlockNumServlet; @@ -92,6 +93,8 @@ public class SolidityNodeHttpApiService extends HttpService { @Autowired private ListWitnessesServlet listWitnessesServlet; @Autowired + private GetPaginatedNowWitnessListServlet getPaginatedNowWitnessListServlet; + @Autowired private GetAssetIssueListServlet getAssetIssueListServlet; @Autowired private GetPaginatedAssetIssueListServlet getPaginatedAssetIssueListServlet; @@ -174,6 +177,8 @@ protected void addServlet(ServletContextHandler context) { // same as FullNode context.addServlet(new ServletHolder(getAccountServlet), "/walletsolidity/getaccount"); context.addServlet(new ServletHolder(listWitnessesServlet), "/walletsolidity/listwitnesses"); + context.addServlet(new ServletHolder(getPaginatedNowWitnessListServlet), + "/walletsolidity/getpaginatednowwitnesslist"); context.addServlet(new ServletHolder(getAssetIssueListServlet), "/walletsolidity/getassetissuelist"); context.addServlet(new ServletHolder(getPaginatedAssetIssueListServlet), From 82f93fff9a4ebc6622b8dfc551f65fd6f7eeb544 Mon Sep 17 00:00:00 2001 From: Sunny Jiao <> Date: Mon, 15 Sep 2025 17:17:36 +0800 Subject: [PATCH 2/5] add isSolidityRequest check for MaintenanceUnavailableException --- framework/src/main/java/org/tron/core/Wallet.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 5397648d106..8c93c3f63a2 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -174,6 +174,7 @@ import org.tron.core.db.Manager; import org.tron.core.db.TransactionContext; import org.tron.core.db2.core.Chainbase; +import org.tron.core.db2.core.Chainbase.Cursor; import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ContractExeException; @@ -784,8 +785,10 @@ public WitnessList getPaginatedNowWitnessList(long offset, long limit) throws In the maintenance period, the VoteStores will be cleared. To avoid the race condition of VoteStores deleted but Witness vote counts not updated, return retry error. + Only apply to non-solidity request. */ - if (chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1) { + boolean isSolidityRequest = Args.getInstance().isSolidityNode() || (getCursor() == Cursor.SOLIDITY); + if (!isSolidityRequest && chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1) { String message = "Service temporarily unavailable during maintenance period. Please try again later."; throw new MaintenanceUnavailableException(message); From a6ca75efc0d3abf060df6ac524fe049742024402 Mon Sep 17 00:00:00 2001 From: Sunny Jiao <> Date: Tue, 16 Sep 2025 14:03:17 +0800 Subject: [PATCH 3/5] add unit tests --- .../src/test/java/org/tron/core/WalletTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/framework/src/test/java/org/tron/core/WalletTest.java b/framework/src/test/java/org/tron/core/WalletTest.java index 10b0aa178f6..e388d3375c4 100644 --- a/framework/src/test/java/org/tron/core/WalletTest.java +++ b/framework/src/test/java/org/tron/core/WalletTest.java @@ -71,6 +71,7 @@ import org.tron.core.capsule.VotesCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.config.args.Args; +import org.tron.core.db2.core.Chainbase; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.MaintenanceUnavailableException; @@ -867,6 +868,20 @@ public void testGetPaginatedNowWitnessList_Error() { Assert.assertTrue("Should throw MaintenanceClearingException", e instanceof MaintenanceUnavailableException); } + + try { + Args.getInstance().setSolidityNode(true); + wallet.getPaginatedNowWitnessList(0, 10); + Args.getInstance().setSolidityNode(false); + + dbManager.setCursor(Chainbase.Cursor.SOLIDITY); + wallet.getPaginatedNowWitnessList(0, 10); + dbManager.setCursor(Chainbase.Cursor.HEAD); + } catch (Exception e) { + Assert.assertFalse("Should not throw MaintenanceClearingException", + e instanceof MaintenanceUnavailableException); + } + dbManager.getChainBaseManager().getDynamicPropertiesStore().saveStateFlag(0); } From 6c3bda450795215d461618accaac40b629d52b03 Mon Sep 17 00:00:00 2001 From: Sunny Jiao <> Date: Wed, 17 Sep 2025 11:25:45 +0800 Subject: [PATCH 4/5] update review condition --- framework/src/main/java/org/tron/core/Wallet.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 8c93c3f63a2..c5f8f0bd744 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -785,10 +785,11 @@ public WitnessList getPaginatedNowWitnessList(long offset, long limit) throws In the maintenance period, the VoteStores will be cleared. To avoid the race condition of VoteStores deleted but Witness vote counts not updated, return retry error. - Only apply to non-solidity request. + Only apply to requests that rely on the latest block, + which means the normal fullnode requests with HEAD cursor. */ - boolean isSolidityRequest = Args.getInstance().isSolidityNode() || (getCursor() == Cursor.SOLIDITY); - if (!isSolidityRequest && chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1) { + if (!Args.getInstance().isSolidityNode() && (getCursor() == Cursor.HEAD) && + chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1) { String message = "Service temporarily unavailable during maintenance period. Please try again later."; throw new MaintenanceUnavailableException(message); From 6a08c39c52c9245fbe74731e6e49a20e42da268e Mon Sep 17 00:00:00 2001 From: Sunny Jiao <> Date: Wed, 17 Sep 2025 11:31:47 +0800 Subject: [PATCH 5/5] fix condition order --- framework/src/main/java/org/tron/core/Wallet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index c5f8f0bd744..1632de2ac0a 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -788,8 +788,8 @@ public WitnessList getPaginatedNowWitnessList(long offset, long limit) throws Only apply to requests that rely on the latest block, which means the normal fullnode requests with HEAD cursor. */ - if (!Args.getInstance().isSolidityNode() && (getCursor() == Cursor.HEAD) && - chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1) { + boolean isMaintenance = chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1; + if (isMaintenance && !Args.getInstance().isSolidityNode() && getCursor() == Cursor.HEAD) { String message = "Service temporarily unavailable during maintenance period. Please try again later."; throw new MaintenanceUnavailableException(message);