Skip to content

Commit a1c7338

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into feature/optimize_stake2_code
2 parents 699c044 + a4100b6 commit a1c7338

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1410
-277
lines changed

chainbase/src/main/java/org/tron/core/ChainBaseManager.java

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.tron.core.db.RecentBlockStore;
3030
import org.tron.core.db.RecentTransactionStore;
3131
import org.tron.core.db.TransactionStore;
32-
import org.tron.core.db2.core.ITronChainBase;
3332
import org.tron.core.exception.BadItemException;
3433
import org.tron.core.exception.HeaderNotFound;
3534
import org.tron.core.exception.ItemNotFoundException;
@@ -245,54 +244,6 @@ public class ChainBaseManager {
245244
@Setter
246245
private long lowestBlockNum = -1; // except num = 0.
247246

248-
public void closeOneStore(ITronChainBase database) {
249-
logger.info("******** Begin to close {}. ********", database.getName());
250-
try {
251-
database.close();
252-
} catch (Exception e) {
253-
logger.info("Failed to close {}.", database.getName(), e);
254-
} finally {
255-
logger.info("******** End to close {}. ********", database.getName());
256-
}
257-
}
258-
259-
public void closeAllStore() {
260-
dbStatService.shutdown();
261-
closeOneStore(transactionRetStore);
262-
closeOneStore(recentBlockStore);
263-
closeOneStore(transactionHistoryStore);
264-
closeOneStore(transactionStore);
265-
closeOneStore(accountStore);
266-
closeOneStore(blockStore);
267-
closeOneStore(blockIndexStore);
268-
closeOneStore(accountIdIndexStore);
269-
closeOneStore(accountIndexStore);
270-
closeOneStore(witnessScheduleStore);
271-
closeOneStore(assetIssueStore);
272-
closeOneStore(dynamicPropertiesStore);
273-
closeOneStore(abiStore);
274-
closeOneStore(codeStore);
275-
closeOneStore(contractStore);
276-
closeOneStore(contractStateStore);
277-
closeOneStore(storageRowStore);
278-
closeOneStore(exchangeStore);
279-
closeOneStore(proposalStore);
280-
closeOneStore(votesStore);
281-
closeOneStore(delegatedResourceStore);
282-
closeOneStore(delegatedResourceAccountIndexStore);
283-
closeOneStore(assetIssueV2Store);
284-
closeOneStore(exchangeV2Store);
285-
closeOneStore(nullifierStore);
286-
closeOneStore(merkleTreeStore);
287-
closeOneStore(delegationStore);
288-
closeOneStore(proofStore);
289-
closeOneStore(commonStore);
290-
closeOneStore(commonDataBase);
291-
closeOneStore(pbftSignDataStore);
292-
closeOneStore(sectionBloomStore);
293-
closeOneStore(accountAssetStore);
294-
}
295-
296247
// for test only
297248
public List<ByteString> getWitnesses() {
298249
return witnessScheduleStore.getActiveWitnesses();
@@ -316,9 +267,7 @@ public BlockCapsule getHead() throws HeaderNotFound {
316267
}
317268

318269
public synchronized BlockId getHeadBlockId() {
319-
return new BlockId(
320-
dynamicPropertiesStore.getLatestBlockHeaderHash(),
321-
dynamicPropertiesStore.getLatestBlockHeaderNumber());
270+
return new BlockId(dynamicPropertiesStore.getLatestBlockHeaderHash());
322271
}
323272

324273
public long getHeadBlockNum() {
@@ -434,6 +383,10 @@ private void init() {
434383
this.nodeType = getLowestBlockNum() > 1 ? NodeType.LITE : NodeType.FULL;
435384
}
436385

386+
public void shutdown() {
387+
dbStatService.shutdown();
388+
}
389+
437390
public boolean isLiteNode() {
438391
return getNodeType() == NodeType.LITE;
439392
}

chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@ public static byte[] getOwner(Transaction.Contract contract) {
346346
}
347347
}
348348
return owner.toByteArray();
349+
} catch (InvalidProtocolBufferException invalidProtocolBufferException) {
350+
logger.warn("InvalidProtocolBufferException occurred because {}, please verify the interface "
351+
+ "input parameters", invalidProtocolBufferException.getMessage());
352+
return new byte[0];
349353
} catch (Exception ex) {
350354
logger.error(ex.getMessage());
351355
return new byte[0];

chainbase/src/main/java/org/tron/core/db/TronDatabase.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,14 @@ public void reset() {
9494
*/
9595
@Override
9696
public void close() {
97-
dbSource.closeDB();
97+
logger.info("******** Begin to close {}. ********", getName());
98+
try {
99+
dbSource.closeDB();
100+
} catch (Exception e) {
101+
logger.warn("Failed to close {}.", getName(), e);
102+
} finally {
103+
logger.info("******** End to close {}. ********", getName());
104+
}
98105
}
99106

100107
public abstract void put(byte[] key, T item);

chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,14 @@ public String getName() {
182182

183183
@Override
184184
public void close() {
185-
revokingDB.close();
185+
logger.info("******** Begin to close {}. ********", getName());
186+
try {
187+
revokingDB.close();
188+
} catch (Exception e) {
189+
logger.warn("Failed to close {}.", getName(), e);
190+
} finally {
191+
logger.info("******** End to close {}. ********", getName());
192+
}
186193
}
187194

188195
@Override

chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,26 @@
33
import com.google.common.hash.BloomFilter;
44
import com.google.common.hash.Funnels;
55
import com.google.common.primitives.Longs;
6+
import java.io.BufferedInputStream;
7+
import java.io.BufferedOutputStream;
8+
import java.io.InputStream;
9+
import java.io.InputStreamReader;
10+
import java.io.OutputStream;
11+
import java.io.Reader;
12+
import java.io.Writer;
13+
import java.nio.charset.StandardCharsets;
14+
import java.nio.file.Files;
15+
import java.nio.file.Path;
616
import java.nio.file.Paths;
17+
import java.nio.file.StandardOpenOption;
718
import java.util.Iterator;
819
import java.util.Map;
920
import java.util.Map.Entry;
21+
import java.util.Properties;
22+
import java.util.concurrent.CompletableFuture;
23+
import java.util.concurrent.atomic.AtomicBoolean;
24+
import lombok.Getter;
25+
import lombok.Setter;
1026
import lombok.extern.slf4j.Slf4j;
1127
import org.apache.commons.lang3.ArrayUtils;
1228
import org.bouncycastle.util.encoders.Hex;
@@ -17,6 +33,7 @@
1733
import org.tron.common.storage.leveldb.LevelDbDataSourceImpl;
1834
import org.tron.common.storage.rocksdb.RocksDbDataSourceImpl;
1935
import org.tron.common.utils.ByteArray;
36+
import org.tron.common.utils.FileUtil;
2037
import org.tron.common.utils.JsonUtil;
2138
import org.tron.common.utils.StorageUtils;
2239
import org.tron.core.capsule.BytesCapsule;
@@ -42,6 +59,7 @@ public class TxCacheDB implements DB<byte[], byte[]>, Flusher {
4259
private BloomFilter<byte[]>[] bloomFilters = new BloomFilter[2];
4360
// filterStartBlock record the start block of the active filter
4461
private volatile long filterStartBlock = INVALID_BLOCK;
62+
private volatile long currentBlockNum = INVALID_BLOCK;
4563
// currentFilterIndex records the index of the active filter
4664
private volatile int currentFilterIndex = 0;
4765

@@ -57,6 +75,16 @@ public class TxCacheDB implements DB<byte[], byte[]>, Flusher {
5775
// replace persistentStore and optimizes startup performance
5876
private RecentTransactionStore recentTransactionStore;
5977

78+
private final Path cacheFile0;
79+
private final Path cacheFile1;
80+
private final Path cacheProperties;
81+
private final Path cacheDir;
82+
private AtomicBoolean isValid = new AtomicBoolean(false);
83+
84+
@Getter
85+
@Setter
86+
private volatile boolean alive;
87+
6088
public TxCacheDB(String name, RecentTransactionStore recentTransactionStore) {
6189
this.name = name;
6290
this.TRANSACTION_COUNT =
@@ -85,6 +113,10 @@ public TxCacheDB(String name, RecentTransactionStore recentTransactionStore) {
85113
MAX_BLOCK_SIZE * TRANSACTION_COUNT);
86114
this.bloomFilters[1] = BloomFilter.create(Funnels.byteArrayFunnel(),
87115
MAX_BLOCK_SIZE * TRANSACTION_COUNT);
116+
cacheDir = Paths.get(CommonParameter.getInstance().getOutputDirectory(), ".cache");
117+
this.cacheFile0 = Paths.get(cacheDir.toString(), "bloomFilters_0");
118+
this.cacheFile1 = Paths.get(cacheDir.toString(), "bloomFilters_1");
119+
this.cacheProperties = Paths.get(cacheDir.toString(), "txCache.properties");
88120

89121
}
90122

@@ -110,6 +142,11 @@ private void initCache() {
110142
}
111143

112144
public void init() {
145+
if (recovery()) {
146+
isValid.set(true);
147+
setAlive(true);
148+
return;
149+
}
113150
long size = recentTransactionStore.size();
114151
if (size != MAX_BLOCK_SIZE) {
115152
// 0. load from persistentStore
@@ -129,6 +166,8 @@ public void init() {
129166
logger.info("Load cache from recentTransactionStore, filter: {}, filter-fpp: {}, cost: {} ms.",
130167
bloomFilters[1].approximateElementCount(), bloomFilters[1].expectedFpp(),
131168
System.currentTimeMillis() - start);
169+
isValid.set(true);
170+
setAlive(true);
132171
}
133172

134173
@Override
@@ -172,7 +211,7 @@ public void put(byte[] key, byte[] value) {
172211
MAX_BLOCK_SIZE * TRANSACTION_COUNT);
173212
}
174213
bloomFilters[currentFilterIndex].put(key);
175-
214+
currentBlockNum = blockNum;
176215
if (lastMetricBlock != blockNum) {
177216
lastMetricBlock = blockNum;
178217
Metrics.gaugeSet(MetricKeys.Gauge.TX_CACHE,
@@ -208,22 +247,138 @@ public Iterator<Entry<byte[], byte[]>> iterator() {
208247
}
209248

210249
@Override
211-
public void flush(Map<WrappedByteArray, WrappedByteArray> batch) {
250+
public synchronized void flush(Map<WrappedByteArray, WrappedByteArray> batch) {
251+
isValid.set(false);
212252
batch.forEach((k, v) -> this.put(k.getBytes(), v.getBytes()));
253+
isValid.set(true);
213254
}
214255

215256
@Override
216257
public void close() {
217-
reset();
258+
if (!isAlive()) {
259+
return;
260+
}
261+
dump();
218262
bloomFilters[0] = null;
219263
bloomFilters[1] = null;
220264
persistentStore.close();
265+
setAlive(false);
221266
}
222267

223268
@Override
224269
public void reset() {
225270
}
226271

272+
private boolean recovery() {
273+
FileUtil.createDirIfNotExists(this.cacheDir.toString());
274+
logger.info("recovery bloomFilters start.");
275+
CompletableFuture<Boolean> loadProperties = CompletableFuture.supplyAsync(this::loadProperties);
276+
CompletableFuture<Boolean> tk0 = loadProperties.thenApplyAsync(
277+
v -> recovery(0, this.cacheFile0));
278+
CompletableFuture<Boolean> tk1 = loadProperties.thenApplyAsync(
279+
v -> recovery(1, this.cacheFile1));
280+
281+
return CompletableFuture.allOf(tk0, tk1).thenApply(v -> {
282+
logger.info("recovery bloomFilters success.");
283+
return true;
284+
}).exceptionally(this::handleException).join();
285+
}
286+
287+
private boolean recovery(int index, Path file) {
288+
try (InputStream in = new BufferedInputStream(Files.newInputStream(file,
289+
StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE))) {
290+
logger.info("recovery bloomFilter[{}] from file.", index);
291+
long start = System.currentTimeMillis();
292+
bloomFilters[index] = BloomFilter.readFrom(in, Funnels.byteArrayFunnel());
293+
logger.info("recovery bloomFilter[{}] from file done,filter: {}, filter-fpp: {}, cost {} ms.",
294+
index, bloomFilters[index].approximateElementCount(), bloomFilters[index].expectedFpp(),
295+
System.currentTimeMillis() - start);
296+
return true;
297+
} catch (Exception e) {
298+
throw new RuntimeException(e);
299+
}
300+
}
301+
302+
private boolean handleException(Throwable e) {
303+
bloomFilters[0] = BloomFilter.create(Funnels.byteArrayFunnel(),
304+
MAX_BLOCK_SIZE * TRANSACTION_COUNT);
305+
bloomFilters[1] = BloomFilter.create(Funnels.byteArrayFunnel(),
306+
MAX_BLOCK_SIZE * TRANSACTION_COUNT);
307+
try {
308+
Files.deleteIfExists(this.cacheFile0);
309+
Files.deleteIfExists(this.cacheFile1);
310+
} catch (Exception ignored) {
311+
312+
}
313+
logger.info("recovery bloomFilters failed. {}", e.getMessage());
314+
logger.info("rollback to previous mode.");
315+
return false;
316+
}
317+
318+
private void dump() {
319+
if (!isValid.get()) {
320+
logger.info("bloomFilters is not valid.");
321+
}
322+
FileUtil.createDirIfNotExists(this.cacheDir.toString());
323+
logger.info("dump bloomFilters start.");
324+
CompletableFuture<Void> task0 = CompletableFuture.runAsync(
325+
() -> dump(0, this.cacheFile0));
326+
CompletableFuture<Void> task1 = CompletableFuture.runAsync(
327+
() -> dump(1, this.cacheFile1));
328+
CompletableFuture.allOf(task0, task1).thenRun(() -> {
329+
writeProperties();
330+
logger.info("dump bloomFilters done.");
331+
332+
}).exceptionally(e -> {
333+
logger.info("dump bloomFilters to file failed. {}", e.getMessage());
334+
return null;
335+
}).join();
336+
}
337+
338+
private void dump(int index, Path file) {
339+
try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(file))) {
340+
logger.info("dump bloomFilters[{}] to file.", index);
341+
long start = System.currentTimeMillis();
342+
bloomFilters[index].writeTo(out);
343+
logger.info("dump bloomFilters[{}] to file done,filter: {}, filter-fpp: {}, cost {} ms.",
344+
index, bloomFilters[index].approximateElementCount(), bloomFilters[index].expectedFpp(),
345+
System.currentTimeMillis() - start);
346+
} catch (Exception e) {
347+
throw new RuntimeException(e);
348+
}
349+
}
350+
351+
private boolean loadProperties() {
352+
try (Reader r = new InputStreamReader(new BufferedInputStream(Files.newInputStream(
353+
this.cacheProperties, StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE)),
354+
StandardCharsets.UTF_8)) {
355+
Properties properties = new Properties();
356+
properties.load(r);
357+
filterStartBlock = Long.parseLong(properties.getProperty("filterStartBlock"));
358+
currentBlockNum = Long.parseLong(properties.getProperty("currentBlockNum"));
359+
currentFilterIndex = Integer.parseInt(properties.getProperty("currentFilterIndex"));
360+
logger.info("filterStartBlock: {}, currentBlockNum: {}, currentFilterIndex: {}, load done.",
361+
filterStartBlock, currentBlockNum, currentFilterIndex);
362+
return true;
363+
} catch (Exception e) {
364+
throw new RuntimeException(e);
365+
}
366+
}
367+
368+
private void writeProperties() {
369+
try (Writer w = Files.newBufferedWriter(this.cacheProperties, StandardCharsets.UTF_8)) {
370+
Properties properties = new Properties();
371+
properties.setProperty("filterStartBlock", String.valueOf(filterStartBlock));
372+
properties.setProperty("currentBlockNum", String.valueOf(currentBlockNum));
373+
properties.setProperty("currentFilterIndex", String.valueOf(currentFilterIndex));
374+
properties.store(w, "Generated by the application. PLEASE DO NOT EDIT! ");
375+
logger.info("filterStartBlock: {}, currentBlockNum: {}, currentFilterIndex: {}, write done.",
376+
filterStartBlock, currentBlockNum, currentFilterIndex);
377+
} catch (Exception e) {
378+
throw new RuntimeException(e);
379+
}
380+
}
381+
227382
@Override
228383
public TxCacheDB newInstance() {
229384
return new TxCacheDB(name, recentTransactionStore);

chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,6 @@ public synchronized void disable() {
284284

285285
@Override
286286
public void shutdown() {
287-
logger.info("******** Begin to pop revokingDb. ********");
288-
logger.info("******** Before revokingDb size: {}.", size);
289-
checkTmpStore.close();
290-
logger.info("******** End to pop revokingDb. ********");
291287
if (pruneCheckpointThread != null) {
292288
pruneCheckpointThread.shutdown();
293289
}

0 commit comments

Comments
 (0)