-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(toolkit): exclude historical balance DBs from lite snapshot #6690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
4f4f8dd
b9ffd79
8cea390
d6d0f20
53324d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| import com.google.common.primitives.Bytes; | ||
| import com.google.common.primitives.Ints; | ||
| import com.google.common.primitives.Longs; | ||
| import com.google.protobuf.ByteString; | ||
| import java.io.File; | ||
| import java.io.FileNotFoundException; | ||
| import java.io.IOException; | ||
|
|
@@ -30,6 +31,7 @@ | |
| import org.tron.plugins.utils.db.DBIterator; | ||
| import org.tron.plugins.utils.db.DbTool; | ||
| import org.tron.protos.Protocol; | ||
| import org.tron.protos.contract.BalanceContract; | ||
| import picocli.CommandLine; | ||
|
|
||
| @Slf4j(topic = "lite") | ||
|
|
@@ -57,13 +59,17 @@ public class DbLite implements Callable<Integer> { | |
| private static final String TRANSACTION_HISTORY_DB_NAME = "transactionHistoryStore"; | ||
| private static final String PROPERTIES_DB_NAME = "properties"; | ||
| private static final String TRANS_CACHE_DB_NAME = "trans-cache"; | ||
| private static final String BALANCE_TRACE_DB_NAME = "balance-trace"; | ||
| private static final String ACCOUNT_TRACE_DB_NAME = "account-trace"; | ||
|
|
||
| private static final List<String> archiveDbs = Arrays.asList( | ||
| BLOCK_DB_NAME, | ||
| BLOCK_INDEX_DB_NAME, | ||
| TRANS_DB_NAME, | ||
| TRANSACTION_RET_DB_NAME, | ||
| TRANSACTION_HISTORY_DB_NAME); | ||
| TRANSACTION_HISTORY_DB_NAME, | ||
| BALANCE_TRACE_DB_NAME, | ||
| ACCOUNT_TRACE_DB_NAME); | ||
|
|
||
| enum Operate { split, merge } | ||
|
|
||
|
|
@@ -522,24 +528,42 @@ private void trimExtraHistory(String liteDir, BlockNumInfo blockNumInfo) | |
| DBInterface blockDb = DbTool.getDB(liteDir, BLOCK_DB_NAME); | ||
| DBInterface transDb = DbTool.getDB(liteDir, TRANS_DB_NAME); | ||
| DBInterface tranRetDb = DbTool.getDB(liteDir, TRANSACTION_RET_DB_NAME); | ||
|
|
||
| DBInterface balanceTraceDb = DbTool.getDB(liteDir, BALANCE_TRACE_DB_NAME); | ||
| DBInterface accountTraceDb = DbTool.getDB(liteDir, ACCOUNT_TRACE_DB_NAME); | ||
|
|
||
| ProgressBar.wrap(LongStream.rangeClosed(start, end) | ||
| .boxed() | ||
| .sorted((a, b) -> Long.compare(b, a)), "trimHistory").forEach(n -> { | ||
| .sorted((a, b) -> Long.compare(b, a)), "trimHistory") | ||
| .map(ByteArray::fromLong).forEach(n -> { | ||
| try { | ||
| byte[] blockIdHash = blockIndexDb.get(ByteArray.fromLong(n)); | ||
| byte[] blockIdHash = blockIndexDb.get(n); | ||
| Protocol.Block block = Protocol.Block.parseFrom(blockDb.get(blockIdHash)); | ||
| // delete transactions | ||
| for (Protocol.Transaction e : block.getTransactionsList()) { | ||
| transDb.delete(DBUtils.getTransactionId(e).getBytes()); | ||
| } | ||
| // delete transaction result | ||
| tranRetDb.delete(ByteArray.fromLong(n)); | ||
| tranRetDb.delete(n); | ||
| // delete block | ||
| blockDb.delete(blockIdHash); | ||
| // delete block index | ||
| blockIndexDb.delete(ByteArray.fromLong(n)); | ||
| blockIndexDb.delete(n); | ||
| byte[] balanceTrace = balanceTraceDb.get(n); | ||
| if (balanceTrace != null) { | ||
| long blockNum = ByteArray.toLong(n); | ||
| // delete account trace: one row per (address, blockNum) touched in this block | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [SHOULD] This still reconstructs the Drift here is silent: deleting a non-existent key is a no-op, so if the key format ever changes, trim will stop deleting the intended rows and leave orphaned Please extract a shared helper in a lower-level module accessible to both sides, or at minimum add a contract test that keeps the store-side write path and the toolkit-side reconstruction in sync.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we at least add a one-line comment on both sides pointing at each other? Something like: |
||
| BalanceContract.BlockBalanceTrace.parseFrom(balanceTrace) | ||
| .getTransactionBalanceTraceList().stream() | ||
| .flatMap(tx -> tx.getOperationList().stream()) | ||
| .map(BalanceContract.TransactionBalanceTrace.Operation::getAddress) | ||
| .distinct() | ||
| .map(ByteString::toByteArray) | ||
| .map(address -> Bytes.concat(address, Longs.toByteArray( | ||
| blockNum ^ Long.MAX_VALUE))) | ||
| .forEach(accountTraceDb::delete); | ||
| // delete balance trace | ||
| balanceTraceDb.delete(n); | ||
| } | ||
| } catch (IOException e) { | ||
| throw new RuntimeException(e); | ||
| } | ||
|
|
@@ -570,7 +594,13 @@ private void mergeBak2Database(String liteDir, BlockNumInfo blockNumInfo) throws | |
| DBInterface bakDb = DbTool.getDB(bakDir.toString(), dbName); | ||
| DBInterface destDb = DbTool.getDB(liteDir, dbName); | ||
| try (DBIterator iterator = bakDb.iterator()) { | ||
| if (TRANS_DB_NAME.equals(dbName) || TRANSACTION_HISTORY_DB_NAME.equals(dbName)) { | ||
| // These DBs cannot be positioned by block number: | ||
| // TRANS_DB_NAME / TRANSACTION_HISTORY_DB_NAME are keyed by txId; | ||
| // ACCOUNT_TRACE_DB_NAME is keyed by address || (blockNum ^ Long.MAX_VALUE). | ||
| // Full replay is safe: the overlapping segment [0, historyMaxNum] is | ||
| // identical on both sides, so re-putting it is idempotent. | ||
| if (TRANS_DB_NAME.equals(dbName) || TRANSACTION_HISTORY_DB_NAME.equals(dbName) | ||
|
halibobo1205 marked this conversation as resolved.
|
||
| || ACCOUNT_TRACE_DB_NAME.equals(dbName)) { | ||
| iterator.seekToFirst(); | ||
| } else { | ||
| iterator.seek(head); | ||
|
halibobo1205 marked this conversation as resolved.
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package org.tron.plugins.rocksdb; | ||
|
|
||
| import java.io.IOException; | ||
| import org.junit.Test; | ||
| import org.tron.plugins.DbLiteTest; | ||
|
|
||
| public class DbLiteWithHistoryRocksDbTest extends DbLiteTest { | ||
|
|
||
| @Test | ||
| public void testToolsWithTrimHistoryV1() throws InterruptedException, IOException { | ||
| testTools("ROCKSDB", 1, true, true); | ||
|
halibobo1205 marked this conversation as resolved.
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package org.tron.plugins.rocksdb; | ||
|
|
||
| import java.io.IOException; | ||
| import org.junit.Test; | ||
| import org.tron.plugins.DbLiteTest; | ||
|
|
||
| public class DbLiteWithHistoryRocksDbV2Test extends DbLiteTest { | ||
|
|
||
| @Test | ||
| public void testToolsWithTrimHistoryV2() throws InterruptedException, IOException { | ||
| testTools("ROCKSDB", 2, true, true); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.