Skip to content

Add a new API to query the real-time vote count of witness #6339

Description

@317787106

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:

  1. 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;

  2. 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

  1. For the existing interface /wallet/listwitnesses for 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.

  1. A new interface /wallet/listrealtimewitness is 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:

  1. Is the interface /wallet/listwitnesses in reverse order of votes?
  2. Is the interface /wallet/listrealtimewitness in reverse order of votes?
  3. Does the real-time interface support dynamic updates after a vote transaction?
  4. Is the paging conditions of the real-time interface reasonable and the handling of boundary conditions?
  5. Does walletsolidity API also support related real-time queries?
  6. 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

Activity

  1. changed the title [-]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[/+] on Jun 4, 2025
  2. SeriousCoding789 commented on Jun 4, 2025

    @SeriousCoding789
    Contributor

    @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/listrealtimewitness request, 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/listrealtimewitness to 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.

  3. moved this to To Do in java-tronon Jun 4, 2025
  4. 317787106 commented on Jun 4, 2025

    @317787106
    CollaboratorAuthor

    @Sunny6889 There is no default value for proto PaginatedMessage. The limit of PaginatedMessage maybe have a maxium, such as 200 or 1000.

  5. waynercheung commented on Jun 4, 2025

    @waynercheung
    Collaborator

    For example, it could always return the top 500 witnesses sorted by vote count in descending order.

    @317787106 @Sunny6889 For this point of view, there is an another option, return all the witnesses as listwitnesses without PaginatedMessage :

    rpc ListRealtimeWitness (EmptyMessage) returns (WitnessList) { };

  6. 317787106 commented on Jun 4, 2025

    @317787106
    CollaboratorAuthor

    @waynercheung Adding this PaginatedMessage can prevent too large results for request, such as GetPaginatedProposalList, GetPaginatedAssetIssueList. As witness's number may grow bigger in future.

  7. waynercheung commented on Jun 4, 2025

    @waynercheung
    Collaborator

    @waynercheung Adding this PaginatedMessage can prevent too large results for request, such as GetPaginatedProposalList, GetPaginatedAssetIssueList. As witness's number may grow bigger in future.

    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 listrealtimewitness is more familiar with listwitnesses, and make these two APIs using the same parameter maybe a good option, right?

  8. yanghang8612 commented on Jun 4, 2025

    @yanghang8612
    Collaborator

    Perhaps we should add a TIP for this feature to discuss the interface design? We can discuss the specific implementation of the interface in the java-tron repository, 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 TIP classification includes interface categories. Refer this.

  9. waynercheung commented on Jun 4, 2025

    @waynercheung
    Collaborator

    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?

  10. King31T commented on Jun 4, 2025

    @King31T

    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?

    refer Why should this feature exist?

  11. 317787106 commented on Jun 4, 2025

    @317787106
    CollaboratorAuthor

    @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.

  12. 9 remaining items

  13. lxcmyf commented on Jun 5, 2025

    @lxcmyf
    Collaborator

    @lxcmyf The java-tron do have metric logged for all transactions processed including transactions from block syncing or received from trx broadcasting. You could observe it from any FullNode. As observed from my personal FullNode, the TPS for VoteWitnessContract is really low, which means the VoteStore size is very limited. @317787106 mentioned above the execution cost is within 20ms.

    You misunderstood me. What I meant was to use Prometheus to record metrics to achieve real-time voting for Witness.

  14. SeriousCoding789 commented on Jun 5, 2025

    @SeriousCoding789
    Contributor

    @lxcmyf Could you explain with more detail for 'use Prometheus to record metrics to achieve real-time voting for Witness'

  15. yanghang8612 commented on Jun 5, 2025

    @yanghang8612
    Collaborator

    Given these considerations and the additional complexity that caching logic would introduce, the potential benefits may not justify the implementation effort and computational overhead. As an alternative solution, we can implement rate limiting in the configuration to prevent API abuse while maintaining the current implementation's simplicity and efficiency.

    @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.

  16. SeriousCoding789 commented on Jun 6, 2025

    @SeriousCoding789
    Contributor

    @yanghang8612 These are excellent points. I agree there should be performance testing to analyze the correlation between computational costs and VotesStore size.

  17. barbatos2011 commented on Jun 12, 2025

    @barbatos2011
    Contributor

    This feature is great. If the performance is acceptable but not ideal, using the rate.limiter in the config file is a good way to limit API requests.

  18. moved this from To Do to In Progress in java-tronon Jun 23, 2025
  19. SeriousCoding789 commented on Jun 30, 2025

    @SeriousCoding789
    Contributor

    @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/listwitnesses API demonstrates efficient performance with average response times under 15ms. To evaluate the new /wallet/getpaginatednowwitnesslist API, 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), where w is the number of witnesses and v is the number of voting records (unique voting accounts). wlogw is witness sorting complexity, v is voting record traversal complexity.

    Cost Analysis:

    Witness Creation Cost:

    • 9999 TRX per witness (~$2699 USD)
    • 1000 witnesses would cost $2.699M USD
    • Testing utilizes 1000 witnesses as a realistic growth projection, considering the prohibitive costs associated with DDoS attack scenarios.

    Voting Record Creation Cost:

    • Account creation: 1 TRX + 200-300 bandwidth (~1.2 TRX total)

    • Voting transaction: ~0.2 TRX

      Cost Projections:

      Records TRX Cost USD Equivalent
      100k 140k $37,800
      1M 1.4M $378,000
      10M 14M $3.78M

    Performance Testing Ranges

    Considering computational complexity where performance overhead is proportional to voting records quantity, we designed the following test ranges:

    Performance Testing Matrix:

    Scenario Voting Records Data Characteristics
    Baseline 1k Simulates current Mainnet workload
    Normal Load 10k 10x baseline transaction volume
    Medium Load 100k Stress test for mid-scale deployments
    High Load 1M Large-scale
    Extreme Load 10M Extrem case

    Test Data Generation Methodology

    Directly insert witness and vote records into LevelDB:

    // Database population code
    chainBaseManager.getWitnessStore().put(fakeWitnessAddress, fakeWitnessCapsule);
    chainBaseManager.getVotesStore().put(fakeOwnerAddress, fakeVotesCapsule);

    JVM Configuration & Memory Analysis

    Official JVM Parameters

    java -Xms9G -Xmx9G \
         -XX:ReservedCodeCacheSize=256m \
         -XX:MetaspaceSize=256m \
         -XX:MaxMetaspaceSize=512m \
         -XX:MaxDirectMemorySize=1G \
         -XX:+UseConcMarkSweepGC \
         -XX:NewRatio=2 \
         -XX:+UseCMSInitiatingOccupancyOnly \
         -XX:CMSInitiatingOccupancyFraction=70

    Memory Allocation

    • Young Generation : ≈3GB (NewRatio=2)
    • Old Generation : ≈6GB
    • Metaspace : 256MB-512MB
    • Direct Memory : 1GB (JVM direct buffer)
      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:

    • Compaction process overhead
    • Increased key lookup complexity, such as when there is large key deletion.
    • Page cache misses
    • Write amplification effects

    Storage Projections

    Object Type Avg Size Notes
    Witness Object 101 bytes
    VoteStore Entry 195 bytes (3 witnesses per vote avg)
    Metric/Category Baseline Scenario Normal Load Medium Load High Load Extreme Load Remarks
    Object Count 1k 10k 100k 1M 10M
    Fake Vote Cost $378 $3,780 $37,800 $378,000 $3.78M Based on 1 TRX = $0.27 USD
    Storage Growth ~128 KB ~1.28 MB ~14.8 MB ~148 MB ~1.48 GB LevelDB compression rate
    Heap Usage ~370KB ~3.7 MB ~37 MB ~370 MB ~3.7 GB 2.5x overhead (iterators)
    Young GC Added/Req 0 0 0-1 2-3 10+ STW 5-20ms per GC
    Full GC Risk/Req None None None Low High STW 200ms+ per GC

    Hardware Specifications

    Testing Environment:

    • Device: MacBook Pro
    • CPU: Apple M1 Max (8 performance cores + 2 efficiency cores)
    • Memory: 64GB Unified Memory

    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.

    Data Volume Avg Response Time CPU Usage Increase Young GC Added/Req Full GC Added /Req STW Time Added
    1k ~10ms [6-30ms] - ~0 0 -
    10k ~40ms - ~0 0 -
    100k ~175ms <10% ~0 0 <10ms
    1M ~2.3s 10-35% ~1 0 20-200ms
    10M ~28s 10-75% ~2 ~0.1 ~900 ms

    MainNet Results

    The test scenario is the same as the Nile network above, which is in continuous block synchronization. The Mainnet has 424 witnesses.

    Data Volume Avg Response Time CPU Usage Increase Young GC Added/Req Full GC Added /Req STW Time Added
    <1k ~12.3ms [7-30ms] - ~0 0 -
    10k ~38.3ms - ~0 0 -
    100k ~337.5ms [290-440ms] <10% ~0 0 -
    1M ~4.2s [3.7-4.7s] 5-20% 0-5 0 No significant
    10M ~46.6s 5-25% 0-15 0 ~200ms

    Key Findings

    • Response time exceeds 280ms at 100k records (recommended threshold: ≤200ms)
    • Significant GC pressure emerges at 1M+ records
    • Relateives stable CPU utilization due to single-threaded processing

    Performance Analysis Summary

    Normal Operation (<10k records):

    • API response <40ms [6~100ms]
    • Minimal system impact

    Critical Threshold (100k+ records):

    • Response time reaches above 290ms
    • Requires architectural optimization:
      • Implement Witness-keyed data structure
      • Avoid full VoteStore traversal
    • Traffic Projection:
      • Current Mainnet volume: 300-700 transactions/maintenance period
      • 15x traffic growth required to reach critical threshold
      • Low-priority optimization target under current traffic patterns

    Risk Mitigation:

    1. Configure rate.limiter in configuration file
    2. Disable API on:
      • High-traffic nodes
      • Witness nodes
    3. Establish dedicated API service nodes, like TronGrid to provide API services.
  20. moved this from In Progress to In Review in java-tronon Jul 1, 2025
  21. Benson0224 commented on Jul 25, 2025

    @Benson0224
    Collaborator

    Status Update: This issue has been scheduled for implementation in the next release, tentatively V4.8.1. The resolution plan is as follows

    • ✅ Added to development pipeline
    • ⏳ Will close automatically when core PRs land
    • 🔔 Maintain real-time status updates here

    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!

  22. moved this from In Review to Done in java-tronon Aug 28, 2025
  23. closed this as completedby moving to Done in java-tronon Aug 28, 2025
  24. linked a pull request that will close this issuefix(API): get now witness count #6451on Sep 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions