Skip to content

Commit ae4587c

Browse files
committed
Merge branch 'release_v4.7.2' into hotfix/stable_testcase
2 parents 4e81526 + 73b37b2 commit ae4587c

11 files changed

Lines changed: 212 additions & 18 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/Wallet.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,8 +3034,6 @@ public Transaction callConstantContract(TransactionCapsule trxCap,
30343034

30353035
TransactionResultCapsule ret = new TransactionResultCapsule();
30363036
builder.setEnergyUsed(result.getEnergyUsed());
3037-
builder.setBlockNumber(headBlockCapsule.getNum());
3038-
builder.setBlockHash(ByteString.copyFrom(headBlockCapsule.getBlockId().getBytes()));
30393037
builder.setEnergyPenalty(result.getEnergyPenaltyTotal());
30403038
builder.addConstantResult(ByteString.copyFrom(result.getHReturn()));
30413039
result.getLogInfoList().forEach(logInfo ->

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: 15 additions & 7 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
}
@@ -309,13 +315,15 @@ public void pushTransaction(TransactionCapsule trx) throws P2pException {
309315
}
310316

311317
public void validSignature(BlockCapsule block) throws P2pException {
318+
boolean flag;
312319
try {
313-
if (!block.validateSignature(dbManager.getDynamicPropertiesStore(),
314-
dbManager.getAccountStore())) {
315-
throw new P2pException(TypeEnum.BAD_BLOCK, "valid signature failed.");
316-
}
317-
} catch (ValidateSignatureException e) {
318-
throw new P2pException(TypeEnum.BAD_BLOCK, e);
320+
flag = block.validateSignature(dbManager.getDynamicPropertiesStore(),
321+
dbManager.getAccountStore());
322+
} catch (Exception e) {
323+
throw new P2pException(TypeEnum.BLOCK_SIGN_ERROR, e);
324+
}
325+
if (!flag) {
326+
throw new P2pException(TypeEnum.BLOCK_SIGN_ERROR, "valid signature failed.");
319327
}
320328
}
321329

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()) {
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package org.tron.common.backup;
2+
3+
import java.lang.reflect.Field;
4+
import java.net.InetSocketAddress;
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.concurrent.ScheduledExecutorService;
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
import org.tron.common.backup.message.KeepAliveMessage;
11+
import org.tron.common.backup.socket.UdpEvent;
12+
import org.tron.common.parameter.CommonParameter;
13+
import org.tron.core.Constant;
14+
import org.tron.core.config.args.Args;
15+
16+
public class BackupManagerTest {
17+
18+
@Test
19+
public void test() throws Exception {
20+
String[] a = new String[0];
21+
Args.setParam(a, Constant.TESTNET_CONF);
22+
CommonParameter parameter = CommonParameter.getInstance();
23+
parameter.setBackupPriority(8);
24+
List<String> members = new ArrayList<>();
25+
members.add("127.0.0.2");
26+
parameter.setBackupMembers(members);
27+
28+
BackupManager manager = new BackupManager();
29+
30+
Field field = manager.getClass().getDeclaredField("localIp");
31+
field.setAccessible(true);
32+
field.set(manager, "127.0.0.1");
33+
34+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.MASTER);
35+
36+
field = manager.getClass().getDeclaredField("executorService");
37+
field.setAccessible(true);
38+
ScheduledExecutorService executorService = (ScheduledExecutorService) field.get(manager);
39+
manager.init();
40+
executorService.shutdown();
41+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.INIT);
42+
43+
/* ip not in the members */
44+
manager.setStatus(BackupManager.BackupStatusEnum.INIT);
45+
KeepAliveMessage message = new KeepAliveMessage(false, 6);
46+
InetSocketAddress address = new InetSocketAddress("127.0.0.3", 1000);
47+
UdpEvent event = new UdpEvent(message, address);
48+
manager.handleEvent(event);
49+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.INIT);
50+
51+
/* ip not the member */
52+
address = new InetSocketAddress("127.0.0.3", 1000);
53+
message = new KeepAliveMessage(false, 6);
54+
event = new UdpEvent(message, address);
55+
manager.handleEvent(event);
56+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.INIT);
57+
58+
/* keepAliveMessage.getFlag() || peerPriority > priority */
59+
address = new InetSocketAddress("127.0.0.2", 1000);
60+
message = new KeepAliveMessage(false, 6);
61+
event = new UdpEvent(message, address);
62+
manager.handleEvent(event);
63+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.INIT);
64+
65+
/* keepAliveMessage.getFlag() || peerPriority > priority */
66+
message = new KeepAliveMessage(false, 10);
67+
event = new UdpEvent(message, address);
68+
manager.handleEvent(event);
69+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.SLAVER);
70+
71+
/* keepAliveMessage.getFlag() || peerPriority > priority */
72+
manager.setStatus(BackupManager.BackupStatusEnum.INIT);
73+
message = new KeepAliveMessage(true, 6);
74+
event = new UdpEvent(message, address);
75+
manager.handleEvent(event);
76+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.SLAVER);
77+
78+
manager.setStatus(BackupManager.BackupStatusEnum.MASTER);
79+
message = new KeepAliveMessage(false, 10);
80+
event = new UdpEvent(message, address);
81+
manager.handleEvent(event);
82+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.MASTER);
83+
84+
message = new KeepAliveMessage(true, 10);
85+
event = new UdpEvent(message, address);
86+
manager.handleEvent(event);
87+
Assert.assertEquals(manager.getStatus(), BackupManager.BackupStatusEnum.SLAVER);
88+
89+
}
90+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.tron.common.backup;
2+
3+
import static org.tron.common.backup.message.UdpMessageTypeEnum.BACKUP_KEEP_ALIVE;
4+
5+
import org.junit.Test;
6+
import org.testng.Assert;
7+
import org.tron.common.backup.message.KeepAliveMessage;
8+
import org.tron.protos.Discover;
9+
10+
public class KeepAliveMessageTest {
11+
12+
@Test
13+
public void test() throws Exception {
14+
KeepAliveMessage m1 = new KeepAliveMessage(true, 10);
15+
Assert.assertTrue(m1.getFlag());
16+
Assert.assertEquals(m1.getPriority(), 10);
17+
Assert.assertEquals(m1.getType(), BACKUP_KEEP_ALIVE);
18+
Assert.assertEquals(m1.getFrom(), null);
19+
Assert.assertEquals(m1.getTimestamp(), 0);
20+
Assert.assertEquals(m1.getData().length + 1, m1.getSendData().length);
21+
22+
23+
Discover.BackupMessage backupMessage = Discover.BackupMessage.newBuilder()
24+
.setFlag(true).setPriority(10).build();
25+
KeepAliveMessage m2 = new KeepAliveMessage(backupMessage.toByteArray());
26+
Assert.assertTrue(m2.getFlag());
27+
Assert.assertEquals(m2.getPriority(), 10);
28+
Assert.assertEquals(m2.getType(), BACKUP_KEEP_ALIVE);
29+
30+
Assert.assertEquals(m2.getMessageId().getBytes(), m1.getMessageId().getBytes());
31+
}
32+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.tron.common.backup;
2+
3+
import static org.tron.common.backup.message.UdpMessageTypeEnum.BACKUP_KEEP_ALIVE;
4+
import static org.tron.common.backup.message.UdpMessageTypeEnum.UNKNOWN;
5+
6+
import org.junit.Test;
7+
import org.testng.Assert;
8+
import org.tron.common.backup.message.UdpMessageTypeEnum;
9+
10+
public class UdpMessageTypeEnumTest {
11+
12+
@Test
13+
public void test() {
14+
UdpMessageTypeEnum type = UdpMessageTypeEnum.fromByte((byte) 5);
15+
Assert.assertEquals(type.getType(), (byte) 0x05);
16+
Assert.assertEquals(type, BACKUP_KEEP_ALIVE);
17+
18+
19+
type = UdpMessageTypeEnum.fromByte((byte) 1);
20+
Assert.assertEquals(type.getType(), (byte) 0xFF);
21+
Assert.assertEquals(type, UNKNOWN);
22+
}
23+
}

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;
@@ -399,6 +400,7 @@ public void pushBlockInvalidMerkelRoot() {
399400
Assert.assertTrue(false);
400401
} catch (BadBlockException e) {
401402
Assert.assertTrue(e instanceof BadBlockException);
403+
Assert.assertTrue(e.getType().equals(CALC_MERKLE_ROOT_FAILED));
402404
Assert.assertEquals("The merkle hash is not validated for "
403405
+ blockCapsule2.getNum(), e.getMessage());
404406
} catch (Exception e) {

0 commit comments

Comments
 (0)