Skip to content

Commit 0d48db4

Browse files
committed
feat(net): stop broadcasting transactions when the block cannot be solidified
1 parent 4557c72 commit 0d48db4

File tree

10 files changed

+126
-2
lines changed

10 files changed

+126
-2
lines changed

common/src/main/java/org/tron/common/parameter/CommonParameter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,14 @@ public class CommonParameter {
651651
@Setter
652652
public long allowCancelAllUnfreezeV2;
653653

654+
@Getter
655+
@Setter
656+
public boolean unsolidifiedBlockCheck;
657+
658+
@Getter
659+
@Setter
660+
public int maxUnsolidifiedBlocks;
661+
654662
private static double calcMaxTimeRatio() {
655663
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
656664
return 5.0;

common/src/main/java/org/tron/core/Constant.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,4 +371,8 @@ public class Constant {
371371
public static final String DYNAMIC_CONFIG_CHECK_INTERVAL = "node.dynamicConfig.checkInterval";
372372

373373
public static final String COMMITTEE_ALLOW_TVM_SHANGHAI = "committee.allowTvmShangHai";
374+
375+
public static final String UNSOLIDIFIED_BLOCK_CHECK = "node.unsolidifiedBlockCheck";
376+
377+
public static final String MAX_UNSOLIDIFIED_BLOCKS = "node.maxUnsolidifiedBlocks";
374378
}

framework/src/main/java/org/tron/core/Wallet.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,13 @@ public GrpcAPI.Return broadcastTransaction(Transaction signedTransaction) {
520520
}
521521
}
522522

523+
if (tronNetDelegate.unsolidifiedBlockCheck()) {
524+
logger.warn("Broadcast transaction {} has failed, block unsolidified.", txID);
525+
return builder.setResult(false).setCode(response_code.BLOCK_UNSOLIDIFIED)
526+
.setMessage(ByteString.copyFromUtf8("Bock unsolidified."))
527+
.build();
528+
}
529+
523530
if (dbManager.isTooManyPending()) {
524531
logger.warn("Broadcast transaction {} has failed, too many pending.", txID);
525532
return builder.setResult(false).setCode(response_code.SERVER_BUSY)

framework/src/main/java/org/tron/core/config/args/Args.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ public static void clearParam() {
230230
PARAMETER.dynamicConfigEnable = false;
231231
PARAMETER.dynamicConfigCheckInterval = 600;
232232
PARAMETER.allowTvmShangHai = 0;
233+
PARAMETER.unsolidifiedBlockCheck = true;
234+
PARAMETER.maxUnsolidifiedBlocks = 1000;
233235
}
234236

235237
/**
@@ -1178,6 +1180,14 @@ public static void setParam(final String[] args, final String confFileName) {
11781180
config.hasPath(Constant.COMMITTEE_ALLOW_TVM_SHANGHAI) ? config
11791181
.getInt(Constant.COMMITTEE_ALLOW_TVM_SHANGHAI) : 0;
11801182

1183+
PARAMETER.unsolidifiedBlockCheck =
1184+
!config.hasPath(Constant.UNSOLIDIFIED_BLOCK_CHECK)
1185+
|| config.getBoolean(Constant.UNSOLIDIFIED_BLOCK_CHECK);
1186+
1187+
PARAMETER.maxUnsolidifiedBlocks =
1188+
config.hasPath(Constant.MAX_UNSOLIDIFIED_BLOCKS) ? config
1189+
.getInt(Constant.MAX_UNSOLIDIFIED_BLOCKS) : 1000;
1190+
11811191
logConfig();
11821192
}
11831193

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.tron.core.capsule.BlockCapsule.BlockId;
3030
import org.tron.core.capsule.PbftSignCapsule;
3131
import org.tron.core.capsule.TransactionCapsule;
32+
import org.tron.core.config.args.Args;
3233
import org.tron.core.db.Manager;
3334
import org.tron.core.exception.AccountResourceInsufficientException;
3435
import org.tron.core.exception.BadBlockException;
@@ -98,6 +99,11 @@ public class TronNetDelegate {
9899
@Setter
99100
private volatile boolean exit = true;
100101

102+
private int maxUnsolidifiedBlocks = Args.getInstance().getMaxUnsolidifiedBlocks();
103+
104+
private boolean unsolidifiedBlockCheck
105+
= Args.getInstance().isUnsolidifiedBlockCheck();
106+
101107
private Cache<BlockId, Long> freshBlockId = CacheBuilder.newBuilder()
102108
.maximumSize(blockIdCacheSize).expireAfterWrite(1, TimeUnit.HOURS)
103109
.recordStats().build();
@@ -365,4 +371,13 @@ public long getMaintenanceTimeInterval() {
365371
return chainBaseManager.getDynamicPropertiesStore().getMaintenanceTimeInterval();
366372
}
367373

374+
public boolean unsolidifiedBlockCheck() {
375+
if (!unsolidifiedBlockCheck) {
376+
return false;
377+
}
378+
long headNum = chainBaseManager.getHeadBlockNum();
379+
long solidNum = chainBaseManager.getSolidBlockId().getNum();
380+
return headNum - solidNum >= maxUnsolidifiedBlocks;
381+
}
382+
368383
}

framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) {
4343
}
4444

4545
private boolean check(PeerConnection peer, InventoryMessage inventoryMessage) {
46+
4647
InventoryType type = inventoryMessage.getInventoryType();
4748
int size = inventoryMessage.getHashList().size();
4849

@@ -52,6 +53,12 @@ private boolean check(PeerConnection peer, InventoryMessage inventoryMessage) {
5253
return false;
5354
}
5455

56+
if (type.equals(InventoryType.TRX) && tronNetDelegate.unsolidifiedBlockCheck()) {
57+
logger.warn("Drop inv: {} size: {} from Peer {}, block unsolidified",
58+
type, size, peer.getInetAddress());
59+
return false;
60+
}
61+
5562
if (type.equals(InventoryType.TRX) && transactionsMsgHandler.isBusy()) {
5663
logger.warn("Drop inv: {} size: {} from Peer {}, transactionsMsgHandler is busy",
5764
type, size, peer.getInetAddress());

framework/src/test/java/org/tron/core/config/args/ArgsTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public void get() {
102102
Assert.assertEquals(0, parameter.getActiveNodes().size());
103103
Assert.assertEquals(30, parameter.getMaxConnections());
104104
Assert.assertEquals(43, parameter.getNodeP2pVersion());
105+
Assert.assertEquals(1000, parameter.getMaxUnsolidifiedBlocks());
106+
Assert.assertEquals(true, parameter.isUnsolidifiedBlockCheck());
105107
//Assert.assertEquals(30, args.getSyncNodeCount());
106108

107109
// gRPC network configs checking
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.tron.core.net;
2+
3+
import static org.mockito.Mockito.mock;
4+
5+
import java.lang.reflect.Field;
6+
import org.junit.Assert;
7+
import org.junit.Test;
8+
import org.mockito.Mockito;
9+
import org.tron.common.parameter.CommonParameter;
10+
import org.tron.common.utils.Sha256Hash;
11+
import org.tron.core.ChainBaseManager;
12+
import org.tron.core.Constant;
13+
import org.tron.core.capsule.BlockCapsule;
14+
import org.tron.core.config.args.Args;
15+
16+
public class TronNetDelegateTest {
17+
18+
@Test
19+
public void test() throws Exception {
20+
Args.setParam(new String[] {"-w"}, Constant.TEST_CONF);
21+
CommonParameter parameter = Args.getInstance();
22+
Args.logConfig();
23+
24+
BlockCapsule.BlockId blockId = new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 10000L);
25+
26+
TronNetDelegate tronNetDelegate = new TronNetDelegate();
27+
28+
ChainBaseManager chainBaseManager = mock(ChainBaseManager.class);
29+
Mockito.when(chainBaseManager.getHeadBlockNum()).thenReturn(10000L);
30+
Mockito.when(chainBaseManager.getSolidBlockId()).thenReturn(blockId);
31+
32+
Field field = tronNetDelegate.getClass().getDeclaredField("chainBaseManager");
33+
field.setAccessible(true);
34+
field.set(tronNetDelegate, chainBaseManager);
35+
36+
Assert.assertTrue(!tronNetDelegate.unsolidifiedBlockCheck());
37+
38+
blockId = new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 1L);
39+
Mockito.when(chainBaseManager.getSolidBlockId()).thenReturn(blockId);
40+
Assert.assertTrue(tronNetDelegate.unsolidifiedBlockCheck());
41+
42+
parameter.setUnsolidifiedBlockCheck(false);
43+
tronNetDelegate = new TronNetDelegate();
44+
45+
field = tronNetDelegate.getClass().getDeclaredField("unsolidifiedBlockCheck");
46+
field.setAccessible(true);
47+
field.set(tronNetDelegate, false);
48+
49+
Assert.assertTrue(!tronNetDelegate.unsolidifiedBlockCheck());
50+
}
51+
}

framework/src/test/java/org/tron/core/net/messagehandler/InventoryMsgHandlerTest.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
package org.tron.core.net.messagehandler;
22

3+
import static org.mockito.Mockito.mock;
4+
35
import java.lang.reflect.Field;
46
import java.net.InetAddress;
57
import java.net.InetSocketAddress;
68
import java.util.ArrayList;
79
import org.junit.Test;
10+
import org.mockito.Mockito;
11+
import org.tron.core.Constant;
12+
import org.tron.core.config.args.Args;
13+
import org.tron.core.net.TronNetDelegate;
814
import org.tron.core.net.message.adv.InventoryMessage;
915
import org.tron.core.net.peer.PeerConnection;
1016
import org.tron.p2p.connection.Channel;
1117
import org.tron.protos.Protocol.Inventory.InventoryType;
1218

1319
public class InventoryMsgHandlerTest {
1420

15-
private InventoryMsgHandler handler = new InventoryMsgHandler();
16-
1721
@Test
1822
public void testProcessMessage() throws Exception {
23+
InventoryMsgHandler handler = new InventoryMsgHandler();
24+
Args.setParam(new String[] {"-w"}, Constant.TEST_CONF);
25+
Args.logConfig();
26+
1927
InventoryMessage msg = new InventoryMessage(new ArrayList<>(), InventoryType.TRX);
2028
PeerConnection peer = new PeerConnection();
2129
peer.setChannel(getChannel("1.0.0.3", 1000));
@@ -31,6 +39,16 @@ public void testProcessMessage() throws Exception {
3139
peer.setNeedSyncFromUs(true);
3240
handler.processMessage(peer, msg);
3341

42+
peer.setNeedSyncFromUs(false);
43+
44+
TronNetDelegate tronNetDelegate = mock(TronNetDelegate.class);
45+
Mockito.when(tronNetDelegate.unsolidifiedBlockCheck()).thenReturn(true);
46+
47+
Field field = handler.getClass().getDeclaredField("tronNetDelegate");
48+
field.setAccessible(true);
49+
field.set(handler, tronNetDelegate);
50+
51+
handler.processMessage(peer, msg);
3452
}
3553

3654
private Channel getChannel(String host, int port) throws Exception {

protocol/src/main/protos/api/api.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,8 @@ message Return {
10511051
SERVER_BUSY = 9;
10521052
NO_CONNECTION = 10;
10531053
NOT_ENOUGH_EFFECTIVE_CONNECTION = 11;
1054+
BLOCK_UNSOLIDIFIED = 12;
1055+
10541056
OTHER_ERROR = 20;
10551057
}
10561058

0 commit comments

Comments
 (0)