diff --git a/build.gradle b/build.gradle index e66ee616807..8a9dd8bec75 100644 --- a/build.gradle +++ b/build.gradle @@ -84,7 +84,7 @@ subprojects { implementation group: 'org.apache.commons', name: 'commons-math', version: '2.2' implementation "org.apache.commons:commons-collections4:4.1" implementation group: 'joda-time', name: 'joda-time', version: '2.3' - implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' + implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.79' compileOnly 'org.projectlombok:lombok:1.18.34' annotationProcessor 'org.projectlombok:lombok:1.18.34' diff --git a/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java b/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java index 940a107a2ac..812e4d7fa5b 100644 --- a/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java +++ b/chainbase/src/main/java/org/tron/common/utils/LocalWitnesses.java @@ -32,6 +32,7 @@ public class LocalWitnesses { @Getter private List privateKeys = Lists.newArrayList(); + @Getter private byte[] witnessAccountAddress; public LocalWitnesses() { @@ -45,21 +46,11 @@ public LocalWitnesses(List privateKeys) { setPrivateKeys(privateKeys); } - public byte[] getWitnessAccountAddress(boolean isECKeyCryptoEngine) { - if (witnessAccountAddress == null) { - byte[] privateKey = ByteArray.fromHexString(getPrivateKey()); - final SignInterface cryptoEngine = SignUtils.fromPrivate(privateKey, isECKeyCryptoEngine); - this.witnessAccountAddress = cryptoEngine.getAddress(); - } - return witnessAccountAddress; - } - - public void setWitnessAccountAddress(final byte[] localWitnessAccountAddress) { - this.witnessAccountAddress = localWitnessAccountAddress; - } - - public void initWitnessAccountAddress(boolean isECKeyCryptoEngine) { - if (witnessAccountAddress == null) { + public void initWitnessAccountAddress(final byte[] witnessAddress, + boolean isECKeyCryptoEngine) { + if (witnessAddress != null) { + this.witnessAccountAddress = witnessAddress; + } else if (!CollectionUtils.isEmpty(privateKeys)) { byte[] privateKey = ByteArray.fromHexString(getPrivateKey()); final SignInterface ecKey = SignUtils.fromPrivate(privateKey, isECKeyCryptoEngine); @@ -85,11 +76,15 @@ private void validate(String privateKey) { privateKey = privateKey.substring(2); } - if (StringUtils.isNotBlank(privateKey) - && privateKey.length() != ChainConstant.PRIVATE_KEY_LENGTH) { + if (StringUtils.isBlank(privateKey) + || privateKey.length() != ChainConstant.PRIVATE_KEY_LENGTH) { throw new IllegalArgumentException( - String.format("private key must be %d-bits hex string, actual: %d", - ChainConstant.PRIVATE_KEY_LENGTH, privateKey.length())); + String.format("private key must be %d hex string, actual: %d", + ChainConstant.PRIVATE_KEY_LENGTH, + StringUtils.isBlank(privateKey) ? 0 : privateKey.length())); + } + if (!StringUtil.isHexadecimal(privateKey)) { + throw new IllegalArgumentException("private key must be hex string"); } } diff --git a/common/src/main/java/org/tron/common/utils/StringUtil.java b/common/src/main/java/org/tron/common/utils/StringUtil.java index ce3e95af46e..412a70d7f9c 100644 --- a/common/src/main/java/org/tron/common/utils/StringUtil.java +++ b/common/src/main/java/org/tron/common/utils/StringUtil.java @@ -44,4 +44,21 @@ public static String createReadableString(ByteString string) { public static ByteString hexString2ByteString(String hexString) { return ByteString.copyFrom(ByteArray.fromHexString(hexString)); } + + public static boolean isHexadecimal(String str) { + if (str == null || str.isEmpty()) { + return false; + } + if (str.length() % 2 != 0) { + return false; + } + + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (Character.digit(c, 16) == -1) { + return false; + } + } + return true; + } } diff --git a/crypto/src/main/java/org/tron/common/crypto/ECKey.java b/crypto/src/main/java/org/tron/common/crypto/ECKey.java index 5fe8b9ef359..d0a6048aca1 100644 --- a/crypto/src/main/java/org/tron/common/crypto/ECKey.java +++ b/crypto/src/main/java/org/tron/common/crypto/ECKey.java @@ -55,6 +55,7 @@ import org.tron.common.crypto.jce.ECKeyPairGenerator; import org.tron.common.crypto.jce.TronCastleProvider; import org.tron.common.utils.BIUtil; +import org.tron.common.utils.ByteArray; import org.tron.common.utils.ByteUtil; @Slf4j(topic = "crypto") @@ -285,7 +286,7 @@ public static ECKey fromPrivate(BigInteger privKey) { * @return - */ public static ECKey fromPrivate(byte[] privKeyBytes) { - if (Objects.isNull(privKeyBytes)) { + if (ByteArray.isEmpty(privKeyBytes)) { return null; } return fromPrivate(new BigInteger(1, privKeyBytes)); diff --git a/crypto/src/main/java/org/tron/common/crypto/sm2/SM2.java b/crypto/src/main/java/org/tron/common/crypto/sm2/SM2.java index c6aebba385a..b1d349efad3 100644 --- a/crypto/src/main/java/org/tron/common/crypto/sm2/SM2.java +++ b/crypto/src/main/java/org/tron/common/crypto/sm2/SM2.java @@ -41,6 +41,7 @@ import org.tron.common.crypto.SignatureInterface; import org.tron.common.crypto.jce.ECKeyFactory; import org.tron.common.crypto.jce.TronCastleProvider; +import org.tron.common.utils.ByteArray; import org.tron.common.utils.ByteUtil; /** @@ -247,7 +248,7 @@ public static SM2 fromPrivate(BigInteger privKey) { * @return - */ public static SM2 fromPrivate(byte[] privKeyBytes) { - if (Objects.isNull(privKeyBytes)) { + if (ByteArray.isEmpty(privKeyBytes)) { return null; } return fromPrivate(new BigInteger(1, privKeyBytes)); diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 3c162e03549..92a021280c4 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -53,7 +53,6 @@ import org.tron.common.args.Witness; import org.tron.common.config.DbBackupConfig; import org.tron.common.cron.CronExpression; -import org.tron.common.crypto.SignInterface; import org.tron.common.logsfilter.EventPluginConfig; import org.tron.common.logsfilter.FilterQuery; import org.tron.common.logsfilter.TriggerConfig; @@ -62,7 +61,6 @@ import org.tron.common.parameter.CommonParameter; import org.tron.common.parameter.RateLimiterInitialization; import org.tron.common.setting.RocksDbSettings; -import org.tron.common.utils.ByteArray; import org.tron.common.utils.Commons; import org.tron.common.utils.LocalWitnesses; import org.tron.core.Constant; @@ -70,11 +68,8 @@ import org.tron.core.config.Configuration; import org.tron.core.config.Parameter.NetConstants; import org.tron.core.config.Parameter.NodeConstant; -import org.tron.core.exception.CipherException; import org.tron.core.exception.TronError; import org.tron.core.store.AccountStore; -import org.tron.keystore.Credentials; -import org.tron.keystore.WalletUtils; import org.tron.p2p.P2pConfig; import org.tron.p2p.dns.update.DnsType; import org.tron.p2p.dns.update.PublishConfig; @@ -412,61 +407,7 @@ public static void setParam(final Config config) { PARAMETER.cryptoEngine = config.hasPath(Constant.CRYPTO_ENGINE) ? config .getString(Constant.CRYPTO_ENGINE) : Constant.ECKey_ENGINE; - if (StringUtils.isNoneBlank(PARAMETER.privateKey)) { - localWitnesses = (new LocalWitnesses(PARAMETER.privateKey)); - if (StringUtils.isNoneBlank(PARAMETER.witnessAddress)) { - byte[] bytes = Commons.decodeFromBase58Check(PARAMETER.witnessAddress); - if (bytes != null) { - localWitnesses.setWitnessAccountAddress(bytes); - logger.debug("Got localWitnessAccountAddress from cmd"); - } else { - PARAMETER.witnessAddress = ""; - logger.warn(IGNORE_WRONG_WITNESS_ADDRESS_FORMAT); - } - } - localWitnesses.initWitnessAccountAddress(PARAMETER.isECKeyCryptoEngine()); - logger.debug("Got privateKey from cmd"); - } else if (config.hasPath(Constant.LOCAL_WITNESS)) { - localWitnesses = new LocalWitnesses(); - List localwitness = config.getStringList(Constant.LOCAL_WITNESS); - localWitnesses.setPrivateKeys(localwitness); - witnessAddressCheck(config); - localWitnesses.initWitnessAccountAddress(PARAMETER.isECKeyCryptoEngine()); - logger.debug("Got privateKey from config.conf"); - } else if (config.hasPath(Constant.LOCAL_WITNESS_KEYSTORE)) { - localWitnesses = new LocalWitnesses(); - List privateKeys = new ArrayList(); - if (PARAMETER.isWitness()) { - List localwitness = config.getStringList(Constant.LOCAL_WITNESS_KEYSTORE); - if (localwitness.size() > 0) { - String fileName = System.getProperty("user.dir") + "/" + localwitness.get(0); - String password; - if (StringUtils.isEmpty(PARAMETER.password)) { - System.out.println("Please input your password."); - password = WalletUtils.inputPassword(); - } else { - password = PARAMETER.password; - PARAMETER.password = null; - } - - try { - Credentials credentials = WalletUtils - .loadCredentials(password, new File(fileName)); - SignInterface sign = credentials.getSignInterface(); - String prikey = ByteArray.toHexString(sign.getPrivateKey()); - privateKeys.add(prikey); - } catch (IOException | CipherException e) { - logger.error("Witness node start failed!"); - throw new TronError(e, TronError.ErrCode.WITNESS_KEYSTORE_LOAD); - } - } - } - localWitnesses.setPrivateKeys(privateKeys); - witnessAddressCheck(config); - localWitnesses.initWitnessAccountAddress(PARAMETER.isECKeyCryptoEngine()); - logger.debug("Got privateKey from keystore"); - } - + localWitnesses = new WitnessInitializer(config).initLocalWitnesses(); if (PARAMETER.isWitness() && CollectionUtils.isEmpty(localWitnesses.getPrivateKeys())) { throw new TronError("This is a witness node, but localWitnesses is null", @@ -1817,19 +1758,6 @@ public static void logConfig() { logger.info("\n"); } - private static void witnessAddressCheck(Config config) { - if (config.hasPath(Constant.LOCAL_WITNESS_ACCOUNT_ADDRESS)) { - byte[] bytes = Commons - .decodeFromBase58Check(config.getString(Constant.LOCAL_WITNESS_ACCOUNT_ADDRESS)); - if (bytes != null) { - localWitnesses.setWitnessAccountAddress(bytes); - logger.debug("Got localWitnessAccountAddress from config.conf"); - } else { - logger.warn(IGNORE_WRONG_WITNESS_ADDRESS_FORMAT); - } - } - } - /** * get output directory. */ diff --git a/framework/src/main/java/org/tron/core/config/args/WitnessInitializer.java b/framework/src/main/java/org/tron/core/config/args/WitnessInitializer.java new file mode 100644 index 00000000000..2ea3a449ef4 --- /dev/null +++ b/framework/src/main/java/org/tron/core/config/args/WitnessInitializer.java @@ -0,0 +1,149 @@ +package org.tron.core.config.args; + +import com.typesafe.config.Config; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.tron.common.crypto.SignInterface; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Commons; +import org.tron.common.utils.LocalWitnesses; +import org.tron.core.Constant; +import org.tron.core.exception.CipherException; +import org.tron.core.exception.TronError; +import org.tron.keystore.Credentials; +import org.tron.keystore.WalletUtils; + +@Slf4j +public class WitnessInitializer { + + private final Config config; + + private LocalWitnesses localWitnesses; + + public WitnessInitializer(Config config) { + this.config = config; + this.localWitnesses = new LocalWitnesses(); + } + + public LocalWitnesses initLocalWitnesses() { + if (!Args.PARAMETER.isWitness()) { + return localWitnesses; + } + + if (tryInitFromCommandLine()) { + return localWitnesses; + } + + if (tryInitFromConfig()) { + return localWitnesses; + } + + tryInitFromKeystore(); + + return localWitnesses; + } + + private boolean tryInitFromCommandLine() { + if (StringUtils.isBlank(Args.PARAMETER.privateKey)) { + return false; + } + + byte[] witnessAddress = null; + this.localWitnesses = new LocalWitnesses(Args.PARAMETER.privateKey); + if (StringUtils.isNotEmpty(Args.PARAMETER.witnessAddress)) { + witnessAddress = Commons.decodeFromBase58Check(Args.PARAMETER.witnessAddress); + if (witnessAddress == null) { + throw new TronError("LocalWitnessAccountAddress format from cmd is incorrect", + TronError.ErrCode.WITNESS_INIT); + } + logger.debug("Got localWitnessAccountAddress from cmd"); + } + + this.localWitnesses.initWitnessAccountAddress(witnessAddress, + Args.PARAMETER.isECKeyCryptoEngine()); + logger.debug("Got privateKey from cmd"); + return true; + } + + private boolean tryInitFromConfig() { + if (!config.hasPath(Constant.LOCAL_WITNESS) || config.getStringList(Constant.LOCAL_WITNESS) + .isEmpty()) { + return false; + } + + List localWitness = config.getStringList(Constant.LOCAL_WITNESS); + this.localWitnesses.setPrivateKeys(localWitness); + logger.debug("Got privateKey from config.conf"); + byte[] witnessAddress = getWitnessAddress(); + this.localWitnesses.initWitnessAccountAddress(witnessAddress, + Args.PARAMETER.isECKeyCryptoEngine()); + return true; + } + + private void tryInitFromKeystore() { + if (!config.hasPath(Constant.LOCAL_WITNESS_KEYSTORE) + || config.getStringList(Constant.LOCAL_WITNESS_KEYSTORE).isEmpty()) { + return; + } + + List localWitness = config.getStringList(Constant.LOCAL_WITNESS_KEYSTORE); + if (localWitness.size() > 1) { + logger.warn( + "Multiple keystores detected. Only the first keystore will be used as witness, all " + + "others will be ignored."); + } + + List privateKeys = new ArrayList<>(); + String fileName = System.getProperty("user.dir") + "/" + localWitness.get(0); + String password; + if (StringUtils.isEmpty(Args.PARAMETER.password)) { + System.out.println("Please input your password."); + password = WalletUtils.inputPassword(); + } else { + password = Args.PARAMETER.password; + Args.PARAMETER.password = null; + } + + try { + Credentials credentials = WalletUtils + .loadCredentials(password, new File(fileName)); + SignInterface sign = credentials.getSignInterface(); + String prikey = ByteArray.toHexString(sign.getPrivateKey()); + privateKeys.add(prikey); + } catch (IOException | CipherException e) { + logger.error("Witness node start failed!"); + throw new TronError(e, TronError.ErrCode.WITNESS_KEYSTORE_LOAD); + } + + this.localWitnesses.setPrivateKeys(privateKeys); + byte[] witnessAddress = getWitnessAddress(); + this.localWitnesses.initWitnessAccountAddress(witnessAddress, + Args.PARAMETER.isECKeyCryptoEngine()); + logger.debug("Got privateKey from keystore"); + } + + private byte[] getWitnessAddress() { + if (!config.hasPath(Constant.LOCAL_WITNESS_ACCOUNT_ADDRESS)) { + return null; + } + + if (localWitnesses.getPrivateKeys().size() != 1) { + throw new TronError( + "LocalWitnessAccountAddress can only be set when there is only one private key", + TronError.ErrCode.WITNESS_INIT); + } + byte[] witnessAddress = Commons + .decodeFromBase58Check(config.getString(Constant.LOCAL_WITNESS_ACCOUNT_ADDRESS)); + if (witnessAddress != null) { + logger.debug("Got localWitnessAccountAddress from config.conf"); + } else { + throw new TronError("LocalWitnessAccountAddress format from config is incorrect", + TronError.ErrCode.WITNESS_INIT); + } + return witnessAddress; + } +} diff --git a/framework/src/main/java/org/tron/core/consensus/ConsensusService.java b/framework/src/main/java/org/tron/core/consensus/ConsensusService.java index ce1f1f1cf08..ef8f30ef498 100644 --- a/framework/src/main/java/org/tron/core/consensus/ConsensusService.java +++ b/framework/src/main/java/org/tron/core/consensus/ConsensusService.java @@ -61,17 +61,18 @@ public void start() { logger.info("Add witness: {}, size: {}", Hex.toHexString(privateKeyAddress), miners.size()); } - } else { + } else if (privateKeys.size() == 1) { byte[] privateKey = fromHexString(Args.getLocalWitnesses().getPrivateKey()); byte[] privateKeyAddress = SignUtils.fromPrivate(privateKey, Args.getInstance().isECKeyCryptoEngine()).getAddress(); - byte[] witnessAddress = Args.getLocalWitnesses().getWitnessAccountAddress( - Args.getInstance().isECKeyCryptoEngine()); + byte[] witnessAddress = Args.getLocalWitnesses().getWitnessAccountAddress(); WitnessCapsule witnessCapsule = witnessStore.get(witnessAddress); if (null == witnessCapsule) { logger.warn("Witness {} is not in witnessStore.", Hex.toHexString(witnessAddress)); } + // In multi-signature mode, the address derived from the private key may differ from + // witnessAddress. Miner miner = param.new Miner(privateKey, ByteString.copyFrom(privateKeyAddress), ByteString.copyFrom(witnessAddress)); miners.add(miner); diff --git a/framework/src/main/java/org/tron/core/metrics/node/NodeMetricManager.java b/framework/src/main/java/org/tron/core/metrics/node/NodeMetricManager.java index a0aba129648..9a5ecb33213 100644 --- a/framework/src/main/java/org/tron/core/metrics/node/NodeMetricManager.java +++ b/framework/src/main/java/org/tron/core/metrics/node/NodeMetricManager.java @@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.backup.BackupManager; -import org.tron.common.parameter.CommonParameter; +import org.tron.common.utils.ByteArray; import org.tron.core.ChainBaseManager; import org.tron.core.config.args.Args; import org.tron.program.Version; @@ -36,8 +36,9 @@ private void setNodeInfo(NodeInfo nodeInfo) { nodeInfo.setIp(Args.getInstance().getNodeExternalIp()); - ByteString witnessAddress = ByteString.copyFrom(Args.getLocalWitnesses() - .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine())); + byte[] witnessAccountAddress = Args.getLocalWitnesses().getWitnessAccountAddress(); + ByteString witnessAddress = !ByteArray.isEmpty(witnessAccountAddress) ? ByteString + .copyFrom(witnessAccountAddress) : null; if (chainBaseManager.getWitnessScheduleStore().getActiveWitnesses().contains(witnessAddress)) { nodeInfo.setNodeType(1); } else { diff --git a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java index 161e918336b..61ae6326e9f 100644 --- a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java +++ b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java @@ -66,11 +66,11 @@ public class RelayService { private List fastForwardNodes = parameter.getFastForwardNodes(); - private ByteString witnessAddress = ByteString - .copyFrom(Args.getLocalWitnesses().getWitnessAccountAddress(CommonParameter.getInstance() - .isECKeyCryptoEngine())); + private final int keySize = Args.getLocalWitnesses().getPrivateKeys().size(); - private int keySize = Args.getLocalWitnesses().getPrivateKeys().size(); + private final ByteString witnessAddress = + Args.getLocalWitnesses().getWitnessAccountAddress() != null ? ByteString + .copyFrom(Args.getLocalWitnesses().getWitnessAccountAddress()) : null; private int maxFastForwardNum = Args.getInstance().getMaxFastForwardNum(); 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/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/config/args/ArgsTest.java b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java index 4b656e463be..7ad15580266 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 @@ -65,10 +65,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 +126,7 @@ public void get() { Assert.assertEquals(address, ByteArray.toHexString(Args.getLocalWitnesses() - .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine()))); + .getWitnessAccountAddress())); Assert.assertTrue(parameter.isKeystore()); } 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..8b9da2c7bc3 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,18 +15,28 @@ package org.tron.core.config.args; +import static org.junit.Assert.fail; + import com.google.common.collect.Lists; +import java.io.IOException; 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.LocalWitnesses; import org.tron.common.utils.PublicMethod; +import org.tron.common.utils.StringUtil; +import org.tron.core.Constant; 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 @@ -42,16 +52,16 @@ public void whenSetNullPrivateKey() { Assert.assertNotNull(localWitness.getPublicKey()); } - @Test + @Test(expected = IllegalArgumentException.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) public void whenSetBadFormatPrivateKey() { localWitness.setPrivateKeys(Lists.newArrayList("a111")); + fail("private key must be 64-bits hex string"); } @Test @@ -65,6 +75,103 @@ 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(); + + try { + localWitnesses.addPrivateKeys(null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("private key must be 64 hex string")); + } catch (Exception e) { + fail("should IllegalArgumentException,actual exception: " + e.getClass().getSimpleName()); + } + + try { + localWitnesses.addPrivateKeys(""); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("private key must be 64 hex string")); + } catch (Exception e) { + fail("should IllegalArgumentException,actual exception: " + e.getClass().getSimpleName()); + } + + try { + localWitnesses.addPrivateKeys(" "); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("private key must be 64 hex string")); + } catch (Exception e) { + fail("should IllegalArgumentException,actual exception: " + e.getClass().getSimpleName()); + } + + try { + localWitnesses.addPrivateKeys("11111"); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("private key must be 64 hex string")); + } catch (Exception e) { + fail("should IllegalArgumentException,actual exception: " + e.getClass().getSimpleName()); + } + + try { + String privateKey = "11111111111111111111111111111111111111111111111111111111111111 "; + localWitnesses.addPrivateKeys(privateKey); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("private key must be hex string")); + } catch (Exception e) { + fail("should IllegalArgumentException,actual exception: " + e.getClass().getSimpleName()); + } + + try { + String privateKey = "xy11111111111111111111111111111111111111111111111111111111111111"; + localWitnesses.addPrivateKeys(privateKey); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("private key must be hex string")); + } catch (Exception e) { + fail("should IllegalArgumentException,actual exception: " + e.getClass().getSimpleName()); + } + } + + @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 +184,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/ManagerTest.java b/framework/src/test/java/org/tron/core/db/ManagerTest.java index db219377b74..d05334c5b94 100755 --- a/framework/src/test/java/org/tron/core/db/ManagerTest.java +++ b/framework/src/test/java/org/tron/core/db/ManagerTest.java @@ -136,7 +136,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 = 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/net/services/RelayServiceTest.java b/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java index 5e22e538e80..eb42ab05719 100644 --- a/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java @@ -5,6 +5,7 @@ import com.google.common.collect.Lists; import com.google.protobuf.ByteString; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.util.ArrayList; @@ -168,4 +169,32 @@ private void testCheckHelloMessage() { logger.info("{}", e.getMessage()); } } -} \ No newline at end of file + + @Test + public void testNullWitnessAddress() { + try { + Class clazz = service.getClass(); + + Field keySizeField = clazz.getDeclaredField("keySize"); + keySizeField.setAccessible(true); + keySizeField.set(service, 0); + + Field witnessAddressField = clazz.getDeclaredField("witnessAddress"); + witnessAddressField.setAccessible(true); + witnessAddressField.set(service, null); + + Method isActiveWitnessMethod = clazz.getDeclaredMethod("isActiveWitness"); + isActiveWitnessMethod.setAccessible(true); + + Boolean result = (Boolean) isActiveWitnessMethod.invoke(service); + Assert.assertNotEquals(Boolean.TRUE, result); + + witnessAddressField.set(service, ByteString.copyFrom(new byte[21])); + result = (Boolean) isActiveWitnessMethod.invoke(service); + Assert.assertNotEquals(Boolean.TRUE, result); + } catch (NoSuchMethodException | NoSuchFieldException + | IllegalAccessException | InvocationTargetException e) { + Assert.fail("Reflection invocation failed: " + e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java b/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java index 4012029e8ae..013d58b63ca 100755 --- a/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java @@ -128,7 +128,7 @@ public class ShieldedReceiveTest extends BaseTest { private static boolean init; static { - Args.setParam(new String[]{"--output-directory", dbPath()}, "config-localtest.conf"); + Args.setParam(new String[]{"--output-directory", dbPath(), "-w"}, "config-localtest.conf"); ADDRESS_ONE_PRIVATE_KEY = getRandomPrivateKey(); FROM_ADDRESS = getHexAddressByPrivateKey(ADDRESS_ONE_PRIVATE_KEY); } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 53d4958f1e5..e8f2596e195 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1569,12 +1569,12 @@ - - - + + + - - + + diff --git a/plugins/build.gradle b/plugins/build.gradle index 40d68e19d2f..e03e9a7c49a 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -37,7 +37,7 @@ dependencies { implementation group: 'info.picocli', name: 'picocli', version: '4.6.3' implementation group: 'com.typesafe', name: 'config', version: '1.3.2' implementation group: 'me.tongfei', name: 'progressbar', version: '0.9.3' - implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' + implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.79' if (rootProject.archInfo.isArm64) { testRuntimeOnly group: 'org.fusesource.hawtjni', name: 'hawtjni-runtime', version: '1.18' // for test implementation project(":platform") @@ -186,4 +186,4 @@ task copyToParent(type: Copy) { -build.finalizedBy(copyToParent) \ No newline at end of file +build.finalizedBy(copyToParent)