() {
+
+ @Override
+ protected int compareParameters(MediaType mediaType1, MediaType mediaType2) {
+ double quality1 = mediaType1.getQualityValue();
+ double quality2 = mediaType2.getQualityValue();
+ int qualityComparison = Double.compare(quality2, quality1);
+ if (qualityComparison != 0) {
+ return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3
+ }
+ return super.compareParameters(mediaType1, mediaType2);
+ }
+ };
+
+ static {
+ // Not using "valueOf' to avoid static init cost
+ ALL = new MediaType("*", "*");
+ APPLICATION_ATOM_XML = new MediaType("application", "atom+xml");
+ APPLICATION_CBOR = new MediaType("application", "cbor");
+ APPLICATION_FORM_URLENCODED = new MediaType("application", "x-www-form-urlencoded");
+ APPLICATION_GRAPHQL = new MediaType("application", "graphql+json");
+ APPLICATION_JSON = new MediaType("application", "json");
+ APPLICATION_JSON_UTF8 = new MediaType("application", "json", StandardCharsets.UTF_8);
+ APPLICATION_NDJSON = new MediaType("application", "x-ndjson");
+ APPLICATION_OCTET_STREAM = new MediaType("application", "octet-stream");
+ APPLICATION_PDF = new MediaType("application", "pdf");
+ APPLICATION_PROBLEM_JSON = new MediaType("application", "problem+json");
+ APPLICATION_PROBLEM_JSON_UTF8 = new MediaType("application", "problem+json",
+ StandardCharsets.UTF_8);
+ APPLICATION_PROBLEM_XML = new MediaType("application", "problem+xml");
+ APPLICATION_RSS_XML = new MediaType("application", "rss+xml");
+ APPLICATION_STREAM_JSON = new MediaType("application", "stream+json");
+ APPLICATION_XHTML_XML = new MediaType("application", "xhtml+xml");
+ APPLICATION_XML = new MediaType("application", "xml");
+ IMAGE_GIF = new MediaType("image", "gif");
+ IMAGE_JPEG = new MediaType("image", "jpeg");
+ IMAGE_PNG = new MediaType("image", "png");
+ MULTIPART_FORM_DATA = new MediaType("multipart", "form-data");
+ MULTIPART_MIXED = new MediaType("multipart", "mixed");
+ MULTIPART_RELATED = new MediaType("multipart", "related");
+ TEXT_EVENT_STREAM = new MediaType("text", "event-stream");
+ TEXT_HTML = new MediaType("text", "html");
+ TEXT_MARKDOWN = new MediaType("text", "markdown");
+ TEXT_PLAIN = new MediaType("text", "plain");
+ TEXT_XML = new MediaType("text", "xml");
+ }
+
+ /**
+ * Create a new {@code MediaType} for the given primary type.
+ * The {@linkplain #getSubtype() subtype} is set to "*", parameters empty.
+ *
+ * @param type the primary type
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ */
+ public MediaType(String type) {
+ super(type);
+ }
+
+ /**
+ * Create a new {@code MediaType} for the given primary type and subtype.
+ *
The parameters are empty.
+ *
+ * @param type the primary type
+ * @param subtype the subtype
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ */
+ public MediaType(String type, String subtype) {
+ super(type, subtype, Collections.emptyMap());
+ }
+
+ /**
+ * Create a new {@code MediaType} for the given type, subtype, and character set.
+ *
+ * @param type the primary type
+ * @param subtype the subtype
+ * @param charset the character set
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ */
+ public MediaType(String type, String subtype, Charset charset) {
+ super(type, subtype, charset);
+ }
+
+ /**
+ * Create a new {@code MediaType} for the given type, subtype, and quality value.
+ *
+ * @param type the primary type
+ * @param subtype the subtype
+ * @param qualityValue the quality value
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ */
+ public MediaType(String type, String subtype, double qualityValue) {
+ this(type, subtype, Collections.singletonMap(PARAM_QUALITY_FACTOR,
+ Double.toString(qualityValue)));
+ }
+
+ /**
+ * Copy-constructor that copies the type, subtype and parameters of the given
+ * {@code MediaType}, and allows to set the specified character set.
+ *
+ * @param other the other media type
+ * @param charset the character set
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ * @since 4.3
+ */
+ public MediaType(MediaType other, Charset charset) {
+ super(other, charset);
+ }
+
+ /**
+ * Copy-constructor that copies the type and subtype of the given {@code MediaType},
+ * and allows for different parameters.
+ *
+ * @param other the other media type
+ * @param parameters the parameters, may be {@code null}
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ */
+ public MediaType(MediaType other, @Nullable Map parameters) {
+ super(other.getType(), other.getSubtype(), parameters);
+ }
+
+
+ /**
+ * Create a new {@code MediaType} for the given type, subtype, and parameters.
+ *
+ * @param type the primary type
+ * @param subtype the subtype
+ * @param parameters the parameters, may be {@code null}
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ */
+ public MediaType(String type, String subtype, @Nullable Map parameters) {
+ super(type, subtype, parameters);
+ }
+
+ /**
+ * Create a new {@code MediaType} for the given {@link MimeType}.
+ * The type, subtype and parameters information is copied and {@code MediaType}-specific
+ * checks on parameters are performed.
+ *
+ * @param mimeType the MIME type
+ * @throws IllegalArgumentException if any of the parameters contain illegal characters
+ * @since 5.3
+ */
+ public MediaType(MimeType mimeType) {
+ super(mimeType);
+ getParameters().forEach(this::checkParameters);
+ }
+
+ /**
+ * Parse the given String value into a {@code MediaType} object,
+ * with this method name following the 'valueOf' naming convention
+ * (as supported by {@link org.springframework.core.convert.ConversionService}.
+ *
+ * @param value the string to parse
+ * @throws InvalidMediaTypeException if the media type value cannot be parsed
+ * @see #parseMediaType(String)
+ */
+ public static MediaType valueOf(String value) {
+ return parseMediaType(value);
+ }
+
+ /**
+ * Parse the given String into a single {@code MediaType}.
+ *
+ * @param mediaType the string to parse
+ * @return the media type
+ * @throws InvalidMediaTypeException if the media type value cannot be parsed
+ */
+ public static MediaType parseMediaType(String mediaType) {
+ MimeType type;
+ try {
+ type = MimeTypeUtils.parseMimeType(mediaType);
+ } catch (InvalidMimeTypeException ex) {
+ throw new InvalidMediaTypeException(ex);
+ }
+ try {
+ return new MediaType(type);
+ } catch (IllegalArgumentException ex) {
+ throw new InvalidMediaTypeException(mediaType, ex.getMessage());
+ }
+ }
+
+ /**
+ * Parse the comma-separated string into a list of {@code MediaType} objects.
+ * This method can be used to parse an Accept or Content-Type header.
+ *
+ * @param mediaTypes the string to parse
+ * @return the list of media types
+ * @throws InvalidMediaTypeException if the media type value cannot be parsed
+ */
+ public static List parseMediaTypes(@Nullable String mediaTypes) {
+ if (!StringUtils.hasLength(mediaTypes)) {
+ return Collections.emptyList();
+ }
+ // Avoid using java.util.stream.Stream in hot paths
+ List tokenizedTypes = MimeTypeUtils.tokenize(mediaTypes);
+ List result = new ArrayList<>(tokenizedTypes.size());
+ for (String type : tokenizedTypes) {
+ if (StringUtils.hasText(type)) {
+ result.add(parseMediaType(type));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Parse the given list of (potentially) comma-separated strings into a
+ * list of {@code MediaType} objects.
+ * This method can be used to parse an Accept or Content-Type header.
+ *
+ * @param mediaTypes the string to parse
+ * @return the list of media types
+ * @throws InvalidMediaTypeException if the media type value cannot be parsed
+ * @since 4.3.2
+ */
+ public static List parseMediaTypes(@Nullable List mediaTypes) {
+ if (CollectionUtils.isEmpty(mediaTypes)) {
+ return Collections.emptyList();
+ } else if (mediaTypes.size() == 1) {
+ return parseMediaTypes(mediaTypes.get(0));
+ } else {
+ List result = new ArrayList<>(8);
+ for (String mediaType : mediaTypes) {
+ result.addAll(parseMediaTypes(mediaType));
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Re-create the given mime types as media types.
+ *
+ * @since 5.0
+ */
+ public static List asMediaTypes(List mimeTypes) {
+ List mediaTypes = new ArrayList<>(mimeTypes.size());
+ for (MimeType mimeType : mimeTypes) {
+ mediaTypes.add(MediaType.asMediaType(mimeType));
+ }
+ return mediaTypes;
+ }
+
+ /**
+ * Re-create the given mime type as a media type.
+ *
+ * @since 5.0
+ */
+ public static MediaType asMediaType(MimeType mimeType) {
+ if (mimeType instanceof MediaType) {
+ return (MediaType) mimeType;
+ }
+ return new MediaType(mimeType.getType(), mimeType.getSubtype(), mimeType.getParameters());
+ }
+
+ /**
+ * Return a string representation of the given list of {@code MediaType} objects.
+ * This method can be used to for an {@code Accept} or {@code Content-Type} header.
+ *
+ * @param mediaTypes the media types to create a string representation for
+ * @return the string representation
+ */
+ public static String toString(Collection mediaTypes) {
+ return MimeTypeUtils.toString(mediaTypes);
+ }
+
+ /**
+ * Sorts the given list of {@code MediaType} objects by specificity.
+ * Given two media types:
+ *
+ * - if either media type has a {@linkplain #isWildcardType() wildcard type},
+ * then the media type without the wildcard is ordered before the other.
+ * - if the two media types have different {@linkplain #getType() types},
+ * then they are considered equal and remain their current order.
+ * - if either media type has a {@linkplain #isWildcardSubtype() wildcard subtype},
+ * then the media type without the wildcard is sorted before the other.
+ * - if the two media types have different {@linkplain #getSubtype() subtypes},
+ * then they are considered equal and remain their current order.
+ * - if the two media types have different {@linkplain #getQualityValue() quality value},
+ * then the media type with the highest quality value is ordered before the other.
+ * - if the two media types have a different amount of
+ * {@linkplain #getParameter(String) parameters}, then the
+ * media type with the most parameters is ordered before the other.
+ *
+ * For example:
+ *
audio/basic < audio/* < */*
+ * audio/* < audio/*;q=0.7; audio/*;q=0.3
+ * audio/basic;level=1 < audio/basic
+ * audio/basic == text/html
+ * audio/basic == audio/wave
+ *
+ * @param mediaTypes the list of media types to be sorted
+ * @see HTTP 1.1: Semantics
+ * and Content, section 5.3.2
+ */
+ public static void sortBySpecificity(List mediaTypes) {
+ Assert.notNull(mediaTypes, "'mediaTypes' must not be null");
+ if (mediaTypes.size() > 1) {
+ mediaTypes.sort(SPECIFICITY_COMPARATOR);
+ }
+ }
+
+ /**
+ * Sorts the given list of {@code MediaType} objects by quality value.
+ * Given two media types:
+ *
+ * - if the two media types have different {@linkplain #getQualityValue() quality value},
+ * then the media type with the highest quality value is ordered before the other.
+ * - if either media type has a {@linkplain #isWildcardType() wildcard type},
+ * then the media type without the wildcard is ordered before the other.
+ * - if the two media types have different {@linkplain #getType() types},
+ * then they are considered equal and remain their current order.
+ * - if either media type has a {@linkplain #isWildcardSubtype() wildcard subtype},
+ * then the media type without the wildcard is sorted before the other.
+ * - if the two media types have different {@linkplain #getSubtype() subtypes},
+ * then they are considered equal and remain their current order.
+ * - if the two media types have a different amount of
+ * {@linkplain #getParameter(String) parameters}, then the
+ * media type with the most parameters is ordered before the other.
+ *
+ *
+ * @param mediaTypes the list of media types to be sorted
+ * @see #getQualityValue()
+ */
+ public static void sortByQualityValue(List mediaTypes) {
+ Assert.notNull(mediaTypes, "'mediaTypes' must not be null");
+ if (mediaTypes.size() > 1) {
+ mediaTypes.sort(QUALITY_VALUE_COMPARATOR);
+ }
+ }
+
+ /**
+ * Sorts the given list of {@code MediaType} objects by specificity as the
+ * primary criteria and quality value the secondary.
+ *
+ * @see MediaType#sortBySpecificity(List)
+ * @see MediaType#sortByQualityValue(List)
+ */
+ public static void sortBySpecificityAndQuality(List mediaTypes) {
+ Assert.notNull(mediaTypes, "'mediaTypes' must not be null");
+ if (mediaTypes.size() > 1) {
+ mediaTypes.sort(
+ MediaType.SPECIFICITY_COMPARATOR.thenComparing(MediaType.QUALITY_VALUE_COMPARATOR));
+ }
+ }
+
+ @Override
+ protected void checkParameters(String parameter, String value) {
+ super.checkParameters(parameter, value);
+ if (PARAM_QUALITY_FACTOR.equals(parameter)) {
+ String unquotedValue = unquote(value);
+ double d = Double.parseDouble(unquotedValue);
+ Assert.isTrue(d >= 0D && d <= 1D,
+ () -> "Invalid quality value \"" + unquotedValue + "\": should be between 0.0 and 1.0");
+ }
+ }
+
+ /**
+ * Return the quality factor, as indicated by a {@code q} parameter, if any.
+ * Defaults to {@code 1.0}.
+ *
+ * @return the quality factor as double value
+ */
+ public double getQualityValue() {
+ String qualityFactor = getParameter(PARAM_QUALITY_FACTOR);
+ return (qualityFactor != null ? Double.parseDouble(unquote(qualityFactor)) : 1D);
+ }
+
+ /**
+ * Indicate whether this {@code MediaType} includes the given media type.
+ * For instance, {@code text/*} includes {@code text/plain} and {@code text/html},
+ * and {@code application/*+xml} includes {@code application/soap+xml}, etc.
+ * This method is not symmetric.
+ *
Simply calls {@link MimeType#includes(MimeType)} but declared with a
+ * {@code MediaType} parameter for binary backwards compatibility.
+ *
+ * @param other the reference media type with which to compare
+ * @return {@code true} if this media type includes the given media type;
+ * {@code false} otherwise
+ */
+ public boolean includes(@Nullable MediaType other) {
+ return super.includes(other);
+ }
+
+ /**
+ * Indicate whether this {@code MediaType} is compatible with the given media type.
+ *
For instance, {@code text/*} is compatible with {@code text/plain},
+ * {@code text/html}, and vice versa. In effect, this method is similar to
+ * {@link #includes}, except that it is symmetric.
+ *
Simply calls {@link MimeType#isCompatibleWith(MimeType)} but declared with a
+ * {@code MediaType} parameter for binary backwards compatibility.
+ *
+ * @param other the reference media type with which to compare
+ * @return {@code true} if this media type is compatible with the given media type;
+ * {@code false} otherwise
+ */
+ public boolean isCompatibleWith(@Nullable MediaType other) {
+ return super.isCompatibleWith(other);
+ }
+
+ /**
+ * Return a replica of this instance with the quality value of the given {@code MediaType}.
+ *
+ * @return the same instance if the given MediaType doesn't have a quality value,
+ * or a new one otherwise
+ */
+ public MediaType copyQualityValue(MediaType mediaType) {
+ if (!mediaType.getParameters().containsKey(PARAM_QUALITY_FACTOR)) {
+ return this;
+ }
+ Map params = new LinkedHashMap<>(getParameters());
+ params.put(PARAM_QUALITY_FACTOR, mediaType.getParameters().get(PARAM_QUALITY_FACTOR));
+ return new MediaType(this, params);
+ }
+
+ /**
+ * Return a replica of this instance with its quality value removed.
+ *
+ * @return the same instance if the media type doesn't contain a quality value,
+ * or a new one otherwise
+ */
+ public MediaType removeQualityValue() {
+ if (!getParameters().containsKey(PARAM_QUALITY_FACTOR)) {
+ return this;
+ }
+ Map params = new LinkedHashMap<>(getParameters());
+ params.remove(PARAM_QUALITY_FACTOR);
+ return new MediaType(this, params);
+ }
+
+}
\ No newline at end of file
diff --git a/framework/src/test/java/org/tron/common/EntityTest.java b/framework/src/test/java/org/tron/common/EntityTest.java
index 483475a453b..bbdc8631225 100644
--- a/framework/src/test/java/org/tron/common/EntityTest.java
+++ b/framework/src/test/java/org/tron/common/EntityTest.java
@@ -5,13 +5,16 @@
import static org.junit.Assert.assertTrue;
import com.google.common.collect.Lists;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.Before;
import org.junit.Test;
import org.tron.common.entity.NodeInfo;
import org.tron.common.entity.NodeInfo.MachineInfo;
import org.tron.common.entity.NodeInfo.MachineInfo.DeadLockThreadInfo;
+import org.tron.common.entity.PeerInfo;
public class EntityTest {
@@ -54,6 +57,9 @@ public void testDeadLockThreadInfo() {
@Test
public void testNodeInfo() {
+ List peerInfoList = new ArrayList<>();
+ peerInfoList.add(getDefaultPeerInfo());
+
NodeInfo nodeInfo = new NodeInfo();
nodeInfo.setTotalFlow(1L);
nodeInfo.setCheatWitnessInfoMap(new HashMap<>());
@@ -62,6 +68,39 @@ public void testNodeInfo() {
nodeInfo.setMachineInfo(machineInfo);
nodeInfo.setBlock("block");
nodeInfo.setSolidityBlock("solidityBlock");
+ nodeInfo.setPeerList(peerInfoList);
nodeInfo.transferToProtoEntity();
}
+
+ private PeerInfo getDefaultPeerInfo() {
+ PeerInfo peerInfo = new PeerInfo();
+ peerInfo.setAvgLatency(peerInfo.getAvgLatency());
+ peerInfo.setBlockInPorcSize(peerInfo.getBlockInPorcSize());
+ peerInfo.setConnectTime(peerInfo.getConnectTime());
+ peerInfo.setDisconnectTimes(peerInfo.getDisconnectTimes());
+ peerInfo.setHeadBlockTimeWeBothHave(peerInfo.getHeadBlockTimeWeBothHave());
+ peerInfo.setHeadBlockWeBothHave(peerInfo.getHeadBlockWeBothHave());
+ peerInfo.setHost("host");
+ peerInfo.setInFlow(peerInfo.getInFlow());
+ peerInfo.setLastBlockUpdateTime(peerInfo.getLastBlockUpdateTime());
+ peerInfo.setLastSyncBlock("last");
+ peerInfo.setLocalDisconnectReason("localDisconnectReason");
+ peerInfo.setNodeCount(peerInfo.getNodeCount());
+ peerInfo.setNodeId("nodeId");
+ peerInfo.setHeadBlockWeBothHave("headBlockWeBothHave");
+ peerInfo.setRemainNum(peerInfo.getRemainNum());
+ peerInfo.setRemoteDisconnectReason("remoteDisconnectReason");
+ peerInfo.setScore(peerInfo.getScore());
+ peerInfo.setPort(peerInfo.getPort());
+ peerInfo.setSyncFlag(peerInfo.isSyncFlag());
+ peerInfo.setNeedSyncFromPeer(peerInfo.isNeedSyncFromPeer());
+ peerInfo.setNeedSyncFromUs(peerInfo.isNeedSyncFromUs());
+ peerInfo.setSyncToFetchSize(peerInfo.getSyncToFetchSize());
+ peerInfo.setSyncToFetchSizePeekNum(peerInfo.getSyncToFetchSizePeekNum());
+ peerInfo.setSyncBlockRequestedSize(peerInfo.getSyncBlockRequestedSize());
+ peerInfo.setUnFetchSynNum(peerInfo.getUnFetchSynNum());
+ peerInfo.setActive(peerInfo.isActive());
+
+ return peerInfo;
+ }
}
diff --git a/framework/src/test/java/org/tron/common/ParameterTest.java b/framework/src/test/java/org/tron/common/ParameterTest.java
index b16be405f61..2f65189ac1c 100644
--- a/framework/src/test/java/org/tron/common/ParameterTest.java
+++ b/framework/src/test/java/org/tron/common/ParameterTest.java
@@ -129,6 +129,12 @@ public void testCommonParameter() {
assertEquals(10, parameter.getMaxConcurrentCallsPerConnection());
parameter.setFlowControlWindow(20);
assertEquals(20, parameter.getFlowControlWindow());
+ assertEquals(0, parameter.getRpcMaxRstStream());
+ parameter.setRpcMaxRstStream(10);
+ assertEquals(10, parameter.getRpcMaxRstStream());
+ assertEquals(0, parameter.getRpcSecondsPerWindow());
+ parameter.setRpcSecondsPerWindow(5);
+ assertEquals(5, parameter.getRpcSecondsPerWindow());
parameter.setMaxConnectionIdleInMillis(1000);
assertEquals(1000, parameter.getMaxConnectionIdleInMillis());
parameter.setBlockProducedTimeOut(500);
diff --git a/framework/src/test/java/org/tron/common/backup/BackupServerTest.java b/framework/src/test/java/org/tron/common/backup/BackupServerTest.java
index c40aca7e17a..18e264eead2 100644
--- a/framework/src/test/java/org/tron/common/backup/BackupServerTest.java
+++ b/framework/src/test/java/org/tron/common/backup/BackupServerTest.java
@@ -10,6 +10,7 @@
import org.junit.rules.Timeout;
import org.tron.common.backup.socket.BackupServer;
import org.tron.common.parameter.CommonParameter;
+import org.tron.common.utils.PublicMethod;
import org.tron.core.Constant;
import org.tron.core.config.args.Args;
@@ -26,7 +27,7 @@ public class BackupServerTest {
@Before
public void setUp() throws Exception {
Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF);
- CommonParameter.getInstance().setBackupPort(80);
+ CommonParameter.getInstance().setBackupPort(PublicMethod.chooseRandomPort());
List members = new ArrayList<>();
members.add("127.0.0.2");
CommonParameter.getInstance().setBackupMembers(members);
diff --git a/framework/src/test/java/org/tron/common/crypto/ECKeyTest.java b/framework/src/test/java/org/tron/common/crypto/ECKeyTest.java
index 4e7d45ee8d7..273672e8342 100644
--- a/framework/src/test/java/org/tron/common/crypto/ECKeyTest.java
+++ b/framework/src/test/java/org/tron/common/crypto/ECKeyTest.java
@@ -5,6 +5,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.tron.common.utils.client.utils.AbiUtil.generateOccupationConstantPrivateKey;
@@ -67,6 +68,11 @@ public void testFromPrivateKey() {
assertTrue(key.isPubKeyCanonical());
assertTrue(key.hasPrivKey());
assertArrayEquals(pubKey, key.getPubKey());
+
+ key = ECKey.fromPrivate((byte[]) null);
+ assertNull(key);
+ key = ECKey.fromPrivate(new byte[0]);
+ assertNull(key);
}
@Test(expected = IllegalArgumentException.class)
diff --git a/framework/src/test/java/org/tron/common/crypto/SM2KeyTest.java b/framework/src/test/java/org/tron/common/crypto/SM2KeyTest.java
index b84026d2085..87e4e14698c 100644
--- a/framework/src/test/java/org/tron/common/crypto/SM2KeyTest.java
+++ b/framework/src/test/java/org/tron/common/crypto/SM2KeyTest.java
@@ -4,6 +4,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.tron.common.utils.client.utils.AbiUtil.generateOccupationConstantPrivateKey;
@@ -64,6 +65,11 @@ public void testFromPrivateKey() {
assertTrue(key.isPubKeyCanonical());
assertTrue(key.hasPrivKey());
assertArrayEquals(pubKey, key.getPubKey());
+
+ key = SM2.fromPrivate((byte[]) null);
+ assertNull(key);
+ key = SM2.fromPrivate(new byte[0]);
+ assertNull(key);
}
@Test(expected = IllegalArgumentException.class)
diff --git a/framework/src/test/java/org/tron/common/logsfilter/NativeMessageQueueTest.java b/framework/src/test/java/org/tron/common/logsfilter/NativeMessageQueueTest.java
index e6bb407bb53..d356e43d66c 100644
--- a/framework/src/test/java/org/tron/common/logsfilter/NativeMessageQueueTest.java
+++ b/framework/src/test/java/org/tron/common/logsfilter/NativeMessageQueueTest.java
@@ -55,18 +55,19 @@ public void publishTrigger() {
public void startSubscribeThread() {
Thread thread = new Thread(() -> {
- ZContext context = new ZContext();
- ZMQ.Socket subscriber = context.createSocket(SocketType.SUB);
+ try (ZContext context = new ZContext()) {
+ ZMQ.Socket subscriber = context.createSocket(SocketType.SUB);
- Assert.assertEquals(true, subscriber.connect(String.format("tcp://localhost:%d", bindPort)));
- Assert.assertEquals(true, subscriber.subscribe(topic));
+ Assert.assertTrue(subscriber.connect(String.format("tcp://localhost:%d", bindPort)));
+ Assert.assertTrue(subscriber.subscribe(topic));
- while (!Thread.currentThread().isInterrupted()) {
- byte[] message = subscriber.recv();
- String triggerMsg = new String(message);
-
- Assert.assertEquals(true, triggerMsg.contains(dataToSend) || triggerMsg.contains(topic));
+ while (!Thread.currentThread().isInterrupted()) {
+ byte[] message = subscriber.recv();
+ String triggerMsg = new String(message);
+ Assert.assertTrue(triggerMsg.contains(dataToSend) || triggerMsg.contains(topic));
+ }
+ // ZMQ.Socket will be automatically closed when ZContext is closed
}
});
thread.start();
diff --git a/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java b/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java
index f400b3215ee..6fa2801c51f 100644
--- a/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java
+++ b/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java
@@ -19,9 +19,9 @@
import org.tron.core.Wallet;
import org.tron.core.exception.ContractExeException;
import org.tron.core.exception.ContractValidateException;
-import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.ReceiptCheckErrException;
import org.tron.core.exception.VMIllegalException;
+import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.services.NodeInfoService;
import org.tron.core.services.jsonrpc.TronJsonRpcImpl;
import org.tron.core.vm.config.ConfigLoader;
diff --git a/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java b/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java
index 3315005b7d2..b447af87bc2 100644
--- a/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java
+++ b/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java
@@ -1,6 +1,8 @@
package org.tron.common.runtime.vm;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.tron.core.config.Parameter.ChainConstant.FROZEN_PERIOD;
import java.util.List;
import java.util.Random;
@@ -13,12 +15,14 @@
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
+import org.mockito.Mockito;
import org.springframework.util.StringUtils;
import org.tron.common.BaseTest;
import org.tron.common.parameter.CommonParameter;
import org.tron.common.runtime.InternalTransaction;
import org.tron.common.utils.DecodeUtil;
import org.tron.core.Constant;
+import org.tron.core.capsule.AccountCapsule;
import org.tron.core.config.args.Args;
import org.tron.core.exception.ContractValidateException;
import org.tron.core.store.StoreFactory;
@@ -26,12 +30,14 @@
import org.tron.core.vm.JumpTable;
import org.tron.core.vm.Op;
import org.tron.core.vm.Operation;
+import org.tron.core.vm.OperationActions;
import org.tron.core.vm.OperationRegistry;
import org.tron.core.vm.VM;
import org.tron.core.vm.config.ConfigLoader;
import org.tron.core.vm.config.VMConfig;
import org.tron.core.vm.program.Program;
import org.tron.core.vm.program.invoke.ProgramInvokeMockImpl;
+import org.tron.core.vm.repository.Repository;
import org.tron.protos.Protocol;
@Slf4j
@@ -886,6 +892,12 @@ public void testSuicideCost() throws ContractValidateException {
Assert.assertEquals(25000, EnergyCost.getSuicideCost2(program));
invoke.getDeposit().createAccount(receiver2, Protocol.AccountType.Normal);
Assert.assertEquals(0, EnergyCost.getSuicideCost2(program));
+
+ byte[] receiver3 = generateRandomAddress();
+ program.stackPush(new DataWord(receiver3));
+ Assert.assertEquals(30000, EnergyCost.getSuicideCost3(program));
+ invoke.getDeposit().createAccount(receiver3, Protocol.AccountType.Normal);
+ Assert.assertEquals(5000, EnergyCost.getSuicideCost3(program));
}
@Test
@@ -911,6 +923,85 @@ public void testSuicideAction() throws ContractValidateException {
VMConfig.initAllowEnergyAdjustment(0);
}
+ @Test
+ public void testCanSuicide2() throws ContractValidateException {
+ VMConfig.initAllowTvmFreeze(1);
+ VMConfig.initAllowTvmFreezeV2(1);
+
+ byte[] contractAddr = Hex.decode("41471fd3ad3e9eeadeec4608b92d16ce6b500704cc");
+ invoke = new ProgramInvokeMockImpl(StoreFactory.getInstance(), new byte[0], contractAddr);
+
+ program = new Program(null, null, invoke,
+ new InternalTransaction(
+ Protocol.Transaction.getDefaultInstance(),
+ InternalTransaction.TrxType.TRX_UNKNOWN_TYPE));
+ program.getContractState().createAccount(
+ program.getContextAddress(), Protocol.AccountType.Contract);
+ Assert.assertTrue(program.canSuicide2());
+
+ long nowInMs =
+ program.getContractState().getDynamicPropertiesStore().getLatestBlockHeaderTimestamp();
+ long expireTime = nowInMs + FROZEN_PERIOD;
+ AccountCapsule owner = program.getContractState().getAccount(program.getContextAddress());
+ owner.setFrozenForEnergy(1000000, expireTime);
+ program.getContractState().updateAccount(program.getContextAddress(), owner);
+ Assert.assertFalse(program.canSuicide2());
+
+ VMConfig.initAllowTvmFreeze(0);
+ VMConfig.initAllowTvmFreezeV2(0);
+ }
+
+ @Test
+ public void testSuicideAction2() throws ContractValidateException {
+ byte[] contractAddr = Hex.decode("41471fd3ad3e9eeadeec4608b92d16ce6b500704cc");
+ invoke = new ProgramInvokeMockImpl(StoreFactory.getInstance(), new byte[0], contractAddr);
+ Assert.assertTrue(invoke.getDeposit().isNewContract(contractAddr));
+
+ program = new Program(null, null, invoke,
+ new InternalTransaction(
+ Protocol.Transaction.getDefaultInstance(),
+ InternalTransaction.TrxType.TRX_UNKNOWN_TYPE));
+
+ VMConfig.initAllowEnergyAdjustment(1);
+ VMConfig.initAllowTvmSelfdestructRestriction(1);
+ VMConfig.initAllowTvmFreeze(1);
+ VMConfig.initAllowTvmFreezeV2(1);
+ VMConfig.initAllowTvmCompatibleEvm(1);
+ VMConfig.initAllowTvmVote(1);
+ byte prePrefixByte = DecodeUtil.addressPreFixByte;
+ DecodeUtil.addressPreFixByte = Constant.ADD_PRE_FIX_BYTE_MAINNET;
+
+ program.stackPush(new DataWord(
+ dbManager.getAccountStore().getBlackhole().getAddress().toByteArray()));
+ OperationActions.suicideAction2(program);
+
+ Assert.assertEquals(1, program.getResult().getDeleteAccounts().size());
+
+
+ invoke = new ProgramInvokeMockImpl(StoreFactory.getInstance(), new byte[0], contractAddr);
+ program = new Program(null, null, invoke,
+ new InternalTransaction(
+ Protocol.Transaction.getDefaultInstance(),
+ InternalTransaction.TrxType.TRX_UNKNOWN_TYPE));
+ Program spyProgram = Mockito.spy(program);
+ Repository realContractState = program.getContractState();
+ Repository spyContractState = Mockito.spy(realContractState);
+ Mockito.when(spyContractState.isNewContract(any(byte[].class))).thenReturn(false);
+ Mockito.when(spyProgram.getContractState()).thenReturn(spyContractState);
+ spyProgram.suicide2(new DataWord(
+ dbManager.getAccountStore().getBlackhole().getAddress().toByteArray()));
+
+ Assert.assertEquals(0, spyProgram.getResult().getDeleteAccounts().size());
+
+ DecodeUtil.addressPreFixByte = prePrefixByte;
+ VMConfig.initAllowEnergyAdjustment(0);
+ VMConfig.initAllowTvmSelfdestructRestriction(0);
+ VMConfig.initAllowTvmFreeze(0);
+ VMConfig.initAllowTvmFreezeV2(0);
+ VMConfig.initAllowTvmCompatibleEvm(0);
+ VMConfig.initAllowTvmVote(0);
+ }
+
@Test
public void testVoteWitnessCost() throws ContractValidateException {
// Build stack environment, the stack from top to bottom is 0x00, 0x80, 0x00, 0x80
diff --git a/framework/src/test/java/org/tron/common/storage/CheckOrInitEngineTest.java b/framework/src/test/java/org/tron/common/storage/CheckOrInitEngineTest.java
new file mode 100644
index 00000000000..90aac10c0b6
--- /dev/null
+++ b/framework/src/test/java/org/tron/common/storage/CheckOrInitEngineTest.java
@@ -0,0 +1,263 @@
+package org.tron.common.storage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mockStatic;
+import static org.tron.core.db.common.DbSourceInter.ENGINE_FILE;
+import static org.tron.core.db.common.DbSourceInter.ENGINE_KEY;
+import static org.tron.core.db.common.DbSourceInter.LEVELDB;
+import static org.tron.core.db.common.DbSourceInter.ROCKSDB;
+import static org.tron.core.db.common.DbSourceInter.checkOrInitEngine;
+
+import com.google.common.base.Strings;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.tron.common.utils.FileUtil;
+import org.tron.common.utils.PropUtil;
+import org.tron.core.exception.TronError;
+
+
+public class CheckOrInitEngineTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private static final String ACCOUNT = "account";
+
+ @After
+ public void clearMocks() {
+ Mockito.clearAllCaches();
+ }
+
+ @Test
+ public void testLevelDbDetectedWhenExpectingRocksDb() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder(ACCOUNT).toString();
+ File currentFile = new File(dir, "CURRENT");
+ assertTrue(currentFile.createNewFile());
+ TronError.ErrCode errCode = TronError.ErrCode.ROCKSDB_INIT;
+ TronError exception = assertThrows(TronError.class, () ->
+ checkOrInitEngine(ROCKSDB, dir, errCode));
+ assertEquals("Cannot open LEVELDB database with ROCKSDB engine.",
+ exception.getMessage());
+ assertEquals(errCode, exception.getErrCode());
+ }
+ }
+
+ @Test
+ public void testCannotCreateDir() {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class)) {
+ String dir = "/invalid/path/that/cannot/be/created";
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(false);
+ TronError.ErrCode errCode = TronError.ErrCode.LEVELDB_INIT;
+ TronError exception = assertThrows(TronError.class, () ->
+ checkOrInitEngine(LEVELDB, dir, errCode));
+ assertEquals("Cannot create dir: " + dir + ".", exception.getMessage());
+ assertEquals(errCode, exception.getErrCode());
+ }
+ }
+
+ @Test
+ public void testCannotCreateEngineFile() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class)) {
+ String dir = temporaryFolder.newFolder().toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(false);
+ TronError.ErrCode errCode = TronError.ErrCode.ROCKSDB_INIT;
+ TronError exception = assertThrows(TronError.class, () ->
+ checkOrInitEngine(ROCKSDB, dir, errCode));
+
+ assertEquals("Cannot create file: " + engineFile + ".", exception.getMessage());
+ assertEquals(errCode, exception.getErrCode());
+ }
+ }
+
+ @Test
+ public void testCannotWritePropertyFile() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder().toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)).thenReturn(null);
+ strings.when(() -> Strings.isNullOrEmpty(null)).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.writeProperty(engineFile, ENGINE_KEY, ROCKSDB))
+ .thenReturn(false);
+
+ TronError.ErrCode errCode = TronError.ErrCode.LEVELDB_INIT;
+
+ TronError exception = assertThrows(TronError.class, () ->
+ checkOrInitEngine(ROCKSDB, dir, errCode));
+
+ assertEquals("Cannot write file: " + engineFile + ".", exception.getMessage());
+ assertEquals(errCode, exception.getErrCode());
+ }
+
+ }
+
+ @Test
+ public void testEngineMismatch() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder(ACCOUNT).toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)).thenReturn(LEVELDB);
+ strings.when(() -> Strings.isNullOrEmpty(LEVELDB)).thenReturn(false);
+
+ TronError.ErrCode errCode = TronError.ErrCode.ROCKSDB_INIT;
+
+ TronError exception = assertThrows(TronError.class, () ->
+ checkOrInitEngine(ROCKSDB, dir, errCode));
+
+ assertEquals("Cannot open LEVELDB database with ROCKSDB engine.",
+ exception.getMessage());
+ assertEquals(errCode, exception.getErrCode());
+ }
+ }
+
+ @Test
+ public void testSuccessfulFirstTimeInit() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder(ACCOUNT).toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY))
+ .thenReturn(null)
+ .thenReturn(LEVELDB);
+ strings.when(() -> Strings.isNullOrEmpty(null)).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.writeProperty(engineFile, ENGINE_KEY, LEVELDB))
+ .thenReturn(true);
+
+ TronError.ErrCode errCode = TronError.ErrCode.LEVELDB_INIT;
+ checkOrInitEngine(LEVELDB, dir, errCode);
+ }
+ }
+
+ @Test
+ public void testSuccessfulExistingEngine() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder(ACCOUNT).toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true);
+ propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)).thenReturn(ROCKSDB);
+ strings.when(() -> Strings.isNullOrEmpty(ROCKSDB)).thenReturn(false);
+
+ TronError.ErrCode errCode = TronError.ErrCode.ROCKSDB_INIT;
+ checkOrInitEngine(ROCKSDB, dir, errCode);
+ }
+ }
+
+ @Test
+ /**
+ * 000003.log CURRENT LOCK MANIFEST-000002
+ */
+ public void testCurrentFileExistsWithNoEngineFile() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder(ACCOUNT).toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+ File currentFile = new File(dir, "CURRENT");
+ assertTrue(currentFile.createNewFile());
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true);
+ propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)).thenReturn(LEVELDB);
+ strings.when(() -> Strings.isNullOrEmpty(LEVELDB)).thenReturn(false);
+
+ TronError.ErrCode errCode = TronError.ErrCode.LEVELDB_INIT;
+
+ checkOrInitEngine(LEVELDB, dir, errCode);
+ }
+ }
+
+ @Test
+ /**
+ * 000003.log CURRENT LOCK MANIFEST-000002 engine.properties(RocksDB)
+ */
+ public void testCurrentFileExistsEngineFileExists() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder(ACCOUNT).toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+
+ File currentFile = new File(dir, "CURRENT");
+ File engineFileObj = new File(engineFile);
+ assertTrue(currentFile.createNewFile());
+ assertTrue(engineFileObj.createNewFile());
+
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)).thenReturn(ROCKSDB);
+ strings.when(() -> Strings.isNullOrEmpty(ROCKSDB)).thenReturn(false);
+
+ TronError.ErrCode errCode = TronError.ErrCode.ROCKSDB_INIT;
+ checkOrInitEngine(ROCKSDB, dir, errCode);
+ }
+ }
+
+ @Test
+ public void testEmptyStringEngine() throws IOException {
+ try (MockedStatic fileUtil = mockStatic(FileUtil.class);
+ MockedStatic propUtil = mockStatic(PropUtil.class);
+ MockedStatic strings = mockStatic(Strings.class)) {
+
+ String dir = temporaryFolder.newFolder("account").toString();
+ String engineFile = Paths.get(dir, ENGINE_FILE).toString();
+
+ fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true);
+ fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY))
+ .thenReturn("").thenReturn(ROCKSDB);
+ strings.when(() -> Strings.isNullOrEmpty("")).thenReturn(true);
+
+ propUtil.when(() -> PropUtil.writeProperty(engineFile, ENGINE_KEY, ROCKSDB))
+ .thenReturn(true);
+ TronError.ErrCode errCode = TronError.ErrCode.ROCKSDB_INIT;
+ checkOrInitEngine(ROCKSDB, dir, errCode);
+ }
+ }
+}
diff --git a/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java b/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java
index bf18b988f19..8fc05746fc8 100644
--- a/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java
+++ b/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java
@@ -28,6 +28,7 @@
import com.google.common.collect.Sets;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -38,15 +39,24 @@
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
+import org.iq80.leveldb.DBException;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import org.rocksdb.RocksDB;
+import org.tron.common.parameter.CommonParameter;
+import org.tron.common.storage.WriteOptionsWrapper;
+import org.tron.common.storage.rocksdb.RocksDbDataSourceImpl;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.FileUtil;
+import org.tron.common.utils.PropUtil;
import org.tron.common.utils.PublicMethod;
+import org.tron.common.utils.StorageUtils;
import org.tron.core.Constant;
import org.tron.core.config.args.Args;
import org.tron.core.db2.common.WrappedByteArray;
@@ -73,6 +83,14 @@ public class LevelDbDataSourceImplTest {
private byte[] key5 = "00000005aa".getBytes();
private byte[] key6 = "00000006aa".getBytes();
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ static {
+ RocksDB.loadLibrary();
+ }
+
/**
* Release resources.
*/
@@ -94,7 +112,6 @@ public void testPutGet() {
dataSourceTest.resetDb();
String key1 = PublicMethod.getRandomPrivateKey();
byte[] key = key1.getBytes();
- dataSourceTest.initDB();
String value1 = "50000";
byte[] value = value1.getBytes();
@@ -102,8 +119,19 @@ public void testPutGet() {
assertNotNull(dataSourceTest.getData(key));
assertEquals(1, dataSourceTest.allKeys().size());
+ assertEquals(1, dataSourceTest.getTotal());
+ assertEquals(1, dataSourceTest.allValues().size());
assertEquals("50000", ByteArray.toStr(dataSourceTest.getData(key1.getBytes())));
+ dataSourceTest.deleteData(key);
+ assertNull(dataSourceTest.getData(key));
+ assertEquals(0, dataSourceTest.getTotal());
+ dataSourceTest.iterator().forEachRemaining(entry -> Assert.fail("iterator should be empty"));
+ dataSourceTest.stream().forEach(entry -> Assert.fail("stream should be empty"));
+ dataSourceTest.stat();
dataSourceTest.closeDB();
+ dataSourceTest.stat(); // stat again
+ exception.expect(DBException.class);
+ dataSourceTest.deleteData(key);
}
@Test
@@ -126,8 +154,6 @@ public void testReset() {
public void testupdateByBatchInner() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_updateByBatch");
- dataSource.initDB();
- dataSource.resetDb();
String key1 = PublicMethod.getRandomPrivateKey();
String value1 = "50000";
String key2 = PublicMethod.getRandomPrivateKey();
@@ -142,6 +168,23 @@ public void testupdateByBatchInner() {
assertEquals("50000", ByteArray.toStr(dataSource.getData(key1.getBytes())));
assertEquals("10000", ByteArray.toStr(dataSource.getData(key2.getBytes())));
assertEquals(2, dataSource.allKeys().size());
+
+ rows.clear();
+ rows.put(key1.getBytes(), null);
+ rows.put(key2.getBytes(), null);
+ dataSource.updateByBatch(rows, WriteOptionsWrapper.getInstance());
+ assertEquals(0, dataSource.allKeys().size());
+
+ rows.clear();
+ rows.put(key1.getBytes(), value1.getBytes());
+ rows.put(key2.getBytes(), null);
+ dataSource.updateByBatch(rows);
+ assertEquals("50000", ByteArray.toStr(dataSource.getData(key1.getBytes())));
+ assertEquals(1, dataSource.allKeys().size());
+ rows.clear();
+ rows.put(null, null);
+ exception.expect(RuntimeException.class);
+ dataSource.updateByBatch(rows);
dataSource.closeDB();
}
@@ -149,7 +192,6 @@ public void testupdateByBatchInner() {
public void testdeleteData() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_delete");
- dataSource.initDB();
String key1 = PublicMethod.getRandomPrivateKey();
byte[] key = key1.getBytes();
dataSource.deleteData(key);
@@ -163,8 +205,6 @@ public void testdeleteData() {
public void testallKeys() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_find_key");
- dataSource.initDB();
- dataSource.resetDb();
String key1 = PublicMethod.getRandomPrivateKey();
byte[] key = key1.getBytes();
@@ -187,7 +227,6 @@ public void testallKeys() {
@Test(timeout = 1000)
public void testLockReleased() {
- dataSourceTest.initDB();
// normal close
dataSourceTest.closeDB();
// closing already closed db.
@@ -202,8 +241,6 @@ public void testLockReleased() {
public void allKeysTest() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_allKeysTest_key");
- dataSource.initDB();
- dataSource.resetDb();
byte[] key = "0000000987b10fbb7f17110757321".getBytes();
byte[] value = "50000".getBytes();
@@ -216,7 +253,6 @@ public void allKeysTest() {
logger.info(ByteArray.toStr(keyOne));
});
assertEquals(2, dataSource.allKeys().size());
- dataSource.resetDb();
dataSource.closeDB();
}
@@ -242,26 +278,10 @@ private void putSomeKeyValue(LevelDbDataSourceImpl dataSource) {
dataSource.putData(key4, value4);
}
- @Test
- public void seekTest() {
- LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
- Args.getInstance().getOutputDirectory(), "test_seek_key");
- dataSource.initDB();
- dataSource.resetDb();
-
- putSomeKeyValue(dataSource);
- Assert.assertTrue(true);
- dataSource.resetDb();
- dataSource.closeDB();
- }
-
@Test
public void getValuesNext() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_getValuesNext_key");
- dataSource.initDB();
- dataSource.resetDb();
-
putSomeKeyValue(dataSource);
Set seekKeyLimitNext = dataSource.getValuesNext("0000000300".getBytes(), 2);
HashSet hashSet = Sets.newHashSet(ByteArray.toStr(value3), ByteArray.toStr(value4));
@@ -276,7 +296,6 @@ public void getValuesNext() {
public void testGetTotal() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_getTotal_key");
- dataSource.initDB();
dataSource.resetDb();
Map dataMapset = Maps.newHashMap();
@@ -293,8 +312,6 @@ public void testGetTotal() {
public void getKeysNext() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_getKeysNext_key");
- dataSource.initDB();
- dataSource.resetDb();
putSomeKeyValue(dataSource);
int limit = 2;
@@ -304,8 +321,6 @@ public void getKeysNext() {
for (int i = 0; i < limit; i++) {
Assert.assertArrayEquals(list.get(i), seekKeyLimitNext.get(i));
}
-
- dataSource.resetDb();
dataSource.closeDB();
}
@@ -313,9 +328,6 @@ public void getKeysNext() {
public void prefixQueryTest() {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_prefixQuery");
- dataSource.initDB();
- dataSource.resetDb();
-
putSomeKeyValue(dataSource);
// put a kv that will not be queried.
byte[] key7 = "0000001".getBytes();
@@ -341,23 +353,113 @@ public void prefixQueryTest() {
Assert.assertEquals(list.size(), result.size());
list.forEach(entry -> Assert.assertTrue(result.contains(entry)));
- dataSource.resetDb();
dataSource.closeDB();
}
@Test
public void initDbTest() {
makeExceptionDb("test_initDb");
- LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
- Args.getInstance().getOutputDirectory(), "test_initDb");
- TronError thrown = assertThrows(TronError.class, dataSource::initDB);
+ TronError thrown = assertThrows(TronError.class, () -> new LevelDbDataSourceImpl(
+ Args.getInstance().getOutputDirectory(), "test_initDb"));
assertEquals(TronError.ErrCode.LEVELDB_INIT, thrown.getErrCode());
}
+ @Test
+ public void testCheckOrInitEngine() {
+ String dir =
+ Args.getInstance().getOutputDirectory() + Args.getInstance().getStorage().getDbDirectory();
+ String enginePath = dir + File.separator + "test_engine" + File.separator + "engine.properties";
+ FileUtil.createDirIfNotExists(dir + File.separator + "test_engine");
+ FileUtil.createFileIfNotExists(enginePath);
+ PropUtil.writeProperty(enginePath, "ENGINE", "LEVELDB");
+ Assert.assertEquals("LEVELDB", PropUtil.readProperty(enginePath, "ENGINE"));
+
+ LevelDbDataSourceImpl dataSource;
+ dataSource = new LevelDbDataSourceImpl(dir, "test_engine");
+ dataSource.closeDB();
+
+ PropUtil.writeProperty(enginePath, "ENGINE", "ROCKSDB");
+ Assert.assertEquals("ROCKSDB", PropUtil.readProperty(enginePath, "ENGINE"));
+ try {
+ new LevelDbDataSourceImpl(dir, "test_engine");
+ } catch (TronError e) {
+ Assert.assertEquals("Cannot open ROCKSDB database with LEVELDB engine.", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testLevelDbOpenRocksDb() {
+ String name = "test_openRocksDb";
+ String output = Paths
+ .get(StorageUtils.getOutputDirectoryByDbName(name), CommonParameter
+ .getInstance().getStorage().getDbDirectory()).toString();
+ RocksDbDataSourceImpl rocksDb = new RocksDbDataSourceImpl(output, name);
+ rocksDb.putData(key1, value1);
+ rocksDb.closeDB();
+ exception.expectMessage("Cannot open ROCKSDB database with LEVELDB engine.");
+ new LevelDbDataSourceImpl(StorageUtils.getOutputDirectoryByDbName(name), name);
+ }
+
+ @Test
+ public void testNewInstance() {
+ dataSourceTest.closeDB();
+ LevelDbDataSourceImpl newInst = dataSourceTest.newInstance();
+ assertFalse(newInst.flush());
+ newInst.closeDB();
+ LevelDbDataSourceImpl empty = new LevelDbDataSourceImpl();
+ empty.setDBName("empty");
+ assertEquals("empty", empty.getDBName());
+ String name = "newInst2";
+ LevelDbDataSourceImpl newInst2 = new LevelDbDataSourceImpl(
+ StorageUtils.getOutputDirectoryByDbName(name),
+ name);
+ newInst2.closeDB();
+ }
+
+ @Test
+ public void testGetNext() {
+ LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
+ Args.getInstance().getOutputDirectory(), "test_getNext_key");
+ putSomeKeyValue(dataSource);
+ // case: normal
+ Map seekKvLimitNext = dataSource.getNext("0000000300".getBytes(), 2);
+ Map hashMap = Maps.newHashMap();
+ hashMap.put(ByteArray.toStr(key3), ByteArray.toStr(value3));
+ hashMap.put(ByteArray.toStr(key4), ByteArray.toStr(value4));
+ seekKvLimitNext.forEach((key, value) -> {
+ String keyStr = ByteArray.toStr(key);
+ Assert.assertTrue("getNext", hashMap.containsKey(keyStr));
+ Assert.assertEquals(ByteArray.toStr(value), hashMap.get(keyStr));
+ });
+ // case: targetKey greater than all existed keys
+ seekKvLimitNext = dataSource.getNext("0000000700".getBytes(), 2);
+ Assert.assertEquals(0, seekKvLimitNext.size());
+ // case: limit<=0
+ seekKvLimitNext = dataSource.getNext("0000000300".getBytes(), 0);
+ Assert.assertEquals(0, seekKvLimitNext.size());
+ dataSource.closeDB();
+ }
+
+ @Test
+ public void testGetlatestValues() {
+ LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
+ Args.getInstance().getOutputDirectory(), "test_getlatestValues_key");
+ putSomeKeyValue(dataSource);
+ // case: normal
+ Set seekKeyLimitNext = dataSource.getlatestValues(2);
+ Set hashSet = Sets.newHashSet(ByteArray.toStr(value5), ByteArray.toStr(value6));
+ seekKeyLimitNext.forEach(value -> {
+ Assert.assertTrue(hashSet.contains(ByteArray.toStr(value)));
+ });
+ // case: limit<=0
+ seekKeyLimitNext = dataSource.getlatestValues(0);
+ assertEquals(0, seekKeyLimitNext.size());
+ dataSource.closeDB();
+ }
+
private void makeExceptionDb(String dbName) {
LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_initDb");
- dataSource.initDB();
dataSource.closeDB();
FileUtil.saveData(dataSource.getDbPath().toString() + "/CURRENT",
"...", Boolean.FALSE);
diff --git a/framework/src/test/java/org/tron/common/storage/leveldb/RocksDbDataSourceImplTest.java b/framework/src/test/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImplTest.java
similarity index 71%
rename from framework/src/test/java/org/tron/common/storage/leveldb/RocksDbDataSourceImplTest.java
rename to framework/src/test/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImplTest.java
index c6fce30e3af..bf71b024541 100644
--- a/framework/src/test/java/org/tron/common/storage/leveldb/RocksDbDataSourceImplTest.java
+++ b/framework/src/test/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImplTest.java
@@ -1,4 +1,4 @@
-package org.tron.common.storage.leveldb;
+package org.tron.common.storage.rocksdb;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -10,6 +10,8 @@
import com.google.common.collect.Sets;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -24,13 +26,20 @@
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
-import org.tron.common.storage.rocksdb.RocksDbDataSourceImpl;
+import org.rocksdb.RocksDBException;
+import org.tron.common.error.TronDBException;
+import org.tron.common.parameter.CommonParameter;
+import org.tron.common.storage.WriteOptionsWrapper;
+import org.tron.common.storage.leveldb.LevelDbDataSourceImpl;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.FileUtil;
import org.tron.common.utils.PropUtil;
import org.tron.common.utils.PublicMethod;
+import org.tron.common.utils.StorageUtils;
import org.tron.core.config.args.Args;
import org.tron.core.db2.common.WrappedByteArray;
import org.tron.core.exception.TronError;
@@ -55,6 +64,9 @@ public class RocksDbDataSourceImplTest {
private byte[] key5 = "00000005aa".getBytes();
private byte[] key6 = "00000006aa".getBytes();
+ @Rule
+ public final ExpectedException expectedException = ExpectedException.none();
+
/**
* Release resources.
*/
@@ -76,7 +88,6 @@ public void testPutGet() {
dataSourceTest.resetDb();
String key1 = PublicMethod.getRandomPrivateKey();
byte[] key = key1.getBytes();
- dataSourceTest.initDB();
String value1 = "50000";
byte[] value = value1.getBytes();
@@ -84,8 +95,18 @@ public void testPutGet() {
assertNotNull(dataSourceTest.getData(key));
assertEquals(1, dataSourceTest.allKeys().size());
+ assertEquals(1, dataSourceTest.getTotal());
+ assertEquals(1, dataSourceTest.allValues().size());
assertEquals("50000", ByteArray.toStr(dataSourceTest.getData(key1.getBytes())));
+ dataSourceTest.deleteData(key);
+ assertNull(dataSourceTest.getData(key));
+ assertEquals(0, dataSourceTest.getTotal());
+ dataSourceTest.iterator().forEachRemaining(entry -> Assert.fail("iterator should be empty"));
+ dataSourceTest.stat();
dataSourceTest.closeDB();
+ dataSourceTest.stat(); // stat again
+ expectedException.expect(TronDBException.class);
+ dataSourceTest.deleteData(key);
}
@Test
@@ -108,8 +129,6 @@ public void testReset() {
public void testupdateByBatchInner() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_updateByBatch");
- dataSource.initDB();
- dataSource.resetDb();
String key1 = PublicMethod.getRandomPrivateKey();
String value1 = "50000";
String key2 = PublicMethod.getRandomPrivateKey();
@@ -124,6 +143,23 @@ public void testupdateByBatchInner() {
assertEquals("50000", ByteArray.toStr(dataSource.getData(key1.getBytes())));
assertEquals("10000", ByteArray.toStr(dataSource.getData(key2.getBytes())));
assertEquals(2, dataSource.allKeys().size());
+
+ rows.clear();
+ rows.put(key1.getBytes(), null);
+ rows.put(key2.getBytes(), null);
+ dataSource.updateByBatch(rows, WriteOptionsWrapper.getInstance());
+ assertEquals(0, dataSource.allKeys().size());
+
+ rows.clear();
+ rows.put(key1.getBytes(), value1.getBytes());
+ rows.put(key2.getBytes(), null);
+ dataSource.updateByBatch(rows);
+ assertEquals("50000", ByteArray.toStr(dataSource.getData(key1.getBytes())));
+ assertEquals(1, dataSource.allKeys().size());
+ rows.clear();
+ rows.put(null, null);
+ expectedException.expect(RuntimeException.class);
+ dataSource.updateByBatch(rows);
dataSource.closeDB();
}
@@ -131,7 +167,6 @@ public void testupdateByBatchInner() {
public void testdeleteData() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_delete");
- dataSource.initDB();
String key1 = PublicMethod.getRandomPrivateKey();
byte[] key = key1.getBytes();
dataSource.deleteData(key);
@@ -145,8 +180,6 @@ public void testdeleteData() {
public void testallKeys() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_find_key");
- dataSource.initDB();
- dataSource.resetDb();
String key1 = PublicMethod.getRandomPrivateKey();
byte[] key = key1.getBytes();
@@ -163,13 +196,11 @@ public void testallKeys() {
dataSource.putData(key2, value2);
assertEquals(2, dataSource.allKeys().size());
- dataSource.resetDb();
dataSource.closeDB();
}
@Test(timeout = 1000)
public void testLockReleased() {
- dataSourceTest.initDB();
// normal close
dataSourceTest.closeDB();
// closing already closed db.
@@ -184,8 +215,6 @@ public void testLockReleased() {
public void allKeysTest() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_allKeysTest_key");
- dataSource.initDB();
- dataSource.resetDb();
byte[] key = "0000000987b10fbb7f17110757321".getBytes();
byte[] value = "50000".getBytes();
@@ -198,7 +227,6 @@ public void allKeysTest() {
logger.info(ByteArray.toStr(keyOne));
});
assertEquals(2, dataSource.allKeys().size());
- dataSource.resetDb();
dataSource.closeDB();
}
@@ -224,31 +252,15 @@ private void putSomeKeyValue(RocksDbDataSourceImpl dataSource) {
dataSource.putData(key4, value4);
}
- @Test
- public void seekTest() {
- RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
- Args.getInstance().getOutputDirectory(), "test_seek_key");
- dataSource.initDB();
- dataSource.resetDb();
-
- putSomeKeyValue(dataSource);
- Assert.assertTrue(true);
- dataSource.resetDb();
- dataSource.closeDB();
- }
-
@Test
public void getValuesNext() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_getValuesNext_key");
- dataSource.initDB();
- dataSource.resetDb();
putSomeKeyValue(dataSource);
Set seekKeyLimitNext = dataSource.getValuesNext("0000000300".getBytes(), 2);
HashSet hashSet = Sets.newHashSet(ByteArray.toStr(value3), ByteArray.toStr(value4));
seekKeyLimitNext.forEach(
value -> Assert.assertTrue("getValuesNext", hashSet.contains(ByteArray.toStr(value))));
- dataSource.resetDb();
dataSource.closeDB();
}
@@ -264,23 +276,17 @@ public void testCheckOrInitEngine() {
RocksDbDataSourceImpl dataSource;
dataSource = new RocksDbDataSourceImpl(dir, "test_engine");
- dataSource.initDB();
Assert.assertNotNull(dataSource.getDatabase());
dataSource.closeDB();
- dataSource = null;
- System.gc();
PropUtil.writeProperty(enginePath, "ENGINE", "LEVELDB");
Assert.assertEquals("LEVELDB", PropUtil.readProperty(enginePath, "ENGINE"));
- dataSource = new RocksDbDataSourceImpl(dir, "test_engine");
+
try {
- dataSource.initDB();
- } catch (Exception e) {
- Assert.assertEquals(String.format("failed to check database: %s, engine do not match",
- "test_engine"),
- e.getMessage());
+ new RocksDbDataSourceImpl(dir, "test_engine");
+ } catch (TronError e) {
+ Assert.assertEquals("Cannot open LEVELDB database with ROCKSDB engine.", e.getMessage());
}
- Assert.assertNull(dataSource.getDatabase());
PropUtil.writeProperty(enginePath, "ENGINE", "ROCKSDB");
}
@@ -288,8 +294,6 @@ public void testCheckOrInitEngine() {
public void testGetNext() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_getNext_key");
- dataSource.initDB();
- dataSource.resetDb();
putSomeKeyValue(dataSource);
// case: normal
Map seekKvLimitNext = dataSource.getNext("0000000300".getBytes(), 2);
@@ -307,7 +311,6 @@ public void testGetNext() {
// case: limit<=0
seekKvLimitNext = dataSource.getNext("0000000300".getBytes(), 0);
Assert.assertEquals(0, seekKvLimitNext.size());
- dataSource.resetDb();
dataSource.closeDB();
}
@@ -315,8 +318,6 @@ public void testGetNext() {
public void testGetlatestValues() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_getlatestValues_key");
- dataSource.initDB();
- dataSource.resetDb();
putSomeKeyValue(dataSource);
// case: normal
Set seekKeyLimitNext = dataSource.getlatestValues(2);
@@ -327,7 +328,6 @@ public void testGetlatestValues() {
// case: limit<=0
seekKeyLimitNext = dataSource.getlatestValues(0);
assertEquals(0, seekKeyLimitNext.size());
- dataSource.resetDb();
dataSource.closeDB();
}
@@ -335,8 +335,6 @@ public void testGetlatestValues() {
public void getKeysNext() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_getKeysNext_key");
- dataSource.initDB();
- dataSource.resetDb();
putSomeKeyValue(dataSource);
int limit = 2;
@@ -346,8 +344,6 @@ public void getKeysNext() {
for (int i = 0; i < limit; i++) {
Assert.assertArrayEquals(list.get(i), seekKeyLimitNext.get(i));
}
-
- dataSource.resetDb();
dataSource.closeDB();
}
@@ -355,8 +351,6 @@ public void getKeysNext() {
public void prefixQueryTest() {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_prefixQuery");
- dataSource.initDB();
- dataSource.resetDb();
putSomeKeyValue(dataSource);
// put a kv that will not be queried.
@@ -383,23 +377,101 @@ public void prefixQueryTest() {
Assert.assertEquals(list.size(), result.size());
list.forEach(entry -> Assert.assertTrue(result.contains(entry)));
- dataSource.resetDb();
dataSource.closeDB();
}
@Test
public void initDbTest() {
makeExceptionDb("test_initDb");
- RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
- Args.getInstance().getOutputDirectory(), "test_initDb");
- TronError thrown = assertThrows(TronError.class, dataSource::initDB);
+ TronError thrown = assertThrows(TronError.class, () -> new RocksDbDataSourceImpl(
+ Args.getInstance().getOutputDirectory(), "test_initDb"));
assertEquals(TronError.ErrCode.ROCKSDB_INIT, thrown.getErrCode());
}
+ @Test
+ public void testRocksDbOpenLevelDb() {
+ String name = "test_openLevelDb";
+ String output = Paths
+ .get(StorageUtils.getOutputDirectoryByDbName(name), CommonParameter
+ .getInstance().getStorage().getDbDirectory()).toString();
+ LevelDbDataSourceImpl levelDb = new LevelDbDataSourceImpl(
+ StorageUtils.getOutputDirectoryByDbName(name), name);
+ levelDb.putData(key1, value1);
+ levelDb.closeDB();
+ expectedException.expectMessage("Cannot open LEVELDB database with ROCKSDB engine.");
+ new RocksDbDataSourceImpl(output, name);
+ }
+
+ @Test
+ public void testRocksDbOpenLevelDb2() {
+ String name = "test_openLevelDb2";
+ String output = Paths
+ .get(StorageUtils.getOutputDirectoryByDbName(name), CommonParameter
+ .getInstance().getStorage().getDbDirectory()).toString();
+ LevelDbDataSourceImpl levelDb = new LevelDbDataSourceImpl(
+ StorageUtils.getOutputDirectoryByDbName(name), name);
+ levelDb.putData(key1, value1);
+ levelDb.closeDB();
+ // delete engine.properties file to simulate the case that db.engine is not set.
+ File engineFile = Paths.get(output, name, "engine.properties").toFile();
+ if (engineFile.exists()) {
+ engineFile.delete();
+ }
+ Assert.assertFalse(engineFile.exists());
+
+ expectedException.expectMessage("Cannot open LEVELDB database with ROCKSDB engine.");
+ new RocksDbDataSourceImpl(output, name);
+ }
+
+ @Test
+ public void testNewInstance() {
+ dataSourceTest.closeDB();
+ RocksDbDataSourceImpl newInst = dataSourceTest.newInstance();
+ assertFalse(newInst.flush());
+ newInst.closeDB();
+ RocksDbDataSourceImpl empty = new RocksDbDataSourceImpl();
+ empty.setDBName("empty");
+ assertEquals("empty", empty.getDBName());
+ String output = Paths
+ .get(StorageUtils.getOutputDirectoryByDbName("newInst2"), CommonParameter
+ .getInstance().getStorage().getDbDirectory()).toString();
+ RocksDbDataSourceImpl newInst2 = new RocksDbDataSourceImpl(output, "newInst2");
+ newInst2.closeDB();
+ }
+
+ @Test
+ public void backupAndDelete() throws RocksDBException {
+ RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
+ Args.getInstance().getOutputDirectory(), "backupAndDelete");
+ putSomeKeyValue(dataSource);
+ Path dir = Paths.get(Args.getInstance().getOutputDirectory(), "backup");
+ String path = dir + File.separator;
+ FileUtil.createDirIfNotExists(path);
+ dataSource.backup(path);
+ File backDB = Paths.get(dir.toString(),dataSource.getDBName()).toFile();
+ Assert.assertTrue(backDB.exists());
+ dataSource.deleteDbBakPath(path);
+ Assert.assertFalse(backDB.exists());
+ dataSource.closeDB();
+ }
+
+ @Test
+ public void testGetTotal() {
+ RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
+ Args.getInstance().getOutputDirectory(), "test_getTotal_key");
+
+ Map dataMapset = Maps.newHashMap();
+ dataMapset.put(key1, value1);
+ dataMapset.put(key2, value2);
+ dataMapset.put(key3, value3);
+ dataMapset.forEach(dataSource::putData);
+ Assert.assertEquals(dataMapset.size(), dataSource.getTotal());
+ dataSource.closeDB();
+ }
+
private void makeExceptionDb(String dbName) {
RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl(
Args.getInstance().getOutputDirectory(), "test_initDb");
- dataSource.initDB();
dataSource.closeDB();
FileUtil.saveData(dataSource.getDbPath().toString() + "/CURRENT",
"...", Boolean.FALSE);
diff --git a/framework/src/test/java/org/tron/common/utils/FileUtilTest.java b/framework/src/test/java/org/tron/common/utils/FileUtilTest.java
index 126e0918520..c22e83760a1 100644
--- a/framework/src/test/java/org/tron/common/utils/FileUtilTest.java
+++ b/framework/src/test/java/org/tron/common/utils/FileUtilTest.java
@@ -67,6 +67,7 @@ public void testReadData_NormalFile() throws IOException {
try (FileWriter writer = new FileWriter(tempFile.toFile())) {
writer.write("Hello, World!");
}
+ tempFile.toFile().deleteOnExit();
char[] buffer = new char[1024];
int len = readData(tempFile.toString(), buffer);
diff --git a/framework/src/test/java/org/tron/common/utils/HashCodeTest.java b/framework/src/test/java/org/tron/common/utils/HashCodeTest.java
new file mode 100644
index 00000000000..36f9435c1aa
--- /dev/null
+++ b/framework/src/test/java/org/tron/common/utils/HashCodeTest.java
@@ -0,0 +1,23 @@
+package org.tron.common.utils;
+
+import java.util.Objects;
+import org.junit.Assert;
+import org.junit.Test;
+import org.tron.core.capsule.AccountCapsule;
+import org.tron.core.vm.repository.Type;
+import org.tron.core.vm.repository.Value;
+import org.tron.protos.Protocol;
+
+public class HashCodeTest {
+
+ @Test
+ public void test() {
+ Type type = new Type();
+ type.setType(Type.NORMAL);
+ Assert.assertEquals(Integer.valueOf(Type.NORMAL).hashCode(), type.hashCode());
+ Protocol.Account account = Protocol.Account.newBuilder().setBalance(100).build();
+ Value value = Value.create(new AccountCapsule(account.toByteArray()));
+ Assert.assertEquals(Integer.valueOf(
+ type.hashCode() + Objects.hashCode(account)).hashCode(), value.hashCode());
+ }
+}
diff --git a/framework/src/test/java/org/tron/common/utils/ObjectSizeUtilTest.java b/framework/src/test/java/org/tron/common/utils/ObjectSizeUtilTest.java
deleted file mode 100644
index c4c72991979..00000000000
--- a/framework/src/test/java/org/tron/common/utils/ObjectSizeUtilTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * java-tron is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * java-tron is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.tron.common.utils;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ObjectSizeUtilTest {
-
- @Test
- public void testGetObjectSize() {
-
- Person person = new Person();
- assertEquals(48, com.carrotsearch.sizeof.RamUsageEstimator.sizeOf(person));
- Person person1 = new Person(1, "tom", new int[]{});
- assertEquals(112, com.carrotsearch.sizeof.RamUsageEstimator.sizeOf(person1));
-
- Person person2 = new Person(1, "tom", new int[]{100});
- assertEquals(120, com.carrotsearch.sizeof.RamUsageEstimator.sizeOf(person2));
-
- Person person3 = new Person(1, "tom", new int[]{100, 100});
- assertEquals(120, com.carrotsearch.sizeof.RamUsageEstimator.sizeOf(person3));
- Person person4 = new Person(1, "tom", new int[]{100, 100, 100});
- assertEquals(128, com.carrotsearch.sizeof.RamUsageEstimator.sizeOf(person4));
- Person person5 = new Person(1, "tom", new int[]{100, 100, 100, 100});
- assertEquals(128, com.carrotsearch.sizeof.RamUsageEstimator.sizeOf(person5));
- Person person6 = new Person(1, "tom", new int[]{100, 100, 100, 100, 100});
- assertEquals(136, com.carrotsearch.sizeof.RamUsageEstimator.sizeOf(person6));
-
- }
-
- class Person {
-
- int age;
- String name;
- int[] scores;
-
- public Person() {
- }
-
- public Person(int age, String name, int[] scores) {
- this.age = age;
- this.name = name;
- this.scores = scores;
- }
- }
-
-}
diff --git a/framework/src/test/java/org/tron/common/utils/client/Configuration.java b/framework/src/test/java/org/tron/common/utils/client/Configuration.java
index 79dded303aa..fb253b9605b 100644
--- a/framework/src/test/java/org/tron/common/utils/client/Configuration.java
+++ b/framework/src/test/java/org/tron/common/utils/client/Configuration.java
@@ -4,7 +4,6 @@
import com.typesafe.config.ConfigFactory;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -28,12 +27,12 @@ public static Config getByPath(final String configurationPath) {
if (config == null) {
File configFile = new File(System.getProperty("user.dir") + '/' + configurationPath);
if (configFile.exists()) {
- try {
- config = ConfigFactory
- .parseReader(new InputStreamReader(new FileInputStream(configurationPath)));
+ try (FileInputStream fis = new FileInputStream(configurationPath);
+ InputStreamReader isr = new InputStreamReader(fis)) {
+ config = ConfigFactory.parseReader(isr);
logger.info("use user defined config file in current dir");
- } catch (FileNotFoundException e) {
- logger.error("load user defined config file exception: " + e.getMessage());
+ } catch (Exception e) {
+ logger.error("load user defined config file exception: {}", e.getMessage());
}
} else {
config = ConfigFactory.load(configurationPath);
diff --git a/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java b/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java
index a68bb616f11..030fbd80dea 100644
--- a/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java
+++ b/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java
@@ -2231,7 +2231,7 @@ public static void waitToProduceOneBlock(String httpNode) {
}
Integer nextBlockNum = 0;
Integer times = 0;
- while (nextBlockNum <= currentBlockNum + 1 && times++ <= 10) {
+ while (nextBlockNum < currentBlockNum + 1 && times++ <= 6) {
response = HttpMethed.getNowBlock(httpNode);
responseContent = HttpMethed.parseResponseContent(response);
if (responseContent.containsKey("block_header")) {
diff --git a/framework/src/test/java/org/tron/common/utils/client/utils/TransactionUtils.java b/framework/src/test/java/org/tron/common/utils/client/utils/TransactionUtils.java
index b6226d01aae..63ffe1b58ff 100644
--- a/framework/src/test/java/org/tron/common/utils/client/utils/TransactionUtils.java
+++ b/framework/src/test/java/org/tron/common/utils/client/utils/TransactionUtils.java
@@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+import static org.tron.core.capsule.TransactionCapsule.getBase64FromByteString;
import com.google.protobuf.ByteString;
import java.security.SignatureException;
@@ -116,20 +117,6 @@ public static byte[] getOwner(Transaction.Contract contract) {
}
}
- /**
- * constructor.
- */
-
- public static String getBase64FromByteString(ByteString sign) {
- byte[] r = sign.substring(0, 32).toByteArray();
- byte[] s = sign.substring(32, 64).toByteArray();
- byte v = sign.byteAt(64);
- if (v < 27) {
- v += 27; //revId -> v
- }
- ECDSASignature signature = ECDSASignature.fromComponents(r, s, v);
- return signature.toBase64();
- }
/*
* 1. check hash
diff --git a/framework/src/test/java/org/tron/core/CoreExceptionTest.java b/framework/src/test/java/org/tron/core/CoreExceptionTest.java
index 89feaba338c..f82b0efe326 100644
--- a/framework/src/test/java/org/tron/core/CoreExceptionTest.java
+++ b/framework/src/test/java/org/tron/core/CoreExceptionTest.java
@@ -29,11 +29,6 @@
import org.tron.core.exception.HeaderNotFound;
import org.tron.core.exception.HighFreqException;
import org.tron.core.exception.ItemNotFoundException;
-import org.tron.core.exception.JsonRpcInternalException;
-import org.tron.core.exception.JsonRpcInvalidParamsException;
-import org.tron.core.exception.JsonRpcInvalidRequestException;
-import org.tron.core.exception.JsonRpcMethodNotFoundException;
-import org.tron.core.exception.JsonRpcTooManyResultException;
import org.tron.core.exception.NonCommonBlockException;
import org.tron.core.exception.NonUniqueObjectException;
import org.tron.core.exception.P2pException;
@@ -56,6 +51,11 @@
import org.tron.core.exception.ValidateSignatureException;
import org.tron.core.exception.ZkProofValidateException;
import org.tron.core.exception.ZksnarkException;
+import org.tron.core.exception.jsonrpc.JsonRpcInternalException;
+import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
+import org.tron.core.exception.jsonrpc.JsonRpcInvalidRequestException;
+import org.tron.core.exception.jsonrpc.JsonRpcMethodNotFoundException;
+import org.tron.core.exception.jsonrpc.JsonRpcTooManyResultException;
public class CoreExceptionTest {
diff --git a/framework/src/test/java/org/tron/core/CreateCommonTransactionTest.java b/framework/src/test/java/org/tron/core/CreateCommonTransactionTest.java
deleted file mode 100644
index 4bcef1e148c..00000000000
--- a/framework/src/test/java/org/tron/core/CreateCommonTransactionTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.tron.core;
-
-import static org.tron.common.utils.client.WalletClient.decodeFromBase58Check;
-
-import com.google.protobuf.Any;
-import com.google.protobuf.ByteString;
-import io.grpc.ManagedChannelBuilder;
-import org.tron.api.GrpcAPI.TransactionExtention;
-import org.tron.api.WalletGrpc;
-import org.tron.api.WalletGrpc.WalletBlockingStub;
-import org.tron.protos.Protocol.Transaction;
-import org.tron.protos.Protocol.Transaction.Contract;
-import org.tron.protos.Protocol.Transaction.Contract.ContractType;
-import org.tron.protos.Protocol.Transaction.raw;
-import org.tron.protos.contract.StorageContract.UpdateBrokerageContract;
-
-public class CreateCommonTransactionTest {
-
- private static final String FULL_NODE = "127.0.0.1:50051";
-
- /**
- * for example create UpdateBrokerageContract
- */
- public static void testCreateUpdateBrokerageContract() {
- WalletBlockingStub walletStub = WalletGrpc
- .newBlockingStub(ManagedChannelBuilder.forTarget(FULL_NODE).usePlaintext().build());
- UpdateBrokerageContract.Builder updateBrokerageContract = UpdateBrokerageContract.newBuilder();
- updateBrokerageContract.setOwnerAddress(
- ByteString.copyFrom(decodeFromBase58Check("TN3zfjYUmMFK3ZsHSsrdJoNRtGkQmZLBLz")))
- .setBrokerage(10);
- Transaction.Builder transaction = Transaction.newBuilder();
- raw.Builder raw = Transaction.raw.newBuilder();
- Contract.Builder contract = Contract.newBuilder();
- contract.setType(ContractType.UpdateBrokerageContract)
- .setParameter(Any.pack(updateBrokerageContract.build()));
- raw.addContract(contract.build());
- transaction.setRawData(raw.build());
- TransactionExtention transactionExtention = walletStub
- .createCommonTransaction(transaction.build());
- System.out.println("Common UpdateBrokerage: " + transactionExtention);
- }
-
- public static void main(String[] args) {
- testCreateUpdateBrokerageContract();
- }
-
-}
diff --git a/framework/src/test/java/org/tron/core/ShieldWalletTest.java b/framework/src/test/java/org/tron/core/ShieldWalletTest.java
index f8d5db1a44c..6e35d600ce7 100644
--- a/framework/src/test/java/org/tron/core/ShieldWalletTest.java
+++ b/framework/src/test/java/org/tron/core/ShieldWalletTest.java
@@ -7,6 +7,7 @@
import java.math.BigInteger;
import javax.annotation.Resource;
import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.tron.api.GrpcAPI.PrivateParameters;
import org.tron.api.GrpcAPI.PrivateParametersWithoutAsk;
@@ -29,13 +30,14 @@ public class ShieldWalletTest extends BaseTest {
@Resource
private Wallet wallet;
- static {
- Args.setParam(new String[] {"-d", dbPath()}, Constant.TEST_CONF);
+ @BeforeClass
+ public static void init() {
+ Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF);
+ librustzcashInitZksnarkParams();
}
@Test
public void testCreateShieldedTransaction1() {
- librustzcashInitZksnarkParams();
String transactionStr1 = new String(ByteArray.fromHexString(
"0x7b0a20202020227472616e73706172656e745f66726f6d5f61646472657373223a202234433930413"
+ "73241433344414546324536383932343545463430303839443634314345414337373433323433414233"
@@ -68,7 +70,6 @@ public void testCreateShieldedTransaction1() {
@Test
public void testCreateShieldedTransaction2() {
- librustzcashInitZksnarkParams();
String transactionStr2 = new String(ByteArray.fromHexString(
"7b0a202020202261736b223a20223938666430333136376632333437623534643737323338343137663"
+ "6373038643537323939643938376362613838353564653037626532346236316464653064222c0a2020"
@@ -176,7 +177,6 @@ public void testCreateShieldedTransaction2() {
@Test
public void testCreateShieldedTransactionWithoutSpendAuthSig() {
- librustzcashInitZksnarkParams();
String transactionStr3 = new String(ByteArray.fromHexString(
"7b0a2020202022616b223a2022373161643638633466353035373464356164333735343863626538363"
+ "63031663732393662393161306362303535353733313462373830383437323730326465222c0a202020"
@@ -286,7 +286,6 @@ public void testCreateShieldedTransactionWithoutSpendAuthSig() {
@Test
public void testGetNewShieldedAddress() {
- librustzcashInitZksnarkParams();
try {
ShieldedAddressInfo shieldedAddressInfo = wallet.getNewShieldedAddress();
Assert.assertNotNull(shieldedAddressInfo);
@@ -297,8 +296,7 @@ public void testGetNewShieldedAddress() {
@Test
public void testCreateShieldedContractParameters() throws ContractExeException {
- librustzcashInitZksnarkParams();
- Args.getInstance().setFullNodeAllowShieldedTransactionArgs(true);
+ Args.getInstance().setAllowShieldedTransactionApi(true);
Wallet wallet1 = spy(new Wallet());
doReturn(BigInteger.valueOf(1).toByteArray())
@@ -340,8 +338,7 @@ public void testCreateShieldedContractParameters() throws ContractExeException {
@Test
public void testCreateShieldedContractParameters2() throws ContractExeException {
- librustzcashInitZksnarkParams();
- Args.getInstance().setFullNodeAllowShieldedTransactionArgs(true);
+ Args.getInstance().setAllowShieldedTransactionApi(true);
Wallet wallet1 = spy(new Wallet());
doReturn(BigInteger.valueOf(1).toByteArray())
@@ -416,8 +413,7 @@ public void testCreateShieldedContractParameters2() throws ContractExeException
@Test
public void testCreateShieldedContractParametersWithoutAsk() throws ContractExeException {
- librustzcashInitZksnarkParams();
- Args.getInstance().setFullNodeAllowShieldedTransactionArgs(true);
+ Args.getInstance().setAllowShieldedTransactionApi(true);
Wallet wallet1 = spy(new Wallet());
doReturn(BigInteger.valueOf(1).toByteArray())
diff --git a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java
index 2c97473b6c3..c2c4bfe3006 100644
--- a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java
+++ b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java
@@ -1,7 +1,5 @@
package org.tron.core;
-import static org.tron.core.zksnark.LibrustzcashTest.librustzcashInitZksnarkParams;
-
import com.google.protobuf.ByteString;
import java.math.BigInteger;
import java.util.Arrays;
@@ -12,7 +10,7 @@
import org.apache.commons.lang3.tuple.Pair;
import org.bouncycastle.util.encoders.Hex;
import org.junit.Assert;
-import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.tron.api.GrpcAPI;
@@ -68,7 +66,6 @@ public class ShieldedTRC20BuilderTest extends BaseTest {
SHIELDED_CONTRACT_ADDRESS = WalletClient.decodeFromBase58Check(SHIELDED_CONTRACT_ADDRESS_STR);
DEFAULT_OVK = ByteArray
.fromHexString("030c8c2bc59fb3eb8afb047a8ea4b028743d23e7d38c6fa30908358431e2314d");
- ZksnarkInitService.librustzcashInitZksnarkParams();
PUBLIC_TO_ADDRESS = WalletClient.decodeFromBase58Check(PUBLIC_TO_ADDRESS_STR);
}
@@ -76,8 +73,9 @@ public class ShieldedTRC20BuilderTest extends BaseTest {
VerifyTransferProof transferContract = new VerifyTransferProof();
VerifyBurnProof burnContract = new VerifyBurnProof();
- @Before
- public void before() {
+ @BeforeClass
+ public static void initZksnarkParams() {
+ ZksnarkInitService.librustzcashInitZksnarkParams();
}
@Ignore
@@ -2172,7 +2170,6 @@ public void createShieldedContractParametersWithoutAskForBurn1to2()
@Ignore
@Test
public void getTriggerInputForForMint() throws Exception {
- librustzcashInitZksnarkParams();
SpendingKey sk = SpendingKey.random();
ExpandedSpendingKey expsk = sk.expandedSpendingKey();
byte[] ovk = expsk.getOvk();
@@ -2241,7 +2238,6 @@ public void getTriggerInputForForMint() throws Exception {
public void testScanShieldedTRC20NotesByIvk() throws Exception {
int statNum = 1;
int endNum = 100;
- librustzcashInitZksnarkParams();
SpendingKey sk = SpendingKey.decode(priKey);
FullViewingKey fvk = sk.fullViewingKey();
byte[] ivk = fvk.inViewingKey().value;
@@ -2273,7 +2269,6 @@ public void testscanShieldedTRC20NotesByOvk() throws Exception {
public void isShieldedTRC20ContractNoteSpent() throws Exception {
int statNum = 9200;
int endNum = 9240;
- librustzcashInitZksnarkParams();
SpendingKey sk = SpendingKey.decode(priKey);
FullViewingKey fvk = sk.fullViewingKey();
byte[] ivk = fvk.inViewingKey().value;
@@ -2350,7 +2345,6 @@ private byte[] decodePath(byte[] encodedPath) {
private GrpcAPI.PrivateShieldedTRC20Parameters mintParams(String privKey,
long value, String contractAddr, byte[] rcm)
throws ZksnarkException, ContractValidateException {
- librustzcashInitZksnarkParams();
long fromAmount = value;
SpendingKey sk = SpendingKey.decode(privKey);
ExpandedSpendingKey expsk = sk.expandedSpendingKey();
diff --git a/framework/src/test/java/org/tron/core/WalletMockTest.java b/framework/src/test/java/org/tron/core/WalletMockTest.java
index 098ba9aee61..ab7ad7ba10c 100644
--- a/framework/src/test/java/org/tron/core/WalletMockTest.java
+++ b/framework/src/test/java/org/tron/core/WalletMockTest.java
@@ -835,7 +835,7 @@ public void testGetTriggerInputForShieldedTRC20Contract() {
CommonParameter commonParameterMock = mock(Args.class);
try (MockedStatic mockedStatic = mockStatic(CommonParameter.class)) {
when(CommonParameter.getInstance()).thenReturn(commonParameterMock);
- when(commonParameterMock.isFullNodeAllowShieldedTransactionArgs()).thenReturn(true);
+ when(commonParameterMock.isAllowShieldedTransactionApi()).thenReturn(true);
assertThrows(ZksnarkException.class, () -> {
wallet.getTriggerInputForShieldedTRC20Contract(triggerParam.build());
@@ -866,7 +866,7 @@ public void testGetTriggerInputForShieldedTRC20Contract1()
CommonParameter commonParameterMock = mock(Args.class);
try (MockedStatic mockedStatic = mockStatic(CommonParameter.class)) {
when(CommonParameter.getInstance()).thenReturn(commonParameterMock);
- when(commonParameterMock.isFullNodeAllowShieldedTransactionArgs()).thenReturn(true);
+ when(commonParameterMock.isAllowShieldedTransactionApi()).thenReturn(true);
GrpcAPI.BytesMessage reponse =
wallet.getTriggerInputForShieldedTRC20Contract(triggerParam.build());
@@ -1319,4 +1319,4 @@ public void testGetContractInfo1() throws Exception {
wallet.getContractInfo(bytesMessage);
assertNotNull(smartContractDataWrapper);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/test/java/org/tron/core/WalletTest.java b/framework/src/test/java/org/tron/core/WalletTest.java
index 831490fdca1..e388d3375c4 100644
--- a/framework/src/test/java/org/tron/core/WalletTest.java
+++ b/framework/src/test/java/org/tron/core/WalletTest.java
@@ -29,6 +29,8 @@
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
+
+import java.util.ArrayList;
import java.util.Arrays;
import javax.annotation.Resource;
import lombok.SneakyThrows;
@@ -66,9 +68,13 @@
import org.tron.core.capsule.TransactionCapsule;
import org.tron.core.capsule.TransactionInfoCapsule;
import org.tron.core.capsule.TransactionResultCapsule;
+import org.tron.core.capsule.VotesCapsule;
+import org.tron.core.capsule.WitnessCapsule;
import org.tron.core.config.args.Args;
+import org.tron.core.db2.core.Chainbase;
import org.tron.core.exception.ContractExeException;
import org.tron.core.exception.ContractValidateException;
+import org.tron.core.exception.MaintenanceUnavailableException;
import org.tron.core.exception.NonUniqueObjectException;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.core.utils.ProposalUtil.ProposalType;
@@ -851,6 +857,153 @@ public void testGetDelegatedResourceV2() {
}
}
+ @Test
+ public void testGetPaginatedNowWitnessList_Error() {
+ try {
+ // To avoid throw MaintenanceClearingException
+ dbManager.getChainBaseManager().getDynamicPropertiesStore().saveStateFlag(1);
+ wallet.getPaginatedNowWitnessList(0, 10);
+ Assert.fail("Should throw error when in maintenance period");
+ } catch (Exception e) {
+ Assert.assertTrue("Should throw MaintenanceClearingException",
+ e instanceof MaintenanceUnavailableException);
+ }
+
+ try {
+ Args.getInstance().setSolidityNode(true);
+ wallet.getPaginatedNowWitnessList(0, 10);
+ Args.getInstance().setSolidityNode(false);
+
+ dbManager.setCursor(Chainbase.Cursor.SOLIDITY);
+ wallet.getPaginatedNowWitnessList(0, 10);
+ dbManager.setCursor(Chainbase.Cursor.HEAD);
+ } catch (Exception e) {
+ Assert.assertFalse("Should not throw MaintenanceClearingException",
+ e instanceof MaintenanceUnavailableException);
+ }
+
+ dbManager.getChainBaseManager().getDynamicPropertiesStore().saveStateFlag(0);
+ }
+
+ @Test
+ public void testGetPaginatedNowWitnessList_CornerCase() {
+ try {
+ // To avoid throw MaintenanceClearingException
+ dbManager.getChainBaseManager().getDynamicPropertiesStore().saveStateFlag(0);
+
+ GrpcAPI.WitnessList witnessList = wallet.getPaginatedNowWitnessList(-100, 0);
+ Assert.assertTrue("Should return an empty witness list when offset is negative",
+ witnessList == null);
+
+ witnessList = wallet.getPaginatedNowWitnessList(100, 0);
+ Assert.assertTrue("Should return an empty witness list when limit is 0", witnessList == null);
+
+ String fakeWitnessAddressPrefix = "fake_witness";
+ int fakeNumberOfWitnesses = 1000 + 10;
+ // Mock additional witnesses with vote counts greater than 1000
+ for (int i = 0; i < fakeNumberOfWitnesses; i++) {
+ saveWitnessWith(fakeWitnessAddressPrefix + i, 200);
+ }
+
+ witnessList = wallet.getPaginatedNowWitnessList(0, 1000000);
+ // Check the returned witness list should contain 1000 witnesses with descending vote count
+ Assert.assertTrue("Witness list should contain 1000 witnesses",
+ witnessList.getWitnessesCount() == 1000);
+
+ // clean up, delete the fake witnesses
+ for (int i = 0; i < fakeNumberOfWitnesses; i++) {
+ chainBaseManager.getWitnessStore()
+ .delete(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + i).toByteArray());
+ }
+ } catch (MaintenanceUnavailableException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testGetPaginatedNowWitnessList() {
+ GrpcAPI.WitnessList witnessList = wallet.getWitnessList();
+ logger.info(witnessList.toString());
+
+ // iterate through the witness list and find the existing maximum vote count
+ long maxVoteCount = 0L;
+ for (Protocol.Witness witness : witnessList.getWitnessesList()) {
+ if (witness.getVoteCount() > maxVoteCount) {
+ maxVoteCount = witness.getVoteCount();
+ }
+ }
+ String fakeWitnessAddressPrefix = "fake_witness_address_for_paged_now_witness_list";
+ int fakeNumberOfWitnesses = 10;
+ // Mock additional witnesses with vote counts greater than the maximum
+ for (int i = 0; i < fakeNumberOfWitnesses; i++) {
+ saveWitnessWith(fakeWitnessAddressPrefix + i, maxVoteCount + 1000000L);
+ }
+
+ // Create a VotesCapsule to simulate the votes for the fake witnesses
+ VotesCapsule votesCapsule = new VotesCapsule(ByteString.copyFromUtf8(ACCOUNT_ADDRESS_ONE),
+ new ArrayList());
+ votesCapsule.addOldVotes(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + 0), 100L);
+ votesCapsule.addOldVotes(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + 1), 50L);
+ votesCapsule.addNewVotes(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + 2), 200L);
+ votesCapsule.addNewVotes(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + 3), 300L);
+ chainBaseManager.getVotesStore().put(votesCapsule.createDbKey(), votesCapsule);
+
+ logger.info("now request paginated witness list with 0 offset and 10 limit:");
+ GrpcAPI.WitnessList witnessList2 = null;
+ try {
+ // To avoid throw MaintenanceClearingException
+ dbManager.getChainBaseManager().getDynamicPropertiesStore().saveStateFlag(0);
+ witnessList2 = wallet.getPaginatedNowWitnessList(0, 10);
+ } catch (MaintenanceUnavailableException e) {
+ Assert.fail(e.getMessage());
+ }
+ // Check the returned witness list should contain 10 witnesses with descending vote count
+ Assert.assertTrue("Witness list should contain 10 witnesses",
+ witnessList2.getWitnessesCount() == 10);
+ // Check the first witness should have the maximum vote count
+ Assert.assertEquals("The first witness should have the maximum vote count",
+ fakeWitnessAddressPrefix + 3, witnessList2.getWitnesses(0).getAddress().toStringUtf8());
+ Assert.assertEquals(maxVoteCount + 1000300L, witnessList2.getWitnesses(0).getVoteCount());
+ // Check the second witness should have the second maximum vote count
+ Assert.assertEquals("The second witness", fakeWitnessAddressPrefix + 2,
+ witnessList2.getWitnesses(1).getAddress().toStringUtf8());
+ Assert.assertEquals(maxVoteCount + 1000200L, witnessList2.getWitnesses(1).getVoteCount());
+ // Check the last witness should have the least vote count
+ Assert.assertEquals("The tenth witness", fakeWitnessAddressPrefix + 0,
+ witnessList2.getWitnesses(9).getAddress().toStringUtf8());
+ Assert.assertEquals(maxVoteCount + 1000000L - 100L,
+ witnessList2.getWitnesses(9).getVoteCount());
+
+
+ logger.info("after paged");
+ GrpcAPI.WitnessList witnessList3 = wallet.getWitnessList();
+ // Check the witness list should remain unchanged after paged request
+ for (Protocol.Witness witness : witnessList3.getWitnessesList()) {
+ if (witness.getVoteCount() > maxVoteCount) {
+ Assert.assertTrue("Check the witness list should remain unchanged after paged request",
+ witness.getVoteCount() == maxVoteCount + 1000000L);
+ }
+ }
+
+ // clean up, delete the fake witnesses
+ for (int i = 0; i < fakeNumberOfWitnesses; i++) {
+ chainBaseManager.getWitnessStore()
+ .delete(ByteString.copyFromUtf8(fakeWitnessAddressPrefix + i).toByteArray());
+ }
+ chainBaseManager.getVotesStore().delete(votesCapsule.createDbKey());
+ Assert.assertTrue("Clean up the mocked witness data",
+ wallet.getWitnessList().getWitnessesCount() == witnessList.getWitnessesCount());
+
+ }
+
+ public void saveWitnessWith(String witnessAddress, long voteCount) {
+ WitnessCapsule witness = new WitnessCapsule(
+ Protocol.Witness.newBuilder()
+ .setAddress(ByteString.copyFromUtf8(witnessAddress)) // Convert String to ByteString
+ .setVoteCount(voteCount).build());
+ chainBaseManager.getWitnessStore().put(witness.getAddress().toByteArray(), witness);
+ }
+
@Test
public void testGetDelegatedResourceAccountIndexV2() {
dbManager.getDynamicPropertiesStore().saveUnfreezeDelayDays(1L);
diff --git a/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java
index b71ba432018..cb95194f3d3 100755
--- a/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java
+++ b/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java
@@ -85,7 +85,7 @@ public class ShieldedTransferActuatorTest extends BaseTest {
*/
@BeforeClass
public static void init() throws ZksnarkException {
- Args.setFullNodeAllowShieldedTransaction(true);
+ Args.getInstance().setAllowShieldedTransactionApi(true);
librustzcashInitZksnarkParams();
}
@@ -950,7 +950,7 @@ public void publicAddressAToShieldAddressNoToAddressFailure() {
*/
@Test
public void publicToShieldAddressAndShieldToPublicAddressWithZoreValueSuccess() {
- Args.setFullNodeAllowShieldedTransaction(true);
+ Args.getInstance().setAllowShieldedTransactionApi(true);
dbManager.getDynamicPropertiesStore().saveAllowShieldedTransaction(1);
long fee = dbManager.getDynamicPropertiesStore().getShieldedTransactionFee();
diff --git a/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java b/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java
index e8a1e862f54..d83f7f14e29 100644
--- a/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java
+++ b/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java
@@ -439,6 +439,8 @@ public void validateCheck() {
testAllowTvmBlobProposal();
+ testAllowTvmSelfdestructRestrictionProposal();
+
forkUtils.getManager().getDynamicPropertiesStore()
.statsByVersion(ForkBlockVersionEnum.ENERGY_LIMIT.getValue(), stats);
forkUtils.reset();
@@ -659,6 +661,58 @@ private void testAllowTvmBlobProposal() {
}
+ private void testAllowTvmSelfdestructRestrictionProposal() {
+ byte[] stats = new byte[27];
+ forkUtils.getManager().getDynamicPropertiesStore()
+ .statsByVersion(ForkBlockVersionEnum.VERSION_4_8_1.getValue(), stats);
+ try {
+ ProposalUtil.validator(dynamicPropertiesStore, forkUtils,
+ ProposalType.ALLOW_TVM_SELFDESTRUCT_RESTRICTION.getCode(), 1);
+ Assert.fail();
+ } catch (ContractValidateException e) {
+ Assert.assertEquals(
+ "Bad chain parameter id [ALLOW_TVM_SELFDESTRUCT_RESTRICTION]",
+ e.getMessage());
+ }
+
+ long maintenanceTimeInterval = forkUtils.getManager().getDynamicPropertiesStore()
+ .getMaintenanceTimeInterval();
+
+ long hardForkTime =
+ ((ForkBlockVersionEnum.VERSION_4_8_1.getHardForkTime() - 1) / maintenanceTimeInterval + 1)
+ * maintenanceTimeInterval;
+ forkUtils.getManager().getDynamicPropertiesStore()
+ .saveLatestBlockHeaderTimestamp(hardForkTime + 1);
+
+ stats = new byte[27];
+ Arrays.fill(stats, (byte) 1);
+ forkUtils.getManager().getDynamicPropertiesStore()
+ .statsByVersion(ForkBlockVersionEnum.VERSION_4_8_1.getValue(), stats);
+
+ // Should fail because the proposal value is invalid
+ try {
+ ProposalUtil.validator(dynamicPropertiesStore, forkUtils,
+ ProposalType.ALLOW_TVM_SELFDESTRUCT_RESTRICTION.getCode(), 2);
+ Assert.fail();
+ } catch (ContractValidateException e) {
+ Assert.assertEquals(
+ "This value[ALLOW_TVM_SELFDESTRUCT_RESTRICTION] is only allowed to be 1",
+ e.getMessage());
+ }
+
+ dynamicPropertiesStore.saveAllowTvmSelfdestructRestriction(1);
+ try {
+ ProposalUtil.validator(dynamicPropertiesStore, forkUtils,
+ ProposalType.ALLOW_TVM_SELFDESTRUCT_RESTRICTION.getCode(), 1);
+ Assert.fail();
+ } catch (ContractValidateException e) {
+ Assert.assertEquals(
+ "[ALLOW_TVM_SELFDESTRUCT_RESTRICTION] has been valid, no need to propose again",
+ e.getMessage());
+ }
+
+ }
+
@Test
public void blockVersionCheck() {
for (ForkBlockVersionEnum forkVersion : ForkBlockVersionEnum.values()) {
diff --git a/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java b/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java
index 089711219f8..770e2bd0ea5 100644
--- a/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java
+++ b/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java
@@ -2,6 +2,7 @@
import java.io.IOException;
import java.lang.reflect.Field;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
@@ -15,12 +16,15 @@
import org.tron.core.Constant;
import org.tron.core.config.args.Args;
import org.tron.core.db.TransactionStoreTest;
+import org.tron.core.vm.trace.Op;
import org.tron.core.vm.trace.OpActions;
import org.tron.core.vm.trace.OpActions.Action;
+import org.tron.core.vm.trace.ProgramTrace;
import org.tron.core.vm.trace.ProgramTraceListener;
@Slf4j(topic = "VM")
public class ProgramTraceListenerTest {
+
@ClassRule
public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -33,7 +37,7 @@ public class ProgramTraceListenerTest {
@BeforeClass
public static void init() throws IOException {
- Args.setParam(new String[]{"--output-directory",
+ Args.setParam(new String[] {"--output-directory",
temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF);
}
@@ -130,7 +134,6 @@ private void validateProgramTraceListener() {
Assert.assertFalse(e instanceof IllegalAccessException);
}
-
traceListener.resetActions();
try {
@@ -179,4 +182,25 @@ public void programTraceListenerTest() {
validateDisableTraceListener();
}
+ @Test
+ public void testGetSet() {
+ ProgramTrace programTrace = new ProgramTrace();
+ Op op = new Op();
+ List ops = new ArrayList<>();
+ ops.add(op);
+ programTrace.setOps(ops);
+ programTrace.setResult("result");
+ programTrace.setContractAddress("contractAddress");
+ programTrace.setError("error");
+ programTrace.result(new byte[] {});
+ programTrace.error(new Exception());
+ programTrace.getOps();
+ programTrace.getContractAddress();
+ programTrace.getError();
+ programTrace.getResult();
+ programTrace.toString();
+
+ Assert.assertTrue(true);
+ }
+
}
diff --git a/framework/src/test/java/org/tron/core/actuator/vm/SerializersTest.java b/framework/src/test/java/org/tron/core/actuator/vm/SerializersTest.java
new file mode 100644
index 00000000000..52ee1eeb937
--- /dev/null
+++ b/framework/src/test/java/org/tron/core/actuator/vm/SerializersTest.java
@@ -0,0 +1,12 @@
+package org.tron.core.actuator.vm;
+
+import org.junit.Test;
+import org.tron.core.vm.trace.Serializers;
+
+public class SerializersTest {
+
+ @Test
+ public void testSerializeFieldsOnly() {
+ Serializers.serializeFieldsOnly("testString", true);
+ }
+}
diff --git a/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java b/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java
index 3c86d893895..552a014a97b 100644
--- a/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java
+++ b/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java
@@ -134,7 +134,7 @@ public void testHasWitnessSignature() {
localWitnesses = new LocalWitnesses();
localWitnesses.setPrivateKeys(Arrays.asList(privateKey));
- localWitnesses.initWitnessAccountAddress(true);
+ localWitnesses.initWitnessAccountAddress(null, true);
Args.setLocalWitnesses(localWitnesses);
Assert.assertFalse(blockCapsule0.hasWitnessSignature());
diff --git a/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java b/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java
index 717c62b01a8..1f0be4b1f7c 100644
--- a/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java
+++ b/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java
@@ -138,12 +138,63 @@ public void testWithdraw() {
@Test
public void testStrictMath() {
long supply = 1_000_000_000_000_000_000L;
- ExchangeProcessor processor = new ExchangeProcessor(supply, false);
- long anotherTokenQuant = processor.exchange(4732214, 2202692725330L, 29218);
- processor = new ExchangeProcessor(supply, true);
- long result = processor.exchange(4732214, 2202692725330L, 29218);
- Assert.assertNotEquals(anotherTokenQuant, result);
+ long[][] testData = {
+ {4732214L, 2202692725330L, 29218L},
+ {5618633L, 556559904655L, 1L},
+ {9299554L, 1120271441185L, 7000L},
+ {62433133L, 12013267997895L, 100000L},
+ {64212664L, 725836766395L, 50000L},
+ {64126212L, 2895100109660L, 5000L},
+ {56459055L, 3288380567368L, 165000L},
+ {21084707L, 1589204008960L, 50000L},
+ {24120521L, 1243764649177L, 20000L},
+ {836877L, 212532333234L, 5293L},
+ {55879741L, 13424854054078L, 250000L},
+ {66388882L, 11300012790454L, 300000L},
+ {94470955L, 7941038150919L, 2000L},
+ {13613746L, 5012660712983L, 122L},
+ {71852829L, 5262251868618L, 396L},
+ {3857658L, 446109245044L, 20637L},
+ {35491863L, 3887393269796L, 100L},
+ {295632118L, 1265298439004L, 500000L},
+ {49320113L, 1692106302503L, 123267L},
+ {10966984L, 6222910652894L, 2018L},
+ {41634280L, 2004508994767L, 865L},
+ {10087714L, 6765558834714L, 1009L},
+ {42270078L, 210360843525L, 200000L},
+ {571091915L, 655011397250L, 2032520L},
+ {51026781L, 1635726339365L, 37L},
+ {61594L, 312318864132L, 500L},
+ {11616684L, 5875978057357L, 20L},
+ {60584529L, 1377717821301L, 78132L},
+ {29818073L, 3033545989651L, 182L},
+ {3855280L, 834647482043L, 16L},
+ {58310711L, 1431562205655L, 200000L},
+ {60226263L, 1386036785882L, 178226L},
+ {3537634L, 965771433992L, 225L},
+ {3760534L, 908700758784L, 328L},
+ {80913L, 301864126445L, 4L},
+ {3789271L, 901842209723L, 1L},
+ {4051904L, 843419481286L, 1005L},
+ {89141L, 282107742510L, 100L},
+ {90170L, 282854635378L, 26L},
+ {4229852L, 787503315944L, 137L},
+ {4259884L, 781975090197L, 295L},
+ {3627657L, 918682223700L, 34L},
+ {813519L, 457546358759L, 173L},
+ {89626L, 327856173057L, 27L},
+ {97368L, 306386489550L, 50L},
+ {93712L, 305866015731L, 4L},
+ {3281260L, 723656594544L, 40L},
+ {3442652L, 689908773685L, 18L},
+ };
+
+ for (long[] data : testData) {
+ ExchangeProcessor processor = new ExchangeProcessor(supply, false);
+ long anotherTokenQuant = processor.exchange(data[0], data[1], data[2]);
+ processor = new ExchangeProcessor(supply, true);
+ long result = processor.exchange(data[0], data[1], data[2]);
+ Assert.assertNotEquals(anotherTokenQuant, result);
+ }
}
-
-
}
diff --git a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java
index 4bb8e7e4909..fb19528b626 100644
--- a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java
+++ b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java
@@ -57,7 +57,8 @@ public void destroy() {
@Test
public void get() {
- Args.setParam(new String[] {"-c", Constant.TEST_CONF}, Constant.TESTNET_CONF);
+ Args.setParam(new String[] {"-c", Constant.TEST_CONF, "--keystore-factory"},
+ Constant.TESTNET_CONF);
CommonParameter parameter = Args.getInstance();
@@ -65,10 +66,10 @@ public void get() {
localWitnesses = new LocalWitnesses();
localWitnesses.setPrivateKeys(Arrays.asList(privateKey));
- localWitnesses.initWitnessAccountAddress(true);
+ localWitnesses.initWitnessAccountAddress(null, true);
Args.setLocalWitnesses(localWitnesses);
address = ByteArray.toHexString(Args.getLocalWitnesses()
- .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine()));
+ .getWitnessAccountAddress());
Assert.assertEquals(Constant.ADD_PRE_FIX_STRING_TESTNET, DecodeUtil.addressPreFixString);
Assert.assertEquals(0, parameter.getBackupPriority());
@@ -126,7 +127,9 @@ public void get() {
Assert.assertEquals(address,
ByteArray.toHexString(Args.getLocalWitnesses()
- .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine())));
+ .getWitnessAccountAddress()));
+
+ Assert.assertTrue(parameter.isKeystoreFactory());
}
@Test
diff --git a/framework/src/test/java/org/tron/core/config/args/LocalWitnessTest.java b/framework/src/test/java/org/tron/core/config/args/LocalWitnessTest.java
index 27d5effd6b1..15d64f3e074 100644
--- a/framework/src/test/java/org/tron/core/config/args/LocalWitnessTest.java
+++ b/framework/src/test/java/org/tron/core/config/args/LocalWitnessTest.java
@@ -15,24 +15,41 @@
package org.tron.core.config.args;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.security.SecureRandom;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.tron.common.utils.ByteArray;
import org.tron.common.utils.LocalWitnesses;
import org.tron.common.utils.PublicMethod;
+import org.tron.common.utils.StringUtil;
+import org.tron.core.Constant;
+import org.tron.core.exception.TronError;
+import org.tron.core.exception.TronError.ErrCode;
public class LocalWitnessTest {
private final LocalWitnesses localWitness = new LocalWitnesses();
private static final String PRIVATE_KEY = PublicMethod.getRandomPrivateKey();
+ @Rule
+ public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+
@Before
public void setLocalWitness() {
localWitness
.setPrivateKeys(
Lists.newArrayList(
- PRIVATE_KEY));
+ PRIVATE_KEY));
}
@Test
@@ -42,16 +59,16 @@ public void whenSetNullPrivateKey() {
Assert.assertNotNull(localWitness.getPublicKey());
}
- @Test
+ @Test(expected = TronError.class)
public void whenSetEmptyPrivateKey() {
localWitness.setPrivateKeys(Lists.newArrayList(""));
- Assert.assertNotNull(localWitness.getPrivateKey());
- Assert.assertNotNull(localWitness.getPublicKey());
+ fail("private key must be 64-bits hex string");
}
- @Test(expected = IllegalArgumentException.class)
+ @Test(expected = TronError.class)
public void whenSetBadFormatPrivateKey() {
localWitness.setPrivateKeys(Lists.newArrayList("a111"));
+ fail("private key must be 64-bits hex string");
}
@Test
@@ -65,6 +82,68 @@ public void whenSetPrefixPrivateKey() {
Assert.assertNotNull(localWitness.getPrivateKey());
}
+ @Test
+ public void testValidPrivateKey() {
+ LocalWitnesses localWitnesses = new LocalWitnesses();
+
+ try {
+ localWitnesses.addPrivateKeys(PRIVATE_KEY);
+ Assert.assertEquals(1, localWitnesses.getPrivateKeys().size());
+ Assert.assertEquals(PRIVATE_KEY, localWitnesses.getPrivateKeys().get(0));
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testValidPrivateKeyWithPrefix() {
+ LocalWitnesses localWitnesses = new LocalWitnesses();
+
+ try {
+ localWitnesses.addPrivateKeys("0x" + PRIVATE_KEY);
+ Assert.assertEquals(1, localWitnesses.getPrivateKeys().size());
+ Assert.assertEquals("0x" + PRIVATE_KEY, localWitnesses.getPrivateKeys().get(0));
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testInvalidPrivateKey() {
+ LocalWitnesses localWitnesses = new LocalWitnesses();
+ String expectedMessage = "private key must be 64 hex string";
+ assertTronError(localWitnesses, null, expectedMessage);
+ assertTronError(localWitnesses, "", expectedMessage);
+ assertTronError(localWitnesses, " ", expectedMessage);
+ assertTronError(localWitnesses, "11111", expectedMessage);
+ String expectedMessage2 = "private key must be hex string";
+ SecureRandom secureRandom = new SecureRandom();
+ byte[] keyBytes = new byte[31];
+ secureRandom.nextBytes(keyBytes);
+ final String privateKey = ByteArray.toHexString(keyBytes) + " ";
+ assertTronError(localWitnesses, privateKey, expectedMessage2);
+ final String privateKey2 = "xy" + ByteArray.toHexString(keyBytes);
+ assertTronError(localWitnesses, privateKey2, expectedMessage2);
+ }
+
+ private void assertTronError(LocalWitnesses localWitnesses, String privateKey,
+ String expectedMessage) {
+ TronError thrown = assertThrows(TronError.class,
+ () -> localWitnesses.addPrivateKeys(privateKey));
+ assertEquals(ErrCode.WITNESS_INIT, thrown.getErrCode());
+ assertTrue(thrown.getMessage().contains(expectedMessage));
+ }
+
+ @Test
+ public void testHexStringFormat() {
+ Assert.assertTrue(StringUtil.isHexadecimal("0123456789abcdefABCDEF"));
+ Assert.assertFalse(StringUtil.isHexadecimal(null));
+ Assert.assertFalse(StringUtil.isHexadecimal(""));
+ Assert.assertFalse(StringUtil.isHexadecimal("abc"));
+ Assert.assertFalse(StringUtil.isHexadecimal(" "));
+ Assert.assertFalse(StringUtil.isHexadecimal("123xyz"));
+ }
+
@Test
public void getPrivateKey() {
Assert.assertEquals(Lists
@@ -77,14 +156,34 @@ public void testConstructor() {
LocalWitnesses localWitnesses = new LocalWitnesses(PublicMethod.getRandomPrivateKey());
LocalWitnesses localWitnesses1 =
new LocalWitnesses(Lists.newArrayList(PublicMethod.getRandomPrivateKey()));
- localWitnesses.setWitnessAccountAddress(new byte[0]);
+ localWitnesses.initWitnessAccountAddress(new byte[0], true);
Assert.assertNotNull(localWitnesses1.getPublicKey());
LocalWitnesses localWitnesses2 = new LocalWitnesses();
Assert.assertNull(localWitnesses2.getPrivateKey());
Assert.assertNull(localWitnesses2.getPublicKey());
- localWitnesses2.initWitnessAccountAddress(true);
+ localWitnesses2.initWitnessAccountAddress(null, true);
LocalWitnesses localWitnesses3 = new LocalWitnesses();
- Assert.assertNotNull(localWitnesses3.getWitnessAccountAddress(true));
+ Assert.assertNull(localWitnesses3.getWitnessAccountAddress());
+ }
+
+ @Test
+ public void testLocalWitnessConfig() throws IOException {
+ Args.setParam(
+ new String[]{"--output-directory", temporaryFolder.newFolder().toString(), "-w", "--debug"},
+ "config-localtest.conf");
+ LocalWitnesses witness = Args.getLocalWitnesses();
+ Assert.assertNotNull(witness.getPrivateKey());
+ Assert.assertNotNull(witness.getWitnessAccountAddress());
+ }
+
+ @Test
+ public void testNullLocalWitnessConfig() throws IOException {
+ Args.setParam(
+ new String[]{"--output-directory", temporaryFolder.newFolder().toString(), "--debug"},
+ Constant.TEST_CONF);
+ LocalWitnesses witness = Args.getLocalWitnesses();
+ Assert.assertNull(witness.getPrivateKey());
+ Assert.assertNull(witness.getWitnessAccountAddress());
}
}
diff --git a/framework/src/test/java/org/tron/core/config/args/WitnessInitializerTest.java b/framework/src/test/java/org/tron/core/config/args/WitnessInitializerTest.java
new file mode 100644
index 00000000000..7364b1f9b3a
--- /dev/null
+++ b/framework/src/test/java/org/tron/core/config/args/WitnessInitializerTest.java
@@ -0,0 +1,268 @@
+package org.tron.core.config.args;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import org.bouncycastle.util.encoders.Hex;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockedStatic;
+import org.tron.common.crypto.SignInterface;
+import org.tron.common.parameter.CommonParameter;
+import org.tron.common.utils.ByteArray;
+import org.tron.common.utils.LocalWitnesses;
+import org.tron.common.utils.PublicMethod;
+import org.tron.common.utils.client.utils.Base58;
+import org.tron.core.Constant;
+import org.tron.core.exception.TronError;
+import org.tron.core.exception.TronError.ErrCode;
+import org.tron.keystore.Credentials;
+import org.tron.keystore.WalletUtils;
+
+public class WitnessInitializerTest {
+
+ private Config config;
+ private WitnessInitializer witnessInitializer;
+
+ private static final String privateKey = PublicMethod.getRandomPrivateKey();
+ private static final String address = Base58.encode58Check(
+ ByteArray.fromHexString(PublicMethod.getHexAddressByPrivateKey(privateKey)));
+ private static final String invalidAddress = "RJCzdnv88Hvqa2jB1C9dMmMYHr5DFdF2R3";
+
+ @Before
+ public void setUp() {
+ config = ConfigFactory.empty();
+ witnessInitializer = new WitnessInitializer(config);
+ }
+
+ @After
+ public void clear() {
+ Args.clearParam();
+ }
+
+ @Test
+ public void testInitLocalWitnessesEmpty() {
+ Args.PARAMETER.setWitness(false);
+
+ LocalWitnesses result = witnessInitializer.initLocalWitnesses();
+ assertNotNull(result);
+ assertTrue(result.getPrivateKeys().isEmpty());
+
+ Args.PARAMETER.setWitness(true);
+ LocalWitnesses localWitnesses = witnessInitializer.initLocalWitnesses();
+ assertTrue(localWitnesses.getPrivateKeys().isEmpty());
+
+ String configString = "localwitness = [] \n localwitnesskeystore = []";
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ localWitnesses = witnessInitializer.initLocalWitnesses();
+ assertTrue(localWitnesses.getPrivateKeys().isEmpty());
+ }
+
+ @Test
+ public void testTryInitFromCommandLine()
+ throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException,
+ InvocationTargetException {
+ Field privateKeyField = CommonParameter.class.getDeclaredField("privateKey");
+ privateKeyField.setAccessible(true);
+ privateKeyField.set(Args.getInstance(), "");
+
+ witnessInitializer = new WitnessInitializer(config);
+ Method method = WitnessInitializer.class.getDeclaredMethod(
+ "tryInitFromCommandLine");
+ method.setAccessible(true);
+ boolean result = (boolean) method.invoke(witnessInitializer);
+ assertFalse(result);
+
+ privateKeyField.set(Args.getInstance(), privateKey);
+ method.invoke(witnessInitializer);
+ result = (boolean) method.invoke(witnessInitializer);
+ assertTrue(result);
+
+ Field witnessAddress = CommonParameter.class.getDeclaredField("witnessAddress");
+ witnessAddress.setAccessible(true);
+ witnessAddress.set(Args.getInstance(), address);
+ result = (boolean) method.invoke(witnessInitializer);
+ assertTrue(result);
+
+ witnessAddress.set(Args.getInstance(), invalidAddress);
+ InvocationTargetException thrown = assertThrows(InvocationTargetException.class,
+ () -> method.invoke(witnessInitializer));
+ TronError targetException = (TronError) thrown.getTargetException();
+ assertEquals(ErrCode.WITNESS_INIT, targetException.getErrCode());
+ }
+
+ @Test
+ public void testTryInitFromConfig()
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ witnessInitializer = new WitnessInitializer(config);
+ Method method = WitnessInitializer.class.getDeclaredMethod(
+ "tryInitFromConfig");
+ method.setAccessible(true);
+ boolean result = (boolean) method.invoke(witnessInitializer);
+ assertFalse(result);
+
+ String configString = "localwitness = []";
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ result = (boolean) method.invoke(witnessInitializer);
+ assertFalse(result);
+
+ configString = "localwitness = [" + privateKey + "]";
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ result = (boolean) method.invoke(witnessInitializer);
+ assertTrue(result);
+
+ configString = "localWitnessAccountAddress = " + address + "\n"
+ + "localwitness = [\n" + privateKey + "]";
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ result = (boolean) method.invoke(witnessInitializer);
+ assertTrue(result);
+
+ configString = "localwitness = [\n" + privateKey + "\n" + privateKey + "]";
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ result = (boolean) method.invoke(witnessInitializer);
+ assertTrue(result);
+
+ configString = "localWitnessAccountAddress = " + invalidAddress + "\n"
+ + "localwitness = [\n" + privateKey + "]";
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ InvocationTargetException thrown = assertThrows(InvocationTargetException.class,
+ () -> method.invoke(witnessInitializer));
+ TronError targetException = (TronError) thrown.getTargetException();
+ assertEquals(ErrCode.WITNESS_INIT, targetException.getErrCode());
+
+ configString = "localWitnessAccountAddress = " + address + "\n"
+ + "localwitness = [\n" + privateKey + "\n" + privateKey + "]";
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ thrown = assertThrows(InvocationTargetException.class,
+ () -> method.invoke(witnessInitializer));
+ targetException = (TronError) thrown.getTargetException();
+ assertEquals(ErrCode.WITNESS_INIT, targetException.getErrCode());
+ }
+
+ @Test
+ public void testTryInitFromKeystore()
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
+ NoSuchFieldException {
+ witnessInitializer = new WitnessInitializer(config);
+ Method method = WitnessInitializer.class.getDeclaredMethod(
+ "tryInitFromKeystore");
+ method.setAccessible(true);
+ method.invoke(witnessInitializer);
+ Field localWitnessField = WitnessInitializer.class.getDeclaredField("localWitnesses");
+ localWitnessField.setAccessible(true);
+ LocalWitnesses localWitnesses = (LocalWitnesses) localWitnessField.get(witnessInitializer);
+ assertTrue(localWitnesses.getPrivateKeys().isEmpty());
+
+ String configString = "localwitnesskeystore = []";
+ Config emptyListConfig = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(emptyListConfig);
+ method.invoke(witnessInitializer);
+ localWitnesses = (LocalWitnesses) localWitnessField.get(witnessInitializer);
+ assertTrue(localWitnesses.getPrivateKeys().isEmpty());
+ }
+
+ @Test
+ public void testTryInitFromKeyStore2()
+ throws NoSuchFieldException, IllegalAccessException {
+ Args.PARAMETER.setWitness(true);
+ Config mockConfig = mock(Config.class);
+ when(mockConfig.hasPath(Constant.LOCAL_WITNESS_KEYSTORE)).thenReturn(false);
+ witnessInitializer = new WitnessInitializer(mockConfig);
+ witnessInitializer.initLocalWitnesses();
+ verify(mockConfig, never()).getStringList(anyString());
+
+ when(mockConfig.hasPath(Constant.LOCAL_WITNESS_KEYSTORE)).thenReturn(true);
+ when(mockConfig.getStringList(Constant.LOCAL_WITNESS_KEYSTORE)).thenReturn(new ArrayList<>());
+ witnessInitializer = new WitnessInitializer(mockConfig);
+ witnessInitializer.initLocalWitnesses();
+ verify(mockConfig, times(1)).getStringList(Constant.LOCAL_WITNESS_KEYSTORE);
+
+ List keystores = new ArrayList<>();
+ keystores.add("keystore1.json");
+ keystores.add("keystore2.json");
+ when(mockConfig.hasPath(Constant.LOCAL_WITNESS_KEYSTORE)).thenReturn(true);
+ when(mockConfig.getStringList(Constant.LOCAL_WITNESS_KEYSTORE)).thenReturn(keystores);
+
+ Field password = CommonParameter.class.getDeclaredField("password");
+ password.setAccessible(true);
+ password.set(Args.getInstance(), "password");
+
+ try (MockedStatic mockedWalletUtils = mockStatic(WalletUtils.class);
+ MockedStatic mockedByteArray = mockStatic(ByteArray.class)) {
+ // Mock WalletUtils.loadCredentials
+ Credentials credentials = mock(Credentials.class);
+ SignInterface signInterface = mock(SignInterface.class);
+ when(credentials.getSignInterface()).thenReturn(signInterface);
+ byte[] keyBytes = Hex.decode(privateKey);
+ when(signInterface.getPrivateKey()).thenReturn(keyBytes);
+ mockedWalletUtils.when(() -> WalletUtils.loadCredentials(anyString(), any(File.class)))
+ .thenReturn(credentials);
+ mockedByteArray.when(() -> ByteArray.toHexString(any())).thenReturn(privateKey);
+ mockedByteArray.when(() -> ByteArray.fromHexString(anyString())).thenReturn(keyBytes);
+
+ witnessInitializer = new WitnessInitializer(mockConfig);
+ Field localWitnessField = WitnessInitializer.class.getDeclaredField("localWitnesses");
+ localWitnessField.setAccessible(true);
+ localWitnessField.set(witnessInitializer, new LocalWitnesses(privateKey));
+ LocalWitnesses localWitnesses = witnessInitializer.initLocalWitnesses();
+ assertFalse(localWitnesses.getPrivateKeys().isEmpty());
+ }
+ }
+
+ @Test
+ public void testGetWitnessAddress()
+ throws InvocationTargetException, IllegalAccessException, NoSuchMethodException,
+ NoSuchFieldException {
+ witnessInitializer = new WitnessInitializer(config);
+ Method method = WitnessInitializer.class.getDeclaredMethod(
+ "getWitnessAddress");
+ method.setAccessible(true);
+ byte[] result = (byte[]) method.invoke(witnessInitializer);
+ assertNull(result);
+
+ String configString = "localWitnessAccountAddress = " + address;
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ Field localWitnessField = WitnessInitializer.class.getDeclaredField("localWitnesses");
+ localWitnessField.setAccessible(true);
+ localWitnessField.set(witnessInitializer, new LocalWitnesses(privateKey));
+ result = (byte[]) method.invoke(witnessInitializer);
+ assertNotNull(result);
+
+ configString = "localWitnessAccountAddress = " + invalidAddress;
+ config = ConfigFactory.parseString(configString);
+ witnessInitializer = new WitnessInitializer(config);
+ InvocationTargetException thrown = assertThrows(InvocationTargetException.class,
+ () -> method.invoke(witnessInitializer));
+ TronError targetException = (TronError) thrown.getTargetException();
+ assertEquals(ErrCode.WITNESS_INIT, targetException.getErrCode());
+ }
+}
diff --git a/framework/src/test/java/org/tron/core/db/AccountStoreTest.java b/framework/src/test/java/org/tron/core/db/AccountStoreTest.java
index 9249a3358dc..aab64df16c7 100755
--- a/framework/src/test/java/org/tron/core/db/AccountStoreTest.java
+++ b/framework/src/test/java/org/tron/core/db/AccountStoreTest.java
@@ -1,20 +1,29 @@
package org.tron.core.db;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
import com.google.protobuf.ByteString;
+import com.typesafe.config.Config;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
import org.tron.common.BaseTest;
import org.tron.common.utils.ByteArray;
import org.tron.core.Constant;
import org.tron.core.capsule.AccountCapsule;
import org.tron.core.config.args.Args;
import org.tron.core.db2.ISession;
+import org.tron.core.exception.TronError;
+import org.tron.core.net.peer.PeerManager;
import org.tron.core.store.AccountStore;
import org.tron.core.store.AssetIssueStore;
import org.tron.core.store.DynamicPropertiesStore;
@@ -61,6 +70,21 @@ public void init() {
init = true;
}
+ @Test
+ public void setAccountTest() throws Exception {
+ Field field = AccountStore.class.getDeclaredField("assertsAddress");
+ field.setAccessible(true);
+ field.set(AccountStore.class, new HashMap<>());
+ Config config = mock(Config.class);
+ Mockito.when(config.getObjectList("genesis.block.assets")).thenReturn(new ArrayList<>());
+ try {
+ AccountStore.setAccount(config);
+ Assert.fail();
+ } catch (Throwable e) {
+ Assert.assertTrue(e instanceof TronError);
+ }
+ }
+
@Test
public void get() {
//test get and has Method
diff --git a/framework/src/test/java/org/tron/core/db/ManagerTest.java b/framework/src/test/java/org/tron/core/db/ManagerTest.java
index db219377b74..b61941c7112 100755
--- a/framework/src/test/java/org/tron/core/db/ManagerTest.java
+++ b/framework/src/test/java/org/tron/core/db/ManagerTest.java
@@ -33,6 +33,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.tron.api.GrpcAPI;
import org.tron.common.application.TronApplicationContext;
import org.tron.common.crypto.ECKey;
import org.tron.common.runtime.RuntimeImpl;
@@ -52,7 +53,10 @@
import org.tron.core.capsule.AccountCapsule;
import org.tron.core.capsule.AssetIssueCapsule;
import org.tron.core.capsule.BlockCapsule;
+import org.tron.core.capsule.BytesCapsule;
import org.tron.core.capsule.TransactionCapsule;
+import org.tron.core.capsule.TransactionInfoCapsule;
+import org.tron.core.capsule.TransactionRetCapsule;
import org.tron.core.capsule.WitnessCapsule;
import org.tron.core.config.DefaultConfig;
import org.tron.core.config.Parameter;
@@ -136,7 +140,7 @@ public void init() throws IOException {
localWitnesses = new LocalWitnesses();
localWitnesses.setPrivateKeys(Arrays.asList(privateKey));
- localWitnesses.initWitnessAccountAddress(true);
+ localWitnesses.initWitnessAccountAddress(null, true);
Args.setLocalWitnesses(localWitnesses);
blockCapsule2 =
@@ -1233,6 +1237,47 @@ public void testExpiration() {
}
+ @Test
+ public void testGetTransactionInfoByBlockNum() throws Exception {
+
+ Transaction transaction = Protocol.Transaction.newBuilder()
+ .addSignature(ByteString.copyFrom(new byte[1])).build();
+ TransactionCapsule transactionCapsule = new TransactionCapsule(transaction);
+
+ Protocol.BlockHeader.raw raw = Protocol.BlockHeader.raw.newBuilder().setNumber(1000L).build();
+ Protocol.BlockHeader header = Protocol.BlockHeader.newBuilder().setRawData(raw).build();
+ Block block = Block.newBuilder().setBlockHeader(header).addTransactions(transaction).build();
+
+ Protocol.TransactionInfo info = Protocol.TransactionInfo.newBuilder()
+ .setBlockNumber(1000L).build();
+
+ BlockCapsule blockCapsule = new BlockCapsule(block);
+ byte[] blockId = new BlockCapsule(block).getBlockId().getBytes();
+ dbManager.getBlockIndexStore().put(ByteArray.fromLong(1000L), new BytesCapsule(blockId));
+ dbManager.getBlockStore().put(blockId, blockCapsule);
+ dbManager.getTransactionHistoryStore().put(transactionCapsule.getTransactionId().getBytes(),
+ new TransactionInfoCapsule(info));
+
+ GrpcAPI.TransactionInfoList transactionInfoList = dbManager.getTransactionInfoByBlockNum(1000L);
+
+ Assert.assertEquals(1, transactionInfoList.getTransactionInfoCount());
+ Assert.assertEquals(1, transactionInfoList.getTransactionInfoList().size());
+
+ Protocol.TransactionRet ret = Protocol.TransactionRet.newBuilder()
+ .addTransactioninfo(info)
+ .addTransactioninfo(info).build();
+
+ TransactionRetCapsule transactionRetCapsule = new TransactionRetCapsule(ret.toByteArray());
+
+ dbManager.getTransactionRetStore()
+ .put(ByteArray.fromLong(1000L), transactionRetCapsule);
+
+ transactionInfoList = dbManager.getTransactionInfoByBlockNum(1000L);
+
+ Assert.assertEquals(2, transactionInfoList.getTransactionInfoCount());
+ Assert.assertEquals(2, transactionInfoList.getTransactionInfoList().size());
+ }
+
@Test
public void blockTrigger() {
Manager manager = spy(new Manager());
diff --git a/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java b/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java
index 420b54525e4..f563203b71a 100644
--- a/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java
+++ b/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java
@@ -57,7 +57,7 @@ private void initLocalWitness() {
String randomPrivateKey = PublicMethod.getRandomPrivateKey();
LocalWitnesses localWitnesses = new LocalWitnesses();
localWitnesses.setPrivateKeys(Arrays.asList(randomPrivateKey));
- localWitnesses.initWitnessAccountAddress(true);
+ localWitnesses.initWitnessAccountAddress(null, true);
Args.setLocalWitnesses(localWitnesses);
}
@@ -85,7 +85,7 @@ public void testExpireTransaction() {
TransferContract transferContract = TransferContract.newBuilder()
.setAmount(1L)
.setOwnerAddress(ByteString.copyFrom(Args.getLocalWitnesses()
- .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine())))
+ .getWitnessAccountAddress()))
.setToAddress(ByteString.copyFrom(ByteArray.fromHexString(
(Wallet.getAddressPreFixString() + "A389132D6639FBDA4FBC8B659264E6B7C90DB086"))))
.build();
@@ -116,8 +116,7 @@ public void testExpireTransactionNew() {
.saveLatestBlockHeaderTimestamp(blockCapsule.getTimeStamp());
dbManager.updateRecentBlock(blockCapsule);
initLocalWitness();
- byte[] address = Args.getLocalWitnesses()
- .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine());
+ byte[] address = Args.getLocalWitnesses().getWitnessAccountAddress();
ByteString addressByte = ByteString.copyFrom(address);
AccountCapsule accountCapsule =
new AccountCapsule(Protocol.Account.newBuilder().setAddress(addressByte).build());
@@ -157,8 +156,7 @@ public void testTransactionApprovedList() {
dbManager.updateRecentBlock(blockCapsule);
initLocalWitness();
- byte[] address = Args.getLocalWitnesses()
- .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine());
+ byte[] address = Args.getLocalWitnesses().getWitnessAccountAddress();
TransferContract transferContract = TransferContract.newBuilder()
.setAmount(1L)
.setOwnerAddress(ByteString.copyFrom(address))
diff --git a/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java b/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java
index d141a5fd790..521d048f23e 100755
--- a/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java
+++ b/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java
@@ -62,12 +62,12 @@ public void testSortWitness() {
List