2323import org .tron .core .net .peer .PeerManager ;
2424import org .tron .core .net .peer .TronState ;
2525import org .tron .core .net .service .sync .SyncService ;
26+ import org .tron .core .net .service .sync .UnparsedBlock ;
2627import org .tron .p2p .connection .Channel ;
2728import org .tron .protos .Protocol ;
2829
@@ -98,12 +99,22 @@ public void testProcessBlock() {
9899 ReflectUtils .setFieldValue (c1 , "inetSocketAddress" , inetSocketAddress );
99100 ReflectUtils .setFieldValue (c1 , "inetAddress" , inetSocketAddress .getAddress ());
100101 peer .setChannel (c1 );
101- service .processBlock (peer ,
102- new BlockMessage (new BlockCapsule (Protocol .Block .newBuilder ().build ())));
102+
103+ BlockCapsule blockCapsule = new BlockCapsule (Protocol .Block .newBuilder ().build ());
104+ BlockMessage blockMessage = new BlockMessage (blockCapsule );
105+ service .processBlock (peer , blockMessage );
106+
103107 boolean fetchFlag = (boolean ) ReflectUtils .getFieldObject (service , "fetchFlag" );
104108 boolean handleFlag = (boolean ) ReflectUtils .getFieldObject (service , "handleFlag" );
105109 Assert .assertTrue (fetchFlag );
106110 Assert .assertTrue (handleFlag );
111+
112+ Map <UnparsedBlock , PeerConnection > blockJustReceived =
113+ (Map <UnparsedBlock , PeerConnection >)
114+ ReflectUtils .getFieldObject (service , "blockJustReceived" );
115+ Assert .assertEquals (1 , blockJustReceived .size ());
116+ UnparsedBlock stored = blockJustReceived .keySet ().iterator ().next ();
117+ Assert .assertEquals (blockMessage .getBlockId (), stored .getBlockId ());
107118 }
108119
109120 @ Test
@@ -169,6 +180,46 @@ public void testStartFetchSyncBlock() throws Exception {
169180 peer .getSyncBlockRequested ().remove (blockId );
170181 method .invoke (service );
171182 Assert .assertTrue (peer .getSyncBlockRequested ().get (blockId ) == null );
183+
184+ // reset maxRequestedBlockNum to 0
185+ Field maxRequestedBlockNumField = service .getClass ().getDeclaredField ("maxRequestedBlockNum" );
186+ maxRequestedBlockNumField .setAccessible (true );
187+ maxRequestedBlockNumField .set (service , 0L );
188+
189+ Map <UnparsedBlock , PeerConnection > blockWaitToProcess =
190+ (Map <UnparsedBlock , PeerConnection >)
191+ ReflectUtils .getFieldObject (service , "blockWaitToProcess" );
192+
193+ // target block has num=1, above maxRequestedBlockNum=0 so it can be throttled
194+ BlockCapsule .BlockId highBlockId = new BlockCapsule .BlockId (Sha256Hash .ZERO_HASH , 1 );
195+ peer .getSyncBlockToFetch ().clear ();
196+ peer .getSyncBlockToFetch ().add (highBlockId );
197+ peer .getSyncBlockRequested ().clear ();
198+ requestBlockIds .invalidateAll ();
199+
200+ // fill blockWaitToProcess to reach maxPendingBlockSize (default 500)
201+ int maxPendingBlockSize = (int ) ReflectUtils .getFieldObject (service , "maxPendingBlockSize" );
202+ for (int i = 0 ; i < maxPendingBlockSize ; i ++) {
203+ BlockCapsule .BlockId fillId = new BlockCapsule .BlockId (Sha256Hash .ZERO_HASH , 10000 + i );
204+ blockWaitToProcess .put (new UnparsedBlock (fillId , new byte [0 ]), peer );
205+ }
206+ method .invoke (service );
207+ // highBlockId must NOT be requested: remainNum <= 0 and num > maxRequestedBlockNum
208+ Assert .assertNull (peer .getSyncBlockRequested ().get (highBlockId ));
209+
210+ // Symmetric retry-exemption case: budget still saturated, but the target block's num
211+ // is below maxRequestedBlockNum, so it must still be requested (deadlock-avoidance
212+ // retry path — guards an explicit invariant of the throttling design).
213+ maxRequestedBlockNumField .set (service , 100L );
214+ BlockCapsule .BlockId retryBlockId = new BlockCapsule .BlockId (Sha256Hash .ZERO_HASH , 50 );
215+ peer .getSyncBlockToFetch ().clear ();
216+ peer .getSyncBlockToFetch ().add (retryBlockId );
217+ peer .getSyncBlockRequested ().clear ();
218+ requestBlockIds .invalidateAll ();
219+ method .invoke (service );
220+ // retryBlockId MUST be requested: remainNum <= 0 but num=50 <= maxRequestedBlockNum=100
221+ Assert .assertNotNull (peer .getSyncBlockRequested ().get (retryBlockId ));
222+ blockWaitToProcess .clear ();
172223 }
173224
174225 @ Test
@@ -181,39 +232,34 @@ public void testHandleSyncBlock() throws Exception {
181232 Method method = service .getClass ().getDeclaredMethod ("handleSyncBlock" );
182233 method .setAccessible (true );
183234
184- Map <BlockMessage , PeerConnection > blockJustReceived =
185- (Map <BlockMessage , PeerConnection >)
235+ Map <UnparsedBlock , PeerConnection > blockJustReceived =
236+ (Map <UnparsedBlock , PeerConnection >)
186237 ReflectUtils .getFieldObject (service , "blockJustReceived" );
187- Protocol . BlockHeader . raw . Builder blockHeaderRawBuild = Protocol . BlockHeader . raw . newBuilder ();
188- Protocol .BlockHeader .raw blockHeaderRaw = blockHeaderRawBuild
238+
239+ Protocol .BlockHeader .raw blockHeaderRaw = Protocol . BlockHeader . raw . newBuilder ()
189240 .setNumber (100000 )
190241 .build ();
191-
192- // block header
193- Protocol .BlockHeader .Builder blockHeaderBuild = Protocol .BlockHeader .newBuilder ();
194- Protocol .BlockHeader blockHeader = blockHeaderBuild .setRawData (blockHeaderRaw ).build ();
195-
196- BlockCapsule blockCapsule = new BlockCapsule (Protocol .Block .newBuilder ()
197- .setBlockHeader (blockHeader ).build ());
198-
242+ Protocol .BlockHeader blockHeader = Protocol .BlockHeader .newBuilder ()
243+ .setRawData (blockHeaderRaw ).build ();
244+ BlockCapsule blockCapsule = new BlockCapsule (
245+ Protocol .Block .newBuilder ().setBlockHeader (blockHeader ).build ());
199246 BlockCapsule .BlockId blockId = blockCapsule .getBlockId ();
200247
201-
202248 InetSocketAddress a1 = new InetSocketAddress ("127.0.0.1" , 10001 );
203249 Channel c1 = mock (Channel .class );
204250 Mockito .when (c1 .getInetSocketAddress ()).thenReturn (a1 );
205251 Mockito .when (c1 .getInetAddress ()).thenReturn (a1 .getAddress ());
206252 PeerManager .add (ctx , c1 );
207253 peer = PeerManager .getPeers ().get (0 );
208254
209- blockJustReceived .put (new BlockMessage (blockCapsule ), peer );
255+ UnparsedBlock unparsedBlock = new UnparsedBlock (blockId , blockCapsule .getData ());
256+ blockJustReceived .put (unparsedBlock , peer );
210257
211258 peer .getSyncBlockToFetch ().add (blockId );
212259
213260 Cache <BlockCapsule .BlockId , PeerConnection > requestBlockIds =
214- (Cache <BlockCapsule .BlockId , PeerConnection >)
215- ReflectUtils .getFieldObject (service , "requestBlockIds" );
216-
261+ (Cache <BlockCapsule .BlockId , PeerConnection >)
262+ ReflectUtils .getFieldObject (service , "requestBlockIds" );
217263 requestBlockIds .put (blockId , peer );
218264
219265 method .invoke (service );
0 commit comments