Skip to content

Commit 8e1629c

Browse files
author
Sunny Jiao
committed
add check maintenance period and throw error
1 parent b276604 commit 8e1629c

File tree

5 files changed

+85
-30
lines changed

5 files changed

+85
-30
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.tron.core.exception;
2+
3+
/**
4+
* Maintenance clearing exception - thrown when system is in maintenance clearing state
5+
* Please try again later
6+
*/
7+
public class MaintenanceClearingException extends TronException {
8+
9+
public MaintenanceClearingException() {
10+
super();
11+
}
12+
13+
public MaintenanceClearingException(String message) {
14+
super(message);
15+
}
16+
17+
public MaintenanceClearingException(String message, Throwable cause) {
18+
super(message, cause);
19+
}
20+
}

framework/src/main/java/org/tron/core/Wallet.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
import org.tron.core.exception.HeaderNotFound;
183183
import org.tron.core.exception.ItemNotFoundException;
184184
import org.tron.core.exception.JsonRpcInvalidParamsException;
185+
import org.tron.core.exception.MaintenanceClearingException;
185186
import org.tron.core.exception.NonUniqueObjectException;
186187
import org.tron.core.exception.PermissionException;
187188
import org.tron.core.exception.SignatureFormatException;
@@ -770,14 +771,23 @@ public WitnessList getWitnessList() {
770771
return builder.build();
771772
}
772773

773-
public WitnessList getPaginatedNowWitnessList(long offset, long limit) {
774+
public WitnessList getPaginatedNowWitnessList(long offset, long limit) throws MaintenanceClearingException {
774775
if (limit <= 0 || offset < 0) {
775776
return null;
776777
}
777778
if (limit > WITNESS_COUNT_LIMIT_MAX) {
778779
limit = WITNESS_COUNT_LIMIT_MAX;
779780
}
780-
781+
782+
/*
783+
In the maintenance period, the VoteStores will be cleared.
784+
To avoid the race condition of VoteStores deleted but Witness vote counts not updated, return retry error.
785+
*/
786+
if (chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1) {
787+
long maintenanceLogicTime = chainBaseManager.getDynamicPropertiesStore().getMaintenanceSkipSlots() * BLOCK_PRODUCED_INTERVAL / 1000;
788+
String message = "Maintenance clearing, please try again later after " + maintenanceLogicTime + " seconds.";
789+
throw new MaintenanceClearingException(message);
790+
}
781791
// It contains the final vote count at the end of the last epoch.
782792
List<WitnessCapsule> witnessCapsuleList = chainBaseManager.getWitnessStore().getAllWitnesses();
783793
if (offset >= witnessCapsuleList.size()) {

framework/src/main/java/org/tron/core/services/RpcApiService.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import org.tron.core.exception.ContractExeException;
9090
import org.tron.core.exception.ContractValidateException;
9191
import org.tron.core.exception.ItemNotFoundException;
92+
import org.tron.core.exception.MaintenanceClearingException;
9293
import org.tron.core.exception.NonUniqueObjectException;
9394
import org.tron.core.exception.StoreException;
9495
import org.tron.core.exception.VMIllegalException;
@@ -399,8 +400,12 @@ public void listWitnesses(EmptyMessage request, StreamObserver<WitnessList> resp
399400
@Override
400401
public void getPaginatedNowWitnessList(PaginatedMessage request,
401402
StreamObserver<WitnessList> responseObserver) {
402-
responseObserver.onNext(
403-
wallet.getPaginatedNowWitnessList(request.getOffset(), request.getLimit()));
403+
try {
404+
responseObserver.onNext(
405+
wallet.getPaginatedNowWitnessList(request.getOffset(), request.getLimit()));
406+
} catch (MaintenanceClearingException e) {
407+
responseObserver.onError(getRunTimeException(e));
408+
}
404409
responseObserver.onCompleted();
405410
}
406411

@@ -1883,8 +1888,12 @@ public void listWitnesses(EmptyMessage request,
18831888
@Override
18841889
public void getPaginatedNowWitnessList(PaginatedMessage request,
18851890
StreamObserver<WitnessList> responseObserver) {
1886-
responseObserver.onNext(
1887-
wallet.getPaginatedNowWitnessList(request.getOffset(), request.getLimit()));
1891+
try {
1892+
responseObserver.onNext(
1893+
wallet.getPaginatedNowWitnessList(request.getOffset(), request.getLimit()));
1894+
} catch (MaintenanceClearingException e) {
1895+
responseObserver.onError(getRunTimeException(e));
1896+
}
18881897
responseObserver.onCompleted();
18891898
}
18901899

framework/src/main/java/org/tron/core/services/http/GetPaginatedNowWitnessListServlet.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.springframework.stereotype.Component;
99
import org.tron.api.GrpcAPI;
1010
import org.tron.core.Wallet;
11+
import org.tron.core.exception.MaintenanceClearingException;
1112

1213
// Get the paged list of witnesses info with realtime vote counts
1314
@Component
@@ -40,7 +41,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
4041
}
4142

4243
private void fillResponse(long offset, long limit, boolean visible, HttpServletResponse response)
43-
throws IOException {
44+
throws IOException, MaintenanceClearingException {
4445
GrpcAPI.WitnessList reply = wallet.getPaginatedNowWitnessList(offset, limit);
4546
if (reply != null) {
4647
response.getWriter().println(JsonFormat.printToString(reply, visible));

framework/src/test/java/org/tron/core/WalletTest.java

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import org.tron.core.config.args.Args;
7575
import org.tron.core.exception.ContractExeException;
7676
import org.tron.core.exception.ContractValidateException;
77+
import org.tron.core.exception.MaintenanceClearingException;
7778
import org.tron.core.exception.NonUniqueObjectException;
7879
import org.tron.core.store.DynamicPropertiesStore;
7980
import org.tron.core.utils.ProposalUtil.ProposalType;
@@ -858,30 +859,37 @@ public void testGetDelegatedResourceV2() {
858859

859860
@Test
860861
public void testGetPaginatedNowWitnessList_CornerCase() {
861-
GrpcAPI.WitnessList witnessList = wallet.getPaginatedNowWitnessList(-100, 0);
862-
Assert.assertTrue("Should return an empty witness list when offset is negative",
863-
witnessList == null);
864-
865-
witnessList = wallet.getPaginatedNowWitnessList(100, 0);
866-
Assert.assertTrue("Should return an empty witness list when limit is 0",
867-
witnessList == null);
868-
869-
String fakeWitnessAddressPrefix = "fake_witness";
870-
int fakeNumberOfWitnesses = 1000 + 10;
871-
// Mock additional witnesses with vote counts greater than 1000
872-
for (int i = 0; i < fakeNumberOfWitnesses; i++) {
873-
saveWitnessWith(fakeWitnessAddressPrefix + i, 200);
874-
}
862+
try {
863+
// To avoid throw MaintenanceClearingException
864+
dbManager.getChainBaseManager().getDynamicPropertiesStore().saveStateFlag(0);
865+
866+
GrpcAPI.WitnessList witnessList = wallet.getPaginatedNowWitnessList(-100, 0);
867+
Assert.assertTrue("Should return an empty witness list when offset is negative",
868+
witnessList == null);
869+
870+
witnessList = wallet.getPaginatedNowWitnessList(100, 0);
871+
Assert.assertTrue("Should return an empty witness list when limit is 0",
872+
witnessList == null);
873+
874+
String fakeWitnessAddressPrefix = "fake_witness";
875+
int fakeNumberOfWitnesses = 1000 + 10;
876+
// Mock additional witnesses with vote counts greater than 1000
877+
for (int i = 0; i < fakeNumberOfWitnesses; i++) {
878+
saveWitnessWith(fakeWitnessAddressPrefix + i, 200);
879+
}
875880

876-
witnessList = wallet.getPaginatedNowWitnessList(0, 1000000);
877-
// Check the returned witness list should contain 1000 witnesses with descending vote count
878-
Assert.assertTrue("Witness list should contain 1000 witnesses",
879-
witnessList.getWitnessesCount() == 1000);
881+
witnessList = wallet.getPaginatedNowWitnessList(0, 1000000);
882+
// Check the returned witness list should contain 1000 witnesses with descending vote count
883+
Assert.assertTrue("Witness list should contain 1000 witnesses",
884+
witnessList.getWitnessesCount() == 1000);
880885

881-
// clean up, delete the fake witnesses
882-
for (int i = 0; i < fakeNumberOfWitnesses; i++) {
883-
chainBaseManager.getWitnessStore()
884-
.delete(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + i).toByteArray());
886+
// clean up, delete the fake witnesses
887+
for (int i = 0; i < fakeNumberOfWitnesses; i++) {
888+
chainBaseManager.getWitnessStore()
889+
.delete(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + i).toByteArray());
890+
}
891+
} catch (MaintenanceClearingException e) {
892+
Assert.fail(e.getMessage());
885893
}
886894
}
887895

@@ -914,7 +922,14 @@ public void testGetPaginatedNowWitnessList() {
914922
chainBaseManager.getVotesStore().put(votesCapsule.createDbKey(), votesCapsule);
915923

916924
logger.info("now request paginated witness list with 0 offset and 10 limit:");
917-
GrpcAPI.WitnessList witnessList2 = wallet.getPaginatedNowWitnessList(0, 10);
925+
GrpcAPI.WitnessList witnessList2 = null;
926+
try {
927+
// To avoid throw MaintenanceClearingException
928+
dbManager.getChainBaseManager().getDynamicPropertiesStore().saveStateFlag(0);
929+
witnessList2 = wallet.getPaginatedNowWitnessList(0, 10);
930+
} catch (MaintenanceClearingException e) {
931+
Assert.fail(e.getMessage());
932+
}
918933
// Check the returned witness list should contain 10 witnesses with descending vote count
919934
Assert.assertTrue("Witness list should contain 10 witnesses",
920935
witnessList2.getWitnessesCount() == 10);

0 commit comments

Comments
 (0)