Skip to content

Commit 0f5a8de

Browse files
authored
Merge master into develop branch (#5668)
* feat(api):fix a concurrency issue for toString in BlockCapsule (#5657) * feat(db):optimize cache settings (#5659) * feat(lite):optimize DbLite tool (#5658)
1 parent 52b3327 commit 0f5a8de

File tree

6 files changed

+98
-48
lines changed

6 files changed

+98
-48
lines changed

chainbase/src/main/java/org/tron/core/store/WitnessStore.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,17 @@
1111
import org.springframework.beans.factory.annotation.Autowired;
1212
import org.springframework.beans.factory.annotation.Value;
1313
import org.springframework.stereotype.Component;
14-
import org.tron.common.cache.CacheManager;
15-
import org.tron.common.cache.CacheStrategies;
16-
import org.tron.common.cache.CacheType;
17-
import org.tron.common.cache.TronCache;
1814
import org.tron.core.capsule.WitnessCapsule;
1915
import org.tron.core.config.Parameter;
2016
import org.tron.core.db.TronStoreWithRevoking;
2117

2218
@Slf4j(topic = "DB")
2319
@Component
2420
public class WitnessStore extends TronStoreWithRevoking<WitnessCapsule> {
25-
// cache for 127 SR
26-
private final TronCache<Integer, List<WitnessCapsule>> witnessStandbyCache;
2721

2822
@Autowired
2923
protected WitnessStore(@Value("witness") String dbName) {
3024
super(dbName);
31-
String strategy = String.format(CacheStrategies.PATTERNS, 1, 1, "30s", 1);
32-
witnessStandbyCache = CacheManager.allocate(CacheType.witnessStandby, strategy);
3325
}
3426

3527
/**
@@ -48,19 +40,8 @@ public WitnessCapsule get(byte[] key) {
4840
}
4941

5042
public List<WitnessCapsule> getWitnessStandby() {
51-
List<WitnessCapsule> list =
52-
witnessStandbyCache.getIfPresent(Parameter.ChainConstant.WITNESS_STANDBY_LENGTH);
53-
if (list != null) {
54-
return list;
55-
}
56-
return updateWitnessStandby(null);
57-
}
58-
59-
public List<WitnessCapsule> updateWitnessStandby(List<WitnessCapsule> all) {
6043
List<WitnessCapsule> ret;
61-
if (all == null) {
62-
all = getAllWitnesses();
63-
}
44+
List<WitnessCapsule> all = getAllWitnesses();
6445
all.sort(Comparator.comparingLong(WitnessCapsule::getVoteCount)
6546
.reversed().thenComparing(Comparator.comparingInt(
6647
(WitnessCapsule w) -> w.getAddress().hashCode()).reversed()));
@@ -71,7 +52,6 @@ public List<WitnessCapsule> updateWitnessStandby(List<WitnessCapsule> all) {
7152
}
7253
// trim voteCount = 0
7354
ret.removeIf(w -> w.getVoteCount() < 1);
74-
witnessStandbyCache.put(Parameter.ChainConstant.WITNESS_STANDBY_LENGTH, ret);
7555
return ret;
7656
}
7757

consensus/src/main/java/org/tron/consensus/ConsensusDelegate.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@ public List<WitnessCapsule> getAllWitnesses() {
108108
return witnessStore.getAllWitnesses();
109109
}
110110

111-
public List<WitnessCapsule> updateWitnessStandby(List<WitnessCapsule> all) {
112-
return witnessStore.updateWitnessStandby(all);
113-
}
114-
115111
public void saveStateFlag(int flag) {
116112
dynamicPropertiesStore.saveStateFlag(flag);
117113
}

consensus/src/main/java/org/tron/consensus/dpos/MaintenanceManager.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,11 @@ public void doMaintenance() {
151151
if (dynamicPropertiesStore.allowChangeDelegation()) {
152152
long nextCycle = dynamicPropertiesStore.getCurrentCycleNumber() + 1;
153153
dynamicPropertiesStore.saveCurrentCycleNumber(nextCycle);
154-
List<WitnessCapsule> all = consensusDelegate.getAllWitnesses();
155-
all.forEach(witness -> {
154+
consensusDelegate.getAllWitnesses().forEach(witness -> {
156155
delegationStore.setBrokerage(nextCycle, witness.createDbKey(),
157156
delegationStore.getBrokerage(witness.createDbKey()));
158157
delegationStore.setWitnessVote(nextCycle, witness.createDbKey(), witness.getVoteCount());
159158
});
160-
consensusDelegate.updateWitnessStandby(all);
161159
}
162160
}
163161

framework/src/main/java/org/tron/program/Version.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
public class Version {
44

5-
public static final String VERSION_NAME = "GreatVoyage-v4.7.2-140-g9d13f9cb69";
6-
public static final String VERSION_CODE = "18173";
7-
private static final String VERSION = "4.7.3";
5+
public static final String VERSION_NAME = "GreatVoyage-v4.7.3-5-g788136ebe";
6+
public static final String VERSION_CODE = "18180";
7+
private static final String VERSION = "4.7.3.1";
88

99
public static String getVersion() {
1010
return VERSION;

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,14 +581,24 @@ public void pushSwitchFork()
581581
AccountResourceInsufficientException, EventBloomException {
582582

583583
String key = "f31db24bfbd1a2ef19beddca0a0fa37632eded9ac666a05d3bd925f01dde1f62";
584+
String key2 = "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4";
584585
byte[] privateKey = ByteArray.fromHexString(key);
585586
final ECKey ecKey = ECKey.fromPrivate(privateKey);
586587
byte[] address = ecKey.getAddress();
587-
588+
WitnessCapsule sr1 = new WitnessCapsule(
589+
ByteString.copyFrom(address), "www.tron.net/first");
590+
sr1.setVoteCount(1000000000L);
591+
byte[] privateKey2 = ByteArray.fromHexString(key2);
592+
final ECKey ecKey2 = ECKey.fromPrivate(privateKey2);
593+
byte[] address2 = ecKey2.getAddress();
594+
WitnessCapsule sr2 = new WitnessCapsule(
595+
ByteString.copyFrom(address2), "www.tron.net/second");
596+
sr2.setVoteCount(100000L);
597+
chainManager.getWitnessStore().put(address, sr1);
588598
WitnessCapsule witnessCapsule = new WitnessCapsule(ByteString.copyFrom(address));
589599
chainManager.getWitnessScheduleStore().saveActiveWitnesses(new ArrayList<>());
590600
chainManager.addWitness(ByteString.copyFrom(address));
591-
601+
List<WitnessCapsule> witnessStandby1 = chainManager.getWitnessStore().getWitnessStandby();
592602
Block block = getSignedBlock(witnessCapsule.getAddress(), 1533529947843L, privateKey);
593603
dbManager.pushBlock(new BlockCapsule(block));
594604

@@ -625,6 +635,9 @@ public void pushSwitchFork()
625635
} catch (Exception e) {
626636
Assert.assertTrue(e instanceof Exception);
627637
}
638+
chainManager.getWitnessStore().put(address, sr2);
639+
List<WitnessCapsule> witnessStandby2 = chainManager.getWitnessStore().getWitnessStandby();
640+
Assert.assertNotEquals(witnessStandby1, witnessStandby2);
628641
}
629642

630643

plugins/src/main/java/org/tron/plugins/DbLite.java

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.google.common.annotations.VisibleForTesting;
44
import com.google.common.collect.Lists;
55
import com.google.common.collect.Maps;
6+
import com.google.common.primitives.Bytes;
7+
import com.google.common.primitives.Ints;
68
import com.google.common.primitives.Longs;
79
import java.io.File;
810
import java.io.FileNotFoundException;
@@ -153,10 +155,10 @@ public void generateSnapshot(String sourceDir, String snapshotDir) {
153155
long start = System.currentTimeMillis();
154156
snapshotDir = Paths.get(snapshotDir, SNAPSHOT_DIR_NAME).toString();
155157
try {
156-
mergeCheckpoint(sourceDir);
157158
hasEnoughBlock(sourceDir);
158159
List<String> snapshotDbs = getSnapshotDbs(sourceDir);
159160
split(sourceDir, snapshotDir, snapshotDbs);
161+
mergeCheckpoint2Snapshot(sourceDir, snapshotDir);
160162
// write genesisBlock , latest recent blocks and trans
161163
fillSnapshotBlockAndTransDb(sourceDir, snapshotDir);
162164
// save min block to info
@@ -190,9 +192,9 @@ public void generateHistory(String sourceDir, String historyDir) {
190192
throw new IllegalStateException(
191193
String.format("Unavailable sourceDir: %s is not fullNode data.", sourceDir));
192194
}
193-
mergeCheckpoint(sourceDir);
194195
hasEnoughBlock(sourceDir);
195196
split(sourceDir, historyDir, archiveDbs);
197+
mergeCheckpoint2History(sourceDir, historyDir);
196198
// save max block to info
197199
generateInfoProperties(Paths.get(historyDir, INFO_FILE_NAME).toString(),
198200
getLatestBlockHeaderNum(sourceDir));
@@ -261,6 +263,15 @@ private List<String> getSnapshotDbs(String sourceDir) {
261263
return snapshotDbs;
262264
}
263265

266+
private void mergeCheckpoint2Snapshot(String sourceDir, String historyDir) {
267+
List<String> snapshotDbs = getSnapshotDbs(sourceDir);
268+
mergeCheckpoint(sourceDir, historyDir, snapshotDbs);
269+
}
270+
271+
private void mergeCheckpoint2History(String sourceDir, String destDir) {
272+
mergeCheckpoint(sourceDir, destDir, archiveDbs);
273+
}
274+
264275
private void split(String sourceDir, String destDir, List<String> dbs) throws IOException {
265276
logger.info("Begin to split the dbs.");
266277
spec.commandLine().getOut().println("Begin to split the dbs.");
@@ -278,7 +289,7 @@ private void split(String sourceDir, String destDir, List<String> dbs) throws IO
278289
FileUtils.copyDatabases(Paths.get(sourceDir), Paths.get(destDir), dbs);
279290
}
280291

281-
private void mergeCheckpoint(String sourceDir) {
292+
private void mergeCheckpoint(String sourceDir, String destDir, List<String> destDbs) {
282293
logger.info("Begin to merge checkpoint to dataset.");
283294
spec.commandLine().getOut().println("Begin to merge checkpoint to dataset.");
284295
try {
@@ -287,18 +298,18 @@ private void mergeCheckpoint(String sourceDir) {
287298
for (String cp : cpList) {
288299
DBInterface checkpointDb = DbTool.getDB(
289300
sourceDir + "/" + DBUtils.CHECKPOINT_DB_V2, cp);
290-
recover(checkpointDb, sourceDir);
301+
recover(checkpointDb, destDir, destDbs);
291302
}
292303
} else if (Paths.get(sourceDir, CHECKPOINT_DB).toFile().exists()) {
293304
DBInterface tmpDb = DbTool.getDB(sourceDir, CHECKPOINT_DB);
294-
recover(tmpDb, sourceDir);
305+
recover(tmpDb, destDir, destDbs);
295306
}
296307
} catch (IOException | RocksDBException e) {
297308
throw new RuntimeException(e);
298309
}
299310
}
300311

301-
private void recover(DBInterface db, String destDir)
312+
private void recover(DBInterface db, String destDir, List<String> destDbs)
302313
throws IOException, RocksDBException {
303314
try (DBIterator iterator = db.iterator()) {
304315
for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
@@ -312,15 +323,17 @@ private void recover(DBInterface db, String destDir)
312323
byte[] realKey = Arrays.copyOfRange(key, dbName.getBytes().length + 4, key.length);
313324
byte[] realValue =
314325
value.length == 1 ? null : Arrays.copyOfRange(value, 1, value.length);
315-
DBInterface destDb = DbTool.getDB(destDir, dbName);
316-
if (realValue != null) {
317-
destDb.put(realKey, realValue);
318-
} else {
319-
byte op = value[0];
320-
if (DBUtils.Operator.DELETE.getValue() == op) {
321-
destDb.delete(realKey);
326+
if (destDbs != null && destDbs.contains(dbName)) {
327+
DBInterface destDb = DbTool.getDB(destDir, dbName);
328+
if (realValue != null) {
329+
destDb.put(realKey, realValue);
322330
} else {
323-
destDb.put(realKey, new byte[0]);
331+
byte op = value[0];
332+
if (DBUtils.Operator.DELETE.getValue() == op) {
333+
destDb.delete(realKey);
334+
} else {
335+
destDb.put(realKey, new byte[0]);
336+
}
324337
}
325338
}
326339
}
@@ -340,14 +353,30 @@ private void generateInfoProperties(String propertyfile, long num)
340353
}
341354

342355
private long getLatestBlockHeaderNum(String databaseDir) throws IOException, RocksDBException {
356+
// query latest_block_header_number from checkpoint first
343357
final String latestBlockHeaderNumber = "latest_block_header_number";
358+
DBInterface checkpointDb = getCheckpointDb(databaseDir);
359+
Long blockNumber = getLatestBlockHeaderNumFromCP(checkpointDb,
360+
latestBlockHeaderNumber.getBytes());
361+
if (blockNumber != null) {
362+
return blockNumber;
363+
}
364+
// query from propertiesDb if checkpoint not contains latest_block_header_number
344365
DBInterface propertiesDb = DbTool.getDB(databaseDir, PROPERTIES_DB_NAME);
345366
return Optional.ofNullable(propertiesDb.get(ByteArray.fromString(latestBlockHeaderNumber)))
346367
.map(ByteArray::toLong)
347368
.orElseThrow(
348369
() -> new IllegalArgumentException("not found latest block header number"));
349370
}
350371

372+
private Long getLatestBlockHeaderNumFromCP(DBInterface db, byte[] key) {
373+
byte[] value = db.get(Bytes.concat(simpleEncode(PROPERTIES_DB_NAME), key));
374+
if (value != null && value.length > 1) {
375+
return ByteArray.toLong(Arrays.copyOfRange(value, 1, value.length));
376+
}
377+
return null;
378+
}
379+
351380
/**
352381
* recent blocks, trans and genesis block.
353382
*/
@@ -414,6 +443,15 @@ private byte[] getGenesisBlockHash(String parentDir) throws IOException, RocksDB
414443
return result;
415444
}
416445

446+
private static byte[] simpleEncode(String s) {
447+
byte[] bytes = s.getBytes();
448+
byte[] length = Ints.toByteArray(bytes.length);
449+
byte[] r = new byte[4 + bytes.length];
450+
System.arraycopy(length, 0, r, 0, 4);
451+
System.arraycopy(bytes, 0, r, 4, bytes.length);
452+
return r;
453+
}
454+
417455
private BlockNumInfo checkAndGetBlockNumInfo(String historyDir, String liteDir)
418456
throws IOException, RocksDBException {
419457
logger.info("Check the compatibility of this history.");
@@ -485,6 +523,7 @@ private void trimExtraHistory(String liteDir, BlockNumInfo blockNumInfo)
485523
DBInterface transDb = DbTool.getDB(liteDir, TRANS_DB_NAME);
486524
DBInterface tranRetDb = DbTool.getDB(liteDir, TRANSACTION_RET_DB_NAME);
487525

526+
488527
ProgressBar.wrap(LongStream.rangeClosed(start, end)
489528
.boxed()
490529
.sorted((a, b) -> Long.compare(b, a)), "trimHistory").forEach(n -> {
@@ -519,6 +558,7 @@ private void mergeBak2Database(String liteDir, BlockNumInfo blockNumInfo) throws
519558
return;
520559
}
521560

561+
522562
Path bakDir = Paths.get(liteDir, BACKUP_DIR_PREFIX + START_TIME);
523563
logger.info("Begin to merge {} to database, start {} end {}.", bakDir, start, end);
524564
spec.commandLine().getOut()
@@ -545,7 +585,17 @@ private void mergeBak2Database(String liteDir, BlockNumInfo blockNumInfo) throws
545585

546586
private byte[] getDataFromSourceDB(String sourceDir, String dbName, byte[] key)
547587
throws IOException, RocksDBException {
548-
byte[] value = DbTool.getDB(sourceDir, dbName).get(key);
588+
DBInterface sourceDb = DbTool.getDB(sourceDir, dbName);
589+
DBInterface checkpointDb = getCheckpointDb(sourceDir);
590+
// get data from tmp first.
591+
byte[] valueFromTmp = checkpointDb.get(Bytes.concat(simpleEncode(dbName), key));
592+
byte[] value;
593+
if (isEmptyBytes(valueFromTmp)) {
594+
value = sourceDb.get(key);
595+
} else {
596+
value = valueFromTmp.length == 1
597+
? null : Arrays.copyOfRange(valueFromTmp, 1, valueFromTmp.length);
598+
}
549599
if (isEmptyBytes(value)) {
550600
throw new RuntimeException(String.format("data not found in store, dbName: %s, key: %s",
551601
dbName, Arrays.toString(key)));
@@ -614,6 +664,19 @@ private long getSecondBlock(String databaseDir) throws RocksDBException, IOExcep
614664
return num;
615665
}
616666

667+
private DBInterface getCheckpointDb(String sourceDir) throws IOException, RocksDBException {
668+
List<String> cpList = getCheckpointV2List(sourceDir);
669+
DBInterface checkpointDb;
670+
if (cpList.size() > 0) {
671+
String latestCp = cpList.get(cpList.size() - 1);
672+
checkpointDb = DbTool.getDB(
673+
sourceDir + "/" + DBUtils.CHECKPOINT_DB_V2, latestCp);
674+
} else {
675+
checkpointDb = DbTool.getDB(sourceDir, CHECKPOINT_DB);
676+
}
677+
return checkpointDb;
678+
}
679+
617680
@VisibleForTesting
618681
public static void setRecentBlks(long recentBlks) {
619682
RECENT_BLKS = recentBlks;

0 commit comments

Comments
 (0)