Repository navigation
Add a new API to query the real-time vote count of witness #6339
Description
Background
Currently, HTTP/gRPC has an interface /wallet/listwitnesses for querying the number of witness votes in the previous epoch. During the maintenance period, the node calculates the votes of all witnesses and selects the first 27 witnesses as SRs for the next epoch block production. There are the following problems:
-
This interface returns the JSON-format voting results of the previous epoch, which is unchanged in the current epoch, and lacks an interface for real-time query of the number of votes in the current epoch;
-
This interface sorts by the address of the witness instead of the number of votes. Users cannot view the overall ranking and need to sort manually; witnesses cannot easily view their ranking in the previous epoch;
We plan to modify the results of /wallet/listwitnesses, namely return results sorted in descending vote order of the witness; and paln to add a new interface to query all real-time witnesses, also sort them in descending order by the number of votes.
Rationale
Why should this feature exist?
-
For ordinary users, they can easily view the historical ranking and real-time ranking of each witness through the API to vote for themselves;
-
For witnesses who want to become Super Represent (SR), they urgently need to know their real-time votes and rankings in the current epoch so as to attract votes and enter the top 27; for SRs who have entered the top 27 in the previous epoch, they urgently need to understand their leading advantage over the 28th witness and provide an early warning mechanism to remind them to increase votes and avoid losing.
What are the use-cases?
- Developers, SRs & SR candidates need this feature urgently.
Specification
- For the existing interface
/wallet/listwitnessesfor querying the voting results of the previous epoch, the current proto is:
rpc ListWitnesses (EmptyMessage) returns (WitnessList) {...}
Since no parameters can be taken in EmptyMessage, the list of witnesses returned by getWitnessList function is sorted in reverse order by vote count by default; if the vote counts are the same, they are sorted in lexicographical order by witness address.
- A new interface
/wallet/listrealtimewitnessis added, which supports HTTP/gRPC and is used to query the real-time vote count of all witnesses in the current epoch. The results are sorted in reverse order by the vote count. If the vote count is the same, they are sorted in lexicographical order of the witness address. In order to avoid too large query results, pagination query is introduced:
rpc ListRealtimeWitness (PaginatedMessage) returns (WitnessList) {
};
In the database, WitnessStore stores the cumulative number of votes cast by users for all witnesses after the last epoch, excluding the votes cast in this epoch; the incremental votes cast in this epoch are stored in VotesStore. The incremental votes may actually be positive or negative, and generally the amount of data is small. By adding up the data of WitnessStore and VotesStore, real-time witness voting data can be calculated.
The above two changes should support both fullnode and solidity related interfaces.
Test Specification
Test conditions include:
- Is the interface
/wallet/listwitnessesin reverse order of votes? - Is the interface
/wallet/listrealtimewitnessin reverse order of votes? - Does the real-time interface support dynamic updates after a vote transaction?
- Is the paging conditions of the real-time interface reasonable and the handling of boundary conditions?
- Does walletsolidity API also support related real-time queries?
- Does the QPS of the real-time interface meet the requirements?
Scope Of Impact
This involves changes to the api.proto file, affecting related interfaces including HTTP and gRPC.
Implementation
Do you have ideas regarding the implementation of this feature?
Y
Are you willing to implement this feature?
Y
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
[-]Added a new API to query the real-time vote count of witness[/-][+]Add a new API to query the real-time vote count of witness[/+]SeriousCoding789 commentedon Jun 4, 2025
@317787106 Thank you for your valuable suggestion. Regarding
PaginatedMessage, could you clarify what the default page size is? Since vote counts may change immediately after each/wallet/listrealtimewitnessrequest, the witness ranking can also shift.Given that the number of Mainnet witnesses is limited to just a few hundred currently and increase slowly, would it make sense for
/wallet/listrealtimewitnessto return a static number of witnesses? For example, it could always return the top 500 witnesses sorted by vote count in descending order. This limit could be configurable, up to a maximum of 1000 or more. With this approach, each request would provide an accurate, real-time voting result without ambiguity. Witnesses outside the top 500 could still query their vote count by providing their witness address.317787106 commentedon Jun 4, 2025
@Sunny6889 There is no default value for proto
PaginatedMessage. The limit of PaginatedMessage maybe have a maxium, such as 200 or 1000.waynercheung commentedon Jun 4, 2025
@317787106 @Sunny6889 For this point of view, there is an another option, return all the witnesses as
listwitnesseswithoutPaginatedMessage:rpc ListRealtimeWitness (EmptyMessage) returns (WitnessList) { };317787106 commentedon Jun 4, 2025
@waynercheung Adding this PaginatedMessage can prevent too large results for request, such as GetPaginatedProposalList, GetPaginatedAssetIssueList. As witness's number may grow bigger in future.
waynercheung commentedon Jun 4, 2025
Yes, you are right, but the realtime witness data is mutable, so you can't ensure that when you fetch the data next time, the sequence will still be the same as what you fetched previously.
Let's consider a simple scenario: returning data ordered by alpha.
First, there are 5 witnesses: A, B, C, D, E. With page=0, limit=2, you get A, B.
Meanwhile, a new witness A1 is added, and the new order is A, A1, B, C, D, E.
When you continue fetching data using page=1, limit=2, you get B, C, missing A1.
Besides that, the user who want to use API
listrealtimewitnessis more familiar withlistwitnesses, and make these two APIs using the same parameter maybe a good option, right?yanghang8612 commentedon Jun 4, 2025
Perhaps we should add a
TIPfor this feature to discuss the interface design? We can discuss the specific implementation of the interface in thejava-tronrepository, such as whether to add a cache to store real-time SR vote counts or persist them to the database to avoid repeated calculations each time.After all, the
TIPclassification includesinterfacecategories. Refer this.waynercheung commentedon Jun 4, 2025
Additionally, another question: Which users would actually use this interface?
https://tronscan.org/#/sr/representatives already displays near-real-time witness rankings, and users can obtain data through this page.
Therefore, is it necessary to provide this interface again at the node level?
Furthermore, what about this interface's performance? Could it potentially affect node performance?
King31T commentedon Jun 4, 2025
refer Why should this feature exist?
317787106 commentedon Jun 4, 2025
@waynercheung The url https://tronscan.org/#/sr/representatives only show the vote of last epoch. Every request takes less than 20ms, that depends on the machine.
9 remaining items
lxcmyf commentedon Jun 5, 2025
You misunderstood me. What I meant was to use Prometheus to record metrics to achieve real-time voting for Witness.
SeriousCoding789 commentedon Jun 5, 2025
@lxcmyf Could you explain with more detail for 'use Prometheus to record metrics to achieve real-time voting for Witness'
yanghang8612 commentedon Jun 5, 2025
@Sunny6889
Unless the query rate for this interface is restricted to an extremely low level, such as once per second, there will still be a certain degree of attack risk.
Since activating an account on TRON requires extremely low consumption, malicious actors can bulk-generate a large number of addresses with 1 TRX and stake TRX, enabling them to perform vote manipulation during each maintenance period. This allows malicious actors to launch attacks during each maintenance period, significantly increasing the load on nodes when executing queries for this interface.
Should we also consider the cost of malicious actors launching attacks? Or should we disregard the cost of attacks and instead evaluate this attack vector purely from a technical perspective?
Perhaps we could conduct some tests under various scenarios involving the number of vote-changing accounts to provide a basis for future design decisions.
SeriousCoding789 commentedon Jun 6, 2025
@yanghang8612 These are excellent points. I agree there should be performance testing to analyze the correlation between computational costs and VotesStore size.
barbatos2011 commentedon Jun 12, 2025
This feature is great. If the performance is acceptable but not ideal, using the
rate.limiterin the config file is a good way to limit API requests.SeriousCoding789 commentedon Jun 30, 2025
@barbatos2011 @yanghang8612 As tested on both Nile and Mainnet network here is the testing report:
GetPaginatedNowWitnessList Performance Analysis
The TRON Mainnet currently has approximately 426 witnesses, with minimal growth due to substantial entry costs. The network processes fewer than 1,000 voting transactions per maintenance cycle, and the existing
/wallet/listwitnessesAPI demonstrates efficient performance with average response times under 15ms. To evaluate the new/wallet/getpaginatednowwitnesslistAPI, we will conduct comprehensive performance testing across both current production volumes and projected future scale scenarios.Algorithm Complexity & Performance Testing Ranges
Algorithm Complexity
The API logic time complexity is
O(wlogw + v), wherewis the number of witnesses andvis the number of voting records (unique voting accounts).wlogwis witness sorting complexity,vis voting record traversal complexity.Cost Analysis:
Witness Creation Cost:
Voting Record Creation Cost:
Account creation: 1 TRX + 200-300 bandwidth (~1.2 TRX total)
Voting transaction: ~0.2 TRX
Cost Projections:
Performance Testing Ranges
Considering computational complexity where performance overhead is proportional to voting records quantity, we designed the following test ranges:
Performance Testing Matrix:
Test Data Generation Methodology
Directly insert witness and vote records into LevelDB:
JVM Configuration & Memory Analysis
Official JVM Parameters
Memory Allocation
Using CMS collector with -XX:CMSInitiatingOccupancyFraction=70 triggers Full GC when Old Generation reaches 70% capacity. Mass object creation/expiration may cause frequent Young GCs, while excessive objec
LevelDB Off-Heap Memory
LevelDB internally operates with native memory allocation outside JVM heap management. When JVM GC activity remains low, LevelDB's native memory operations and data volume changes (insertions/deletions) can still significantly impact query performance through:
Storage Projections
Hardware Specifications
Testing Environment:
Performance Test Results
Nile Testnet Results
Test results were obtained after downloading a snapshot DB while the node was continuously syncing blocks. Since inserting witnesses would affect block validation and cause sync failures, only voting records were inserted. Nile has 416 witnesses, and based on test analysis, the performance impact between 416 and 1000 witnesses is negligible (<2ms). Each data volume tested with at least 50 requests.
MainNet Results
The test scenario is the same as the Nile network above, which is in continuous block synchronization. The Mainnet has 424 witnesses.
Key Findings
Performance Analysis Summary
Normal Operation (<10k records):
Critical Threshold (100k+ records):
Risk Mitigation:
rate.limiterin configuration fileBenson0224 commentedon Jul 25, 2025
Status Update: This issue has been scheduled for implementation in the next release, tentatively V4.8.1. The resolution plan is as follows
However, all talks about this issue will be welcome. Please continue the conversation here if you have relevant topics to contribute. Thanks!
At last, please follow V4.8.1 status at Issue #6342 and watch this issue (via the Subscribe button) to track progress if needed. We value your involvement in TRON's development!