Skip to content

Commit 54c05e5

Browse files
authored
Merge pull request #5130 from wubin01/sync_block_prco
feat(net): optimize sync block processing logic
2 parents 4b3aeb5 + ab6a65e commit 54c05e5

6 files changed

Lines changed: 61 additions & 10 deletions

File tree

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,37 @@
22

33
public class BadBlockException extends TronException {
44

5+
private TypeEnum type = TypeEnum.DEFAULT;
6+
57
public BadBlockException() {
68
super();
79
}
810

911
public BadBlockException(String message) {
1012
super(message);
1113
}
14+
15+
public BadBlockException(TypeEnum type, String message) {
16+
super(message);
17+
this.type = type;
18+
}
19+
20+
public TypeEnum getType() {
21+
return type;
22+
}
23+
24+
public enum TypeEnum {
25+
CALC_MERKLE_ROOT_FAILED(1),
26+
DEFAULT(100);
27+
28+
private Integer value;
29+
30+
TypeEnum(Integer value) {
31+
this.value = value;
32+
}
33+
34+
public Integer getValue() {
35+
return value;
36+
}
37+
}
1238
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +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"),
5355

5456
DEFAULT(100, "default exception");
5557

framework/src/main/java/org/tron/core/db/Manager.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.tron.core.db;
22

33
import static org.tron.common.utils.Commons.adjustBalance;
4+
import static org.tron.core.exception.BadBlockException.TypeEnum.CALC_MERKLE_ROOT_FAILED;
45
import static org.tron.protos.Protocol.Transaction.Contract.ContractType.TransferContract;
56
import static org.tron.protos.Protocol.Transaction.Result.contractResult.SUCCESS;
67

@@ -1213,8 +1214,8 @@ public void pushBlock(final BlockCapsule block)
12131214
if (!block.calcMerkleRoot().equals(block.getMerkleRoot())) {
12141215
logger.warn("Num: {}, the merkle root doesn't match, expect is {} , actual is {}.",
12151216
block.getNum(), block.getMerkleRoot(), block.calcMerkleRoot());
1216-
throw new BadBlockException(String.format("The merkle hash is not validated for %d",
1217-
block.getNum()));
1217+
throw new BadBlockException(CALC_MERKLE_ROOT_FAILED,
1218+
String.format("The merkle hash is not validated for %d", block.getNum()));
12181219
}
12191220
consensus.receiveBlock(block);
12201221
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.tron.core.net;
22

33
import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL;
4+
import static org.tron.core.exception.BadBlockException.TypeEnum.CALC_MERKLE_ROOT_FAILED;
45

56
import com.google.common.cache.Cache;
67
import com.google.common.cache.CacheBuilder;
@@ -282,7 +283,12 @@ public void processBlock(BlockCapsule block, boolean isSync) throws P2pException
282283
| EventBloomException e) {
283284
metricsService.failProcessBlock(block.getNum(), e.getMessage());
284285
logger.error("Process block failed, {}, reason: {}", blockId.getString(), e.getMessage());
285-
throw new P2pException(TypeEnum.BAD_BLOCK, e);
286+
if (e instanceof BadBlockException
287+
&& ((BadBlockException) e).getType().equals(CALC_MERKLE_ROOT_FAILED)) {
288+
throw new P2pException(TypeEnum.BLOCK_MERKLE_ERROR, e);
289+
} else {
290+
throw new P2pException(TypeEnum.BAD_BLOCK, e);
291+
}
286292
}
287293
}
288294
}
@@ -312,10 +318,10 @@ public void validSignature(BlockCapsule block) throws P2pException {
312318
try {
313319
if (!block.validateSignature(dbManager.getDynamicPropertiesStore(),
314320
dbManager.getAccountStore())) {
315-
throw new P2pException(TypeEnum.BAD_BLOCK, "valid signature failed.");
321+
throw new P2pException(TypeEnum.BLOCK_SIGN_ERROR, "valid signature failed.");
316322
}
317323
} catch (ValidateSignatureException e) {
318-
throw new P2pException(TypeEnum.BAD_BLOCK, e);
324+
throw new P2pException(TypeEnum.BLOCK_SIGN_ERROR, e);
319325
}
320326
}
321327

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

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.tron.core.capsule.BlockCapsule.BlockId;
2424
import org.tron.core.config.Parameter.NetConstants;
2525
import org.tron.core.config.args.Args;
26+
import org.tron.core.exception.BadBlockException;
2627
import org.tron.core.exception.P2pException;
2728
import org.tron.core.exception.P2pException.TypeEnum;
2829
import org.tron.core.net.TronNetDelegate;
@@ -263,33 +264,46 @@ private synchronized void handleSyncBlock() {
263264
tronNetDelegate.getActivePeer().stream()
264265
.filter(peer -> msg.getBlockId().equals(peer.getSyncBlockToFetch().peek()))
265266
.forEach(peer -> {
266-
peer.getSyncBlockToFetch().pop();
267-
peer.getSyncBlockInProcess().add(msg.getBlockId());
268267
isFound[0] = true;
269268
});
270269
if (isFound[0]) {
271270
blockWaitToProcess.remove(msg);
272271
isProcessed[0] = true;
273-
processSyncBlock(msg.getBlockCapsule());
272+
processSyncBlock(msg.getBlockCapsule(), peerConnection);
274273
}
275274
}
276275
});
277276
}
278277
}
279278

280-
private void processSyncBlock(BlockCapsule block) {
279+
private void processSyncBlock(BlockCapsule block, PeerConnection peerConnection) {
281280
boolean flag = true;
281+
boolean attackFlag = false;
282282
BlockId blockId = block.getBlockId();
283283
try {
284284
tronNetDelegate.validSignature(block);
285285
tronNetDelegate.processBlock(block, true);
286286
pbftDataSyncHandler.processPBFTCommitData(block);
287+
} catch (P2pException p2pException) {
288+
logger.error("Process sync block {} failed, type: {}",
289+
blockId.getString(), p2pException.getType());
290+
attackFlag = p2pException.getType().equals(TypeEnum.BLOCK_SIGN_ERROR)
291+
|| p2pException.getType().equals(TypeEnum.BLOCK_MERKLE_ERROR);
292+
flag = false;
287293
} catch (Exception e) {
288294
logger.error("Process sync block {} failed", blockId.getString(), e);
289295
flag = false;
290296
}
297+
298+
if (attackFlag) {
299+
invalid(blockId, peerConnection);
300+
peerConnection.disconnect(ReasonCode.BAD_BLOCK);
301+
return;
302+
}
303+
291304
for (PeerConnection peer : tronNetDelegate.getActivePeer()) {
292-
if (peer.getSyncBlockInProcess().remove(blockId)) {
305+
if (blockId.equals(peer.getSyncBlockToFetch().peek())) {
306+
peer.getSyncBlockToFetch().pop();
293307
if (flag) {
294308
peer.setBlockBothHave(blockId);
295309
if (peer.getSyncBlockToFetch().isEmpty() && peer.isFetchAble()) {

framework/src/test/java/org/tron/core/db/ManagerTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static org.tron.common.utils.Commons.adjustBalance;
55
import static org.tron.common.utils.Commons.adjustTotalShieldedPoolValue;
66
import static org.tron.common.utils.Commons.getExchangeStoreFinal;
7+
import static org.tron.core.exception.BadBlockException.TypeEnum.CALC_MERKLE_ROOT_FAILED;
78

89
import com.google.common.collect.Maps;
910
import com.google.protobuf.ByteString;
@@ -392,6 +393,7 @@ public void pushBlockInvalidMerkelRoot() {
392393
Assert.assertTrue(false);
393394
} catch (BadBlockException e) {
394395
Assert.assertTrue(e instanceof BadBlockException);
396+
Assert.assertTrue(e.getType().equals(CALC_MERKLE_ROOT_FAILED));
395397
Assert.assertEquals("The merkle hash is not validated for "
396398
+ blockCapsule2.getNum(), e.getMessage());
397399
} catch (Exception e) {

0 commit comments

Comments
 (0)