Skip to content

Commit 1e2986a

Browse files
authored
Merge pull request #5643 from ss3344520/block_unsolid_solution
feat(net): stop tx broadcasting if block cannot solidified
2 parents a0f431c + bf8de17 commit 1e2986a

File tree

10 files changed

+127
-2
lines changed

10 files changed

+127
-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
@@ -654,6 +654,14 @@ public class CommonParameter {
654654
@Setter
655655
public long allowCancelAllUnfreezeV2;
656656

657+
@Getter
658+
@Setter
659+
public boolean unsolidifiedBlockCheck;
660+
661+
@Getter
662+
@Setter
663+
public int maxUnsolidifiedBlocks;
664+
657665
private static double calcMaxTimeRatio() {
658666
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
659667
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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,14 @@ public GrpcAPI.Return broadcastTransaction(Transaction signedTransaction) {
498498
Sha256Hash txID = trx.getTransactionId();
499499
try {
500500
TransactionMessage message = new TransactionMessage(signedTransaction.toByteArray());
501+
502+
if (tronNetDelegate.isBlockUnsolidified()) {
503+
logger.warn("Broadcast transaction {} has failed, block unsolidified.", txID);
504+
return builder.setResult(false).setCode(response_code.BLOCK_UNSOLIDIFIED)
505+
.setMessage(ByteString.copyFromUtf8("Block unsolidified."))
506+
.build();
507+
}
508+
501509
if (minEffectiveConnection != 0) {
502510
if (tronNetDelegate.getActivePeer().isEmpty()) {
503511
logger.warn("Broadcast transaction {} has failed, no connection.", txID);

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
@@ -229,6 +229,8 @@ public static void clearParam() {
229229
PARAMETER.dynamicConfigEnable = false;
230230
PARAMETER.dynamicConfigCheckInterval = 600;
231231
PARAMETER.allowTvmShangHai = 0;
232+
PARAMETER.unsolidifiedBlockCheck = true;
233+
PARAMETER.maxUnsolidifiedBlocks = 1000;
232234
}
233235

234236
/**
@@ -1181,6 +1183,14 @@ public static void setParam(final String[] args, final String confFileName) {
11811183
config.hasPath(Constant.COMMITTEE_ALLOW_TVM_SHANGHAI) ? config
11821184
.getInt(Constant.COMMITTEE_ALLOW_TVM_SHANGHAI) : 0;
11831185

1186+
PARAMETER.unsolidifiedBlockCheck =
1187+
!config.hasPath(Constant.UNSOLIDIFIED_BLOCK_CHECK)
1188+
|| config.getBoolean(Constant.UNSOLIDIFIED_BLOCK_CHECK);
1189+
1190+
PARAMETER.maxUnsolidifiedBlocks =
1191+
config.hasPath(Constant.MAX_UNSOLIDIFIED_BLOCKS) ? config
1192+
.getInt(Constant.MAX_UNSOLIDIFIED_BLOCKS) : 1000;
1193+
11841194
logConfig();
11851195
}
11861196

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 isBlockUnsolidified() {
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.isBlockUnsolidified()) {
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
@@ -94,6 +94,8 @@ public void get() {
9494
Assert.assertEquals(0, parameter.getActiveNodes().size());
9595
Assert.assertEquals(30, parameter.getMaxConnections());
9696
Assert.assertEquals(43, parameter.getNodeP2pVersion());
97+
Assert.assertEquals(1000, parameter.getMaxUnsolidifiedBlocks());
98+
Assert.assertEquals(true, parameter.isUnsolidifiedBlockCheck());
9799
//Assert.assertEquals(30, args.getSyncNodeCount());
98100

99101
// 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.isBlockUnsolidified());
37+
38+
blockId = new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 1L);
39+
Mockito.when(chainBaseManager.getSolidBlockId()).thenReturn(blockId);
40+
Assert.assertTrue(tronNetDelegate.isBlockUnsolidified());
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.isBlockUnsolidified());
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.isBlockUnsolidified()).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)