77import java .time .ZoneId ;
88import java .time .ZonedDateTime ;
99import java .util .ArrayList ;
10+ import java .util .List ;
1011import java .util .Map ;
1112import java .util .concurrent .atomic .AtomicInteger ;
1213import java .util .stream .Collectors ;
@@ -66,7 +67,7 @@ protected static void initParameter(CommonParameter parameter) {
6667 parameter .setMetricsPrometheusEnable (true );
6768 }
6869
69- protected void check (byte [] address ) throws Exception {
70+ protected void check (byte [] address , Map < ByteString , String > witnessAndAccount ) throws Exception {
7071 Double memoryBytes = CollectorRegistry .defaultRegistry .getSampleValue (
7172 "system_total_physical_memory_bytes" );
7273 Assert .assertNotNull (memoryBytes );
@@ -87,10 +88,42 @@ protected void check(byte[] address) throws Exception {
8788 "tron:block_empty_total" , new String [] {"miner" }, new String [] {minerBase58 });
8889
8990 Assert .assertNotNull (emptyBlock );
90- // The initial address is in the active witness list along with 2 randomly generated witnesses,
91- // so it produces blocks every 3 slots. Total empty blocks = 1 (first manual block) + blocks/3
92- // (from the loop) + 1 if blocks%3 != 0 (partial round)
93- Assert .assertEquals (emptyBlock .intValue (), 1 + blocks / 3 + (blocks % 3 != 0 ? 1 : 0 ));
91+ Assert .assertEquals (emptyBlock .intValue (), 1 );
92+
93+ // Check SR_REMOVE for initial address (removed when addTestWitnessAndAccount() is called)
94+ Double srRemoveCount = CollectorRegistry .defaultRegistry .getSampleValue (
95+ "tron:sr_set_change_total" ,
96+ new String [] {"action" , "witness" },
97+ new String [] {MetricLabels .Counter .SR_REMOVE , minerBase58 }
98+ );
99+ Assert .assertNotNull (srRemoveCount );
100+ Assert .assertEquals (1 , srRemoveCount .intValue ());
101+
102+ // Check SR_ADD and empty blocks for each new witness in witnessAndAccount (excluding initial address)
103+ ByteString addressByteString = ByteString .copyFrom (address );
104+ double totalNewWitnessEmptyBlocks = 0 ;
105+ for (ByteString witnessAddress : witnessAndAccount .keySet ()) {
106+ if (witnessAddress .equals (addressByteString )) {
107+ continue ; // Skip initial address
108+ }
109+ String witnessBase58 = StringUtil .encode58Check (witnessAddress .toByteArray ());
110+
111+ // Check SR_ADD
112+ Double srAddCount = CollectorRegistry .defaultRegistry .getSampleValue (
113+ "tron:sr_set_change_total" ,
114+ new String [] {"action" , "witness" },
115+ new String [] {MetricLabels .Counter .SR_ADD , witnessBase58 }
116+ );
117+ Assert .assertNotNull ("SR_ADD should be recorded for witness: " + witnessBase58 , srAddCount );
118+ Assert .assertEquals ("Each new witness should have 1 SR_ADD record" , 1 , srAddCount .intValue ());
119+
120+ // Collect empty blocks count
121+ Double witnessEmptyBlock = CollectorRegistry .defaultRegistry .getSampleValue (
122+ "tron:block_empty_total" , new String [] {"miner" }, new String [] {witnessBase58 });
123+ Assert .assertNotNull (witnessEmptyBlock );
124+ totalNewWitnessEmptyBlocks += witnessEmptyBlock ;
125+ }
126+ Assert .assertEquals (blocks , (int )totalNewWitnessEmptyBlocks );
94127
95128 Double errorLogs = CollectorRegistry .defaultRegistry .getSampleValue (
96129 "tron:error_info_total" , new String [] {"net" }, new String [] {MetricLabels .UNDEFINED });
@@ -142,10 +175,20 @@ public void testMetric() throws Exception {
142175
143176 Map <ByteString , String > witnessAndAccount = addTestWitnessAndAccount ();
144177 witnessAndAccount .put (ByteString .copyFrom (address ), key );
178+
179+ // Explicitly update WitnessScheduleStore to remove initial address, triggering SR_REMOVE metric
180+ List <ByteString > newActiveWitnesses = new ArrayList <>(witnessAndAccount .keySet ());
181+ newActiveWitnesses .remove (ByteString .copyFrom (address ));
182+ chainBaseManager .getWitnessScheduleStore ().saveActiveWitnesses (newActiveWitnesses );
183+
184+ // Update nextMaintenanceTime to trigger SR set change detection
185+ long nextMaintenanceTime = chainBaseManager .getDynamicPropertiesStore ().getNextMaintenanceTime ();
186+ chainBaseManager .getDynamicPropertiesStore ().updateNextMaintenanceTime (nextMaintenanceTime + 3600_000L );
187+
145188 for (int i = 0 ; i < blocks ; i ++) {
146189 generateBlock (witnessAndAccount );
147190 }
148- check (address );
191+ check (address , witnessAndAccount );
149192 }
150193
151194 private Map <ByteString , String > addTestWitnessAndAccount () {
0 commit comments