diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml new file mode 100644 index 00000000000..12aa565e15e --- /dev/null +++ b/.github/workflows/dependency-check.yml @@ -0,0 +1,60 @@ +name: "Dependency Check" + +on: + push: + branches: [ 'develop', 'master', 'release_**', 'feat/state_root_sync' ] + pull_request: + branches: [ 'develop', "release_**" , 'feat/state_root_sync' ] + schedule: + - cron: '25 6 * * *' + workflow_dispatch: + +jobs: + dependency-check: + name: Dependency Check + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Cache ODC data + uses: actions/cache@v3 + with: + path: ~/.dependency-check/data + key: ${{ runner.os }}-odc-data-${{ hashFiles('**/build.gradle') }} + restore-keys: | + ${{ runner.os }}-odc-data- + + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'temurin' + + - name: Gradlew build + run: ./gradlew --no-daemon -S -Dorg.gradle.dependency.verification=off -Dorg.gradle.warning.mode=none build -x test + + - name: Dependency Check + uses: dependency-check/Dependency-Check_Action@1.1.0 + env: + # actions/setup-java@v1 changes JAVA_HOME, so it needs to be reset to match the depcheck image + JAVA_HOME: /opt/jdk + with: + project: 'java-tron' + path: '.' + format: 'HTML' + out: 'reports' + args: > + --failOnCVSS 7 + --enableRetired + - name: Generate timestamp + run: echo "BUILD_TIMESTAMP=$(date -u +"%Y%m%d-%H%M%S")" >> $GITHUB_ENV + - name: Get Repository Name + run: echo "REPO_NAME=$(echo '${{ github.repository }}' | cut -d'/' -f2)" >> $GITHUB_ENV + - name: Upload report + if: always() + uses: actions/upload-artifact@v4 + with: + name: dependency-check-${{ env.REPO_NAME }}-${{ env.BUILD_TIMESTAMP }} + path: ${{github.workspace}}/reports diff --git a/.github/workflows/dependency-submission.yml b/.github/workflows/dependency-submission.yml new file mode 100644 index 00000000000..d8a5c8a416e --- /dev/null +++ b/.github/workflows/dependency-submission.yml @@ -0,0 +1,29 @@ +name: Dependency Submission + +on: + push: + branches: [ 'develop', 'master', 'release_**', 'feat/state_root_sync' ] + pull_request: + branches: [ 'develop', "release_**" , 'feat/state_root_sync' ] + + workflow_dispatch: + +permissions: + contents: write + +jobs: + dependency-submission: + runs-on: ubuntu-24.04-arm + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + - name: Generate and submit dependency graph + uses: gradle/actions/dependency-submission@v4 \ No newline at end of file diff --git a/README.md b/README.md index 0d0eeb6ef71..0f8b30704bf 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
CRITICAL: The returned WriteOptionsWrapper holds native resources + * and MUST be closed + * after use to prevent memory leaks. It is strongly recommended to use a try-with-resources + * statement. + * + *
Example of correct usage: + *
{@code
+ * try ( WriteOptionsWrapper readOptions = WriteOptionsWrapper.getInstance()) {
+ * // do something
+ * }
+ * }
+ *
+ * @return a new WriteOptionsWrapper that must be closed.
+ */
public static WriteOptionsWrapper getInstance() {
WriteOptionsWrapper wrapper = new WriteOptionsWrapper();
wrapper.level = new org.iq80.leveldb.WriteOptions();
@@ -23,4 +42,12 @@ public WriteOptionsWrapper sync(boolean bool) {
this.rocks.setSync(bool);
return this;
}
+
+ @Override
+ public void close() {
+ if (rocks != null) {
+ rocks.close();
+ }
+ // leveldb WriteOptions has no close method, and does not need to be closed
+ }
}
diff --git a/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java b/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java
index 506ecdcb6c7..c48800573e1 100644
--- a/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java
+++ b/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java
@@ -17,8 +17,9 @@
import static org.fusesource.leveldbjni.JniDBFactory.factory;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
-import java.io.File;
+import com.google.common.primitives.Bytes;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -30,26 +31,20 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
-
-import com.google.common.primitives.Bytes;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.iq80.leveldb.CompressionType;
import org.iq80.leveldb.DB;
import org.iq80.leveldb.DBIterator;
-import org.iq80.leveldb.Logger;
import org.iq80.leveldb.Options;
import org.iq80.leveldb.ReadOptions;
import org.iq80.leveldb.WriteBatch;
import org.iq80.leveldb.WriteOptions;
-import org.slf4j.LoggerFactory;
import org.tron.common.parameter.CommonParameter;
import org.tron.common.storage.WriteOptionsWrapper;
import org.tron.common.storage.metric.DbStat;
@@ -73,29 +68,11 @@ public class LevelDbDataSourceImpl extends DbStat implements DbSourceInterCRITICAL: The returned iterator holds native resources and MUST be closed + * after use to prevent memory leaks. It is strongly recommended to use a try-with-resources + * statement. + * + *
Example of correct usage: + *
{@code
+ * try (DBIterator iterator = db.iterator()) {
+ * while (iterator.hasNext()) {
+ * // ... process entry
+ * }
+ * }
+ * }
+ *
+ * @return a new database iterator that must be closed.
+ */
@Override
public org.tron.core.db.common.iterator.DBIterator iterator() {
return new StoreIterator(getDBIterator());
@@ -467,7 +455,7 @@ public StreamCRITICAL: The returned iterator holds native resources and MUST be closed + * after use to prevent memory leaks. It is strongly recommended to use a try-with-resources + * statement. + * + *
Example of correct usage: + *
{@code
+ * try (DBIterator iterator = db.iterator()) {
+ * while (iterator.hasNext()) {
+ * // ... process entry
+ * }
+ * }
+ * }
+ *
+ * @return a new database iterator that must be closed.
+ */
@Override
public org.tron.core.db.common.iterator.DBIterator iterator() {
- return new RockStoreIterator(getRocksIterator());
- }
-
- private void updateByBatchInner(MapCRITICAL: The returned iterator holds native resources and MUST be closed + * after use to prevent memory leaks. It is strongly recommended to use a try-with-resources + * statement. + * + *
Example of correct usage: + *
{@code
+ * try ( ReadOptions readOptions = new ReadOptions().setFillCache(false);
+ * RocksIterator iterator = getRocksIterator(readOptions)) {
+ * iterator.seekToFirst();
+ * // do something
+ * }
+ * }
+ *
+ * @return a new database iterator that must be closed.
+ */
+ private RocksIterator getRocksIterator(ReadOptions readOptions) {
+ throwIfNotAlive();
+ return database.newIterator(readOptions);
+ }
+
+ /**
+ * Returns an ReadOptions.
+ *
+ * CRITICAL: The returned ReadOptions holds native resources and MUST be closed + * after use to prevent memory leaks. It is strongly recommended to use a try-with-resources + * statement. + * + *
Example of correct usage: + *
{@code
+ * try (ReadOptions readOptions = getReadOptions();
+ * RocksIterator iterator = getRocksIterator(readOptions)) {
+ * iterator.seekToFirst();
+ * // do something
+ * }
+ * }
+ *
+ * @return a new database iterator that must be closed.
+ */
+ private ReadOptions getReadOptions() {
+ throwIfNotAlive();
+ return new ReadOptions().setFillCache(false);
}
public boolean deleteDbBakPath(String dir) {
@@ -545,7 +491,7 @@ public boolean deleteDbBakPath(String dir) {
@Override
public RocksDbDataSourceImpl newInstance() {
- return new RocksDbDataSourceImpl(parentPath, dataBaseName, RocksDbSettings.getSettings());
+ return new RocksDbDataSourceImpl(parentPath, dataBaseName);
}
diff --git a/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java b/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java
index 940a107a2ac..7179045ea7e 100644
--- a/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java
+++ b/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java
@@ -25,6 +25,7 @@
import org.tron.common.crypto.SignInterface;
import org.tron.common.crypto.SignUtils;
import org.tron.core.config.Parameter.ChainConstant;
+import org.tron.core.exception.TronError;
@Slf4j(topic = "app")
public class LocalWitnesses {
@@ -32,6 +33,7 @@ public class LocalWitnesses {
@Getter
private List