Skip to content

Commit 8c57f0b

Browse files
authored
fix(net): map BLOCK_MERKLE_INVALID to BAD_BLOCK disconnect reason (#6791)
- P2pEventHandlerImpl.processException's switch did not include the BLOCK_MERKLE_ERROR type introduced by PR #6716. The new type fell through to the default branch, so peers whose blocks failed merkle root validation were disconnected with ReasonCode.UNKNOWN instead of BAD_BLOCK, missing the bad-peer ban window in PeerConnection.processDisconnect. - Add the case alongside BAD_BLOCK and BLOCK_SIGN_INVALID so the disconnect reason is reported as BAD_BLOCK end-to-end. - Rename the two enum constants for naming consistency: BLOCK_SIGN_ERROR -> BLOCK_SIGN_INVALID, BLOCK_MERKLE_ERROR -> BLOCK_MERKLE_INVALID, and reword their descriptions to 'sign failed' / 'merkle failed' to match the imperative style used by the other nearby enum entries. All call sites updated. - Add two regression tests in P2pEventHandlerImplTest: one pins BLOCK_MERKLE_INVALID -> BAD_BLOCK (the actual fix); the other pins BLOCK_SIGN_INVALID -> BAD_BLOCK so a future switch refactor cannot silently drop either back to UNKNOWN.
1 parent 260585c commit 8c57f0b

6 files changed

Lines changed: 63 additions & 10 deletions

File tree

common/src/main/java/org/tron/core/exception/P2pException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public enum TypeEnum {
5050
TRX_EXE_FAILED(12, "trx exe failed"),
5151
DB_ITEM_NOT_FOUND(13, "DB item not found"),
5252
PROTOBUF_ERROR(14, "protobuf inconsistent"),
53-
BLOCK_SIGN_ERROR(15, "block sign error"),
54-
BLOCK_MERKLE_ERROR(16, "block merkle error"),
53+
BLOCK_SIGN_INVALID(15, "block sign invalid"),
54+
BLOCK_MERKLE_INVALID(16, "block merkle invalid"),
5555
RATE_LIMIT_EXCEEDED(17, "rate limit exceeded"),
5656

5757
DEFAULT(100, "default exception");

framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ private void processException(PeerConnection peer, TronMessage msg, Exception ex
272272
code = Protocol.ReasonCode.BAD_TX;
273273
break;
274274
case BAD_BLOCK:
275-
case BLOCK_SIGN_ERROR:
275+
case BLOCK_SIGN_INVALID:
276+
case BLOCK_MERKLE_INVALID:
276277
code = Protocol.ReasonCode.BAD_BLOCK;
277278
break;
278279
case NO_SUCH_MESSAGE:

framework/src/main/java/org/tron/core/net/TronNetDelegate.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ public void processBlock(BlockCapsule block, boolean isSync) throws P2pException
312312
logger.error("Process block failed, {}, reason: {}", blockId.getString(), e.getMessage());
313313
if (e instanceof BadBlockException
314314
&& ((BadBlockException) e).getType().equals(CALC_MERKLE_ROOT_FAILED)) {
315-
throw new P2pException(TypeEnum.BLOCK_MERKLE_ERROR, e);
315+
throw new P2pException(TypeEnum.BLOCK_MERKLE_INVALID, e);
316316
} else {
317317
throw new P2pException(TypeEnum.BAD_BLOCK, e);
318318
}
@@ -347,10 +347,10 @@ public void validSignature(BlockCapsule block) throws P2pException {
347347
flag = block.validateSignature(dbManager.getDynamicPropertiesStore(),
348348
dbManager.getAccountStore());
349349
} catch (Exception e) {
350-
throw new P2pException(TypeEnum.BLOCK_SIGN_ERROR, e);
350+
throw new P2pException(TypeEnum.BLOCK_SIGN_INVALID, e);
351351
}
352352
if (!flag) {
353-
throw new P2pException(TypeEnum.BLOCK_SIGN_ERROR, "valid signature failed.");
353+
throw new P2pException(TypeEnum.BLOCK_SIGN_INVALID, "valid signature failed.");
354354
}
355355
}
356356

@@ -363,7 +363,7 @@ public boolean validBlock(BlockCapsule block) throws P2pException {
363363
try {
364364
block.validateMerkleRoot();
365365
} catch (BadBlockException e) {
366-
throw new P2pException(TypeEnum.BLOCK_MERKLE_ERROR, e.getMessage());
366+
throw new P2pException(TypeEnum.BLOCK_MERKLE_INVALID, e.getMessage());
367367
}
368368
validSignature(block);
369369
return witnessScheduleStore.getActiveWitnesses().contains(block.getWitnessAddress());

framework/src/main/java/org/tron/core/net/service/sync/SyncService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ private void processSyncBlock(BlockCapsule block, PeerConnection peerConnection)
342342
} catch (P2pException p2pException) {
343343
logger.error("Process sync block {} failed, type: {}",
344344
blockId.getString(), p2pException.getType());
345-
attackFlag = p2pException.getType().equals(TypeEnum.BLOCK_SIGN_ERROR)
346-
|| p2pException.getType().equals(TypeEnum.BLOCK_MERKLE_ERROR);
345+
attackFlag = p2pException.getType().equals(TypeEnum.BLOCK_SIGN_INVALID)
346+
|| p2pException.getType().equals(TypeEnum.BLOCK_MERKLE_INVALID);
347347
flag = false;
348348
} catch (Exception e) {
349349
logger.error("Process sync block {} failed", blockId.getString(), e);

framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.tron.core.net;
22

33
import static org.mockito.Mockito.mock;
4+
import static org.mockito.Mockito.verify;
45

56
import java.lang.reflect.Method;
7+
import java.net.InetSocketAddress;
68
import java.util.ArrayList;
79
import java.util.List;
810
import org.junit.Assert;
@@ -14,6 +16,7 @@
1416
import org.tron.common.parameter.CommonParameter;
1517
import org.tron.common.utils.Sha256Hash;
1618
import org.tron.core.config.args.Args;
19+
import org.tron.core.exception.P2pException;
1720
import org.tron.core.net.message.TronMessage;
1821
import org.tron.core.net.message.adv.FetchInvDataMessage;
1922
import org.tron.core.net.message.adv.InventoryMessage;
@@ -223,4 +226,53 @@ public void testUpdateLastInteractiveTime() throws Exception {
223226
method.invoke(p2pEventHandler, peer, message);
224227
Assert.assertTrue(peer.getLastInteractiveTime() >= t1);
225228
}
229+
230+
/**
231+
* Regression for PR #6716: validateMerkleRoot introduced
232+
* P2pException.TypeEnum.BLOCK_MERKLE_INVALID, but processException's switch
233+
* did not include the new type, so the peer was disconnected with
234+
* ReasonCode.UNKNOWN instead of BAD_BLOCK. This test pins that
235+
* BLOCK_MERKLE_INVALID is mapped to BAD_BLOCK (and gets the bad-peer ban
236+
* window via PeerConnection.processDisconnect).
237+
*/
238+
@Test
239+
public void testProcessExceptionMapsBlockMerkleErrorToBadBlock() throws Exception {
240+
P2pEventHandlerImpl handler = new P2pEventHandlerImpl();
241+
PeerConnection peer = mock(PeerConnection.class);
242+
Mockito.when(peer.getInetSocketAddress())
243+
.thenReturn(new InetSocketAddress("127.0.0.1", 18888));
244+
245+
P2pException ex = new P2pException(
246+
P2pException.TypeEnum.BLOCK_MERKLE_INVALID, "merkle mismatch");
247+
248+
Method method = handler.getClass().getDeclaredMethod("processException",
249+
PeerConnection.class, TronMessage.class, Exception.class);
250+
method.setAccessible(true);
251+
method.invoke(handler, peer, null, ex);
252+
253+
verify(peer).disconnect(Protocol.ReasonCode.BAD_BLOCK);
254+
}
255+
256+
/**
257+
* Companion sanity check: BLOCK_SIGN_INVALID already mapped correctly
258+
* before this fix; pin it so future refactors do not silently drop it
259+
* (or BLOCK_MERKLE_INVALID) back to UNKNOWN.
260+
*/
261+
@Test
262+
public void testProcessExceptionMapsBlockSignErrorToBadBlock() throws Exception {
263+
P2pEventHandlerImpl handler = new P2pEventHandlerImpl();
264+
PeerConnection peer = mock(PeerConnection.class);
265+
Mockito.when(peer.getInetSocketAddress())
266+
.thenReturn(new InetSocketAddress("127.0.0.1", 18888));
267+
268+
P2pException ex = new P2pException(
269+
P2pException.TypeEnum.BLOCK_SIGN_INVALID, "bad signature");
270+
271+
Method method = handler.getClass().getDeclaredMethod("processException",
272+
PeerConnection.class, TronMessage.class, Exception.class);
273+
method.setAccessible(true);
274+
method.invoke(handler, peer, null, ex);
275+
276+
verify(peer).disconnect(Protocol.ReasonCode.BAD_BLOCK);
277+
}
226278
}

framework/src/test/java/org/tron/core/net/TronNetDelegateTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public void testValidBlockMerkleRoot() throws Exception {
169169
tronNetDelegate.validBlock(tampered);
170170
Assert.fail("Expected P2pException for tampered merkle root");
171171
} catch (P2pException e) {
172-
Assert.assertEquals(TypeEnum.BLOCK_MERKLE_ERROR, e.getType());
172+
Assert.assertEquals(TypeEnum.BLOCK_MERKLE_INVALID, e.getType());
173173
}
174174
}
175175
}

0 commit comments

Comments
 (0)