diff --git a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java index e4e17a14..6b47a505 100644 --- a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java +++ b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java @@ -68,6 +68,8 @@ public interface DataCodes { // public static final int METADATA_PARTICIPANT_INFO = 0x640; public static final int METADATA_CRYPTO_SETTING = 0x642; + + public static final int METADATA_CRYPTO_SETTING_PROVIDER = 0x643; // public static final int ACCOUNT = 0x700; diff --git a/source/base/src/main/java/com/jd/blockchain/provider/ProviderManager.java b/source/base/src/main/java/com/jd/blockchain/provider/ProviderManager.java index 447ba3db..98584de4 100644 --- a/source/base/src/main/java/com/jd/blockchain/provider/ProviderManager.java +++ b/source/base/src/main/java/com/jd/blockchain/provider/ProviderManager.java @@ -4,6 +4,7 @@ import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -48,32 +49,45 @@ public final class ProviderManager { * @return */ public S getService(Class serviceClazz, String providerName) { - NamedProviders providers = getServiceProvider(serviceClazz); + NamedProviders providers = getNamedProviders(serviceClazz); return providers.getService(providerName); } + + public Provider getProvider(Class serviceClazz, String providerName) { + @SuppressWarnings("unchecked") + NamedProviders providers = (NamedProviders) serviceProviders.get(serviceClazz); + if (providers == null) { + return null; + } + return providers.getProvider(providerName); + } public Collection> getAllProviders(Class serviceClazz) { - NamedProviders providers = getServiceProvider(serviceClazz); + @SuppressWarnings("unchecked") + NamedProviders providers = (NamedProviders) serviceProviders.get(serviceClazz); + if (providers == null) { + return Collections.emptyList(); + } return providers.getProviders(); } public S installProvider(Class serviceClazz, String providerFullName) { - NamedProviders providers = getServiceProvider(serviceClazz); + NamedProviders providers = getNamedProviders(serviceClazz); return providers.install(providerFullName); } public S installProvider(Class service, String providerFullName, ClassLoader classLoader) { - NamedProviders providers = getServiceProvider(service); + NamedProviders providers = getNamedProviders(service); return providers.install(providerFullName, classLoader); } public void installAllProviders(Class serviceClazz, ClassLoader classLoader) { - NamedProviders providers = getServiceProvider(serviceClazz); + NamedProviders providers = getNamedProviders(serviceClazz); providers.installAll(classLoader); } @SuppressWarnings("unchecked") - private NamedProviders getServiceProvider(Class serviceClazz) { + private NamedProviders getNamedProviders(Class serviceClazz) { NamedProviders providers = (NamedProviders) serviceProviders.get(serviceClazz); if (providers == null) { synchronized (mutex) { @@ -189,6 +203,11 @@ public final class ProviderManager { public Collection> getProviders() { return namedProviders.values(); } + + + public Provider getProvider(String providerFullName) { + return namedProviders.get(providerFullName); + } public S getService(String name) { String fullName = shortNames.get(name); diff --git a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/client/BftsmartMessageService.java b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/client/BftsmartMessageService.java index 53a5f0a8..5ecf6596 100644 --- a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/client/BftsmartMessageService.java +++ b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/client/BftsmartMessageService.java @@ -40,7 +40,7 @@ public class BftsmartMessageService implements MessageService { asyncFuture.complete(result); } catch (Exception e) { - throw new RuntimeException(); + throw new RuntimeException(e); } finally { asyncPeerProxyPool.returnObject(asynchServiceProxy); diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java index 80be911f..3eac13bb 100644 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java +++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java @@ -5,6 +5,7 @@ import com.jd.blockchain.crypto.PrivKey; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.tools.keygen.KeyGenCommand; +import com.jd.blockchain.utils.StringUtils; import com.jd.blockchain.utils.codec.Base58Utils; import com.jd.blockchain.utils.io.FileUtils; import org.apache.maven.plugin.AbstractMojo; diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/StringUtils.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/StringUtils.java deleted file mode 100644 index f8fe1867..00000000 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/StringUtils.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.jd.blockchain; -/** - * @Author zhaogw - * @Date 2018/11/26 20:46 - */ -public abstract class StringUtils { - public static boolean isEmpty(Object str) { - return str == null || "".equals(str); - } -} \ No newline at end of file diff --git a/source/contract/contract-maven-plugin/src/main/resources/sys-contract.properties b/source/contract/contract-maven-plugin/src/main/resources/sys-contract.properties index 6dd66e5e..a7179906 100644 --- a/source/contract/contract-maven-plugin/src/main/resources/sys-contract.properties +++ b/source/contract/contract-maven-plugin/src/main/resources/sys-contract.properties @@ -1,9 +1,9 @@ -#项目源文件存放的位置; +#PROJECT_BASE_DIR PROJECT_BASE_DIR=E:\\gitCode\\block\\prototype\\ -#合同使用的类库存放的位置,可能不在项目中,故采用全新的地址; +#LEDGER_BASE_CLASS_PATH LEDGER_BASE_CLASS_PATH=E:\\gitCode\\block\\prototype\\libs\\ -#为了测试,临时添加的变量; +#deploy and execute the contract; cParam=com.jd.blockchain.contract.AssetContract3 sParam=E:\\gitCode\\block\\prototype\\source\\sdk\\contract-sample\\src\\main\\java\\ eParam=utf-8 diff --git a/source/contract/contract-tools/pom.xml b/source/contract/contract-tools/pom.xml deleted file mode 100644 index da60f463..00000000 --- a/source/contract/contract-tools/pom.xml +++ /dev/null @@ -1,80 +0,0 @@ - - 4.0.0 - - com.jd.blockchain - contract - 0.9.0-SNAPSHOT - - contract-tools - - - - com.jd.blockchain - contract-compiler - ${project.version} - - - com.jd.blockchain - contract-jar - ${project.version} - - - commons-io - commons-io - ${commons-io.version} - - - junit - junit - test - - - org.mockito - mockito-core - test - - - org.slf4j - slf4j-log4j12 - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.5 - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/source/crypto/crypto-adv/pom.xml b/source/crypto/crypto-adv/pom.xml index bf759175..6c3705f2 100644 --- a/source/crypto/crypto-adv/pom.xml +++ b/source/crypto/crypto-adv/pom.xml @@ -21,6 +21,13 @@ org.bouncycastle bcprov-jdk15on + + + org.bouncycastle + bcpkix-jdk15on + 1.61 + + com.jd.blockchain binary-proto diff --git a/source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/PaillierUtilsTest.java b/source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/PaillierUtilsTest.java index 8ace44d1..a88b14ed 100644 --- a/source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/PaillierUtilsTest.java +++ b/source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/PaillierUtilsTest.java @@ -19,7 +19,7 @@ import static org.junit.Assert.assertEquals; */ public class PaillierUtilsTest { @Test - public void generateKeyPairTest() { + public void test() { AsymmetricCipherKeyPair keyPair = PaillierUtils.generateKeyPair(); PaillierPublicKeyParameters pubKeyParams = (PaillierPublicKeyParameters) keyPair.getPublic(); @@ -58,13 +58,6 @@ public class PaillierUtilsTest { assertEquals(pInverseConverted, pInverse); assertEquals(muPConverted, muP); assertEquals(muQConverted, muQ); - } - - @Test - public void encryptTest() { - - AsymmetricCipherKeyPair keyPair = PaillierUtils.generateKeyPair(); - PaillierPublicKeyParameters pubKeyParams = (PaillierPublicKeyParameters) keyPair.getPublic(); byte[] pubKeyBytes = PaillierUtils.pubKey2Bytes(pubKeyParams); @@ -77,23 +70,15 @@ public class PaillierUtilsTest { assertEquals(512,ciphertextFromParams.length); assertEquals(512,ciphertextFromBytes.length); - } - @Test - public void decryptTest(){ - AsymmetricCipherKeyPair keyPair = PaillierUtils.generateKeyPair(); - PaillierPublicKeyParameters pubKeyParams = (PaillierPublicKeyParameters) keyPair.getPublic(); - PaillierPrivateKeyParameters privKeyParams = (PaillierPrivateKeyParameters) keyPair.getPrivate(); - - byte[] pubKeyBytes = PaillierUtils.pubKey2Bytes(pubKeyParams); byte[] privKeyBytes = PaillierUtils.privKey2Bytes(privKeyParams); int input = 666; - byte[] data = intToByteArray(input); + byte[] inputBytes = intToByteArray(input); - byte[] ciphertextFromParams = PaillierUtils.encrypt(data,pubKeyParams); - byte[] ciphertextFromBytes = PaillierUtils.encrypt(data,pubKeyBytes); + ciphertextFromParams = PaillierUtils.encrypt(inputBytes,pubKeyParams); + ciphertextFromBytes = PaillierUtils.encrypt(inputBytes,pubKeyBytes); byte[] plaintextFromParams = PaillierUtils.decrypt(ciphertextFromBytes,privKeyParams); byte[] plaintextFromBytes = PaillierUtils.decrypt(ciphertextFromParams,privKeyBytes); @@ -103,16 +88,9 @@ public class PaillierUtilsTest { assertEquals(input,outputFromParams); assertEquals(input,outputFromBytes); - } - @Test - public void addTest() { - AsymmetricCipherKeyPair keyPair = PaillierUtils.generateKeyPair(); - PaillierPublicKeyParameters pubKeyParams = (PaillierPublicKeyParameters) keyPair.getPublic(); - PaillierPrivateKeyParameters privKeyParams = (PaillierPrivateKeyParameters) keyPair.getPrivate(); - - byte[] pubKeyBytes = PaillierUtils.pubKey2Bytes(pubKeyParams); + pubKeyBytes = PaillierUtils.pubKey2Bytes(pubKeyParams); int input1 = 600; int input2 = 60; @@ -139,26 +117,19 @@ public class PaillierUtilsTest { output = byteArrayToInt(plaintext); assertEquals(sum,output); - } - @Test - public void scalarMultiplyTest() { - AsymmetricCipherKeyPair keyPair = PaillierUtils.generateKeyPair(); - PaillierPublicKeyParameters pubKeyParams = (PaillierPublicKeyParameters) keyPair.getPublic(); - PaillierPrivateKeyParameters privKeyParams = (PaillierPrivateKeyParameters) keyPair.getPrivate(); - - byte[] pubKeyBytes = PaillierUtils.pubKey2Bytes(pubKeyParams); + pubKeyBytes = PaillierUtils.pubKey2Bytes(pubKeyParams); - int input = 111; + input = 111; int scalar = 6; - byte[] data = intToByteArray(input); + data = intToByteArray(input); byte[] ciphertext = PaillierUtils.encrypt(data,pubKeyParams); byte[] ciphertextPowered = PaillierUtils.scalarMultiply(pubKeyBytes,ciphertext,scalar); byte[] plaintextMultiplied = PaillierUtils.decrypt(ciphertextPowered,privKeyParams); - int output = byteArrayToInt(plaintextMultiplied); + output = byteArrayToInt(plaintextMultiplied); assertEquals(input * scalar, output); } diff --git a/source/crypto/crypto-classic/pom.xml b/source/crypto/crypto-classic/pom.xml index bd59aeb8..75ab597b 100644 --- a/source/crypto/crypto-classic/pom.xml +++ b/source/crypto/crypto-classic/pom.xml @@ -15,6 +15,12 @@ crypto-framework ${project.version} + + + org.bouncycastle + bcpkix-jdk15on + 1.61 + \ No newline at end of file diff --git a/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/service/classic/RSACryptoFunction.java b/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/service/classic/RSACryptoFunction.java index b7bd9c8d..ab078bfb 100644 --- a/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/service/classic/RSACryptoFunction.java +++ b/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/service/classic/RSACryptoFunction.java @@ -21,11 +21,11 @@ public class RSACryptoFunction implements AsymmetricEncryptionFunction, Signatur private static final CryptoAlgorithm RSA = ClassicAlgorithm.RSA; - // modulus.length = 256, publicExponent.length = 1 - private static final int PUBKEY_SIZE = 257; - // modulus.length = 256, publicExponent.length = 1, privateExponent.length = 256, p.length = 128, q.length =128, + // modulus.length = 256, publicExponent.length = 3 + private static final int PUBKEY_SIZE = 259; + // modulus.length = 256, publicExponent.length = 3, privateExponent.length = 256, p.length = 128, q.length =128, // dP.length = 128, dQ.length = 128, qInv.length = 128 - private static final int PRIVKEY_SIZE = 1153; + private static final int PRIVKEY_SIZE = 1155; private static final int SIGNATUREDIGEST_SIZE = 256; private static final int CIPHERTEXTBLOCK_SIZE = 256; diff --git a/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/RSAUtils.java b/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/RSAUtils.java index 555f5006..a787b655 100644 --- a/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/RSAUtils.java +++ b/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/RSAUtils.java @@ -60,6 +60,7 @@ public class RSAUtils { private static final int QINV_LENGTH = 1024 / 8; private static final BigInteger PUBEXP_0X03 = BigInteger.valueOf(0x03); + private static final BigInteger PUBEXP_0X010001 = BigInteger.valueOf(0x010001); private static final BigInteger VERSION_2PRIMES = BigInteger.valueOf(0); @@ -82,6 +83,21 @@ public class RSAUtils { } public static AsymmetricCipherKeyPair generateKeyPair(SecureRandom random){ + AsymmetricCipherKeyPairGenerator kpGen = new RSAKeyPairGenerator(); + kpGen.init(new RSAKeyGenerationParameters(PUBEXP_0X010001, random, KEYSIZEBITS, CERTAINTY)); + return kpGen.generateKeyPair(); + } + + /** + * key pair generation with short public exponent锛 resulting in verifying and encrypting more efficiently + * + * @return key pair + */ + public static AsymmetricCipherKeyPair generateKeyPair_shortExp(){ + return generateKeyPair_shortExp(new SecureRandom()); + } + + public static AsymmetricCipherKeyPair generateKeyPair_shortExp(SecureRandom random){ AsymmetricCipherKeyPairGenerator kpGen = new RSAKeyPairGenerator(); kpGen.init(new RSAKeyGenerationParameters(PUBEXP_0X03, random, KEYSIZEBITS, CERTAINTY)); return kpGen.generateKeyPair(); @@ -303,22 +319,16 @@ public class RSAUtils { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKeyBytes); - KeyFactory keyFactory = null; - try { - keyFactory = KeyFactory.getInstance("RSA"); - } catch (NoSuchAlgorithmException e) { - throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); - } + KeyFactory keyFactory; + RSAPublicKey publicKey; - RSAPublicKey publicKey = null; try { + keyFactory = KeyFactory.getInstance("RSA"); publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec); - } catch (InvalidKeySpecException e) { + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); } - assert publicKey != null; - BigInteger exponent = publicKey.getPublicExponent(); BigInteger modulus = publicKey.getModulus(); @@ -414,7 +424,7 @@ public class RSAUtils { BigInteger qInv = privKey.getQInv(); byte[] modulusBytes = bigInteger2Bytes(modulus,MODULUS_LENGTH); - byte[] pubExpBytes = pubExp.toByteArray(); + byte[] pubExpBytes = pubExp.toByteArray(); byte[] privExpBytes = bigInteger2Bytes(privExp,PRIVEXP_LENGTH); byte[] pBytes = bigInteger2Bytes(p,P_LENGTH); byte[] qBytes = bigInteger2Bytes(q,Q_LENGTH); @@ -446,22 +456,16 @@ public class RSAUtils { PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyBytes); - KeyFactory keyFactory = null; - try { - keyFactory = KeyFactory.getInstance("RSA"); - } catch (NoSuchAlgorithmException e) { - throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); - } - + KeyFactory keyFactory; RSAPrivateCrtKey privateKey; + try { + keyFactory = KeyFactory.getInstance("RSA"); privateKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec); - } catch (InvalidKeySpecException e) { + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); } - assert privateKey != null; - BigInteger modulus = privateKey.getModulus(); BigInteger pubExp = privateKey.getPublicExponent(); BigInteger privExp = privateKey.getPrivateExponent(); @@ -524,7 +528,7 @@ public class RSAUtils { result,0, length); } else { System.arraycopy(srcBytes,0, - result,length - srcLength, length); + result,length - srcLength, srcLength); } return result; diff --git a/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/SSHKeyParser.java b/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/SSHKeyParser.java new file mode 100644 index 00000000..73e5243a --- /dev/null +++ b/source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/SSHKeyParser.java @@ -0,0 +1,49 @@ +package com.jd.blockchain.crypto.utils.classic; + +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil; +import org.bouncycastle.jce.spec.OpenSSHPublicKeySpec; +import org.bouncycastle.util.encoders.Base64; + +/** + * @author zhanglin33 + * @title: SSHKeyParser + * @description: a parser for parsing asymmetric keys in Base64 format + * @date 2019-05-17, 17:52 + */ +public class SSHKeyParser { + + private String pubKeyFormat; + private String pubKeyType; + + public AsymmetricKeyParameter pubKeyParse(String pubKeyStr) { + + byte[] pubKeyBytes; + + if (pubKeyStr.startsWith("ssh") || pubKeyStr.startsWith("ecdsa")) { + String[] algoAndKeyAndLocal = pubKeyStr.split(" "); + pubKeyBytes = Base64.decode(algoAndKeyAndLocal[1]); + } else { + pubKeyBytes = Base64.decode(pubKeyStr); + } + + OpenSSHPublicKeySpec pubKeySpec = new OpenSSHPublicKeySpec(pubKeyBytes); + + pubKeyFormat = pubKeySpec.getFormat(); + pubKeyType = pubKeySpec.getType(); + + return OpenSSHPublicKeyUtil.parsePublicKey(pubKeyBytes); + } + + + + + + public String getPubKeyFormat() { + return pubKeyFormat; + } + + public String getPubKeyType() { + return pubKeyType; + } +} diff --git a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/service/classic/RSACryptoFunctionTest.java b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/service/classic/RSACryptoFunctionTest.java index bb61d80b..60f4d113 100644 --- a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/service/classic/RSACryptoFunctionTest.java +++ b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/service/classic/RSACryptoFunctionTest.java @@ -42,7 +42,7 @@ public class RSACryptoFunctionTest { } @Test - public void generateKeyPairTest() { + public void test() { CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); assertNotNull(algorithm); @@ -55,15 +55,15 @@ public class RSACryptoFunctionTest { PrivKey privKey = keyPair.getPrivKey(); assertEquals(PUBLIC.CODE, pubKey.getKeyType().CODE); - assertEquals(257, pubKey.getRawKeyBytes().length); + assertEquals(259, pubKey.getRawKeyBytes().length); assertEquals(PRIVATE.CODE, privKey.getKeyType().CODE); - assertEquals(1153, privKey.getRawKeyBytes().length); + assertEquals(1155, privKey.getRawKeyBytes().length); assertEquals(algorithm.code(), pubKey.getAlgorithm()); assertEquals(algorithm.code(), privKey.getAlgorithm()); - assertEquals(2 + 1 + 257, pubKey.toBytes().length); - assertEquals(2 + 1 + 1153, privKey.toBytes().length); + assertEquals(2 + 1 + 259, pubKey.toBytes().length); + assertEquals(2 + 1 + 1155, privKey.toBytes().length); byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); byte[] pubKeyTypeBytes = new byte[] { PUBLIC.CODE }; @@ -72,20 +72,7 @@ public class RSACryptoFunctionTest { byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); assertArrayEquals(BytesUtils.concat(algoBytes, pubKeyTypeBytes, rawPubKeyBytes), pubKey.toBytes()); assertArrayEquals(BytesUtils.concat(algoBytes, privKeyTypeBytes, rawPrivKeyBytes), privKey.toBytes()); - } - - @Test - public void retrievePubKeyTest() { - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - - PubKey pubKey = keyPair.getPubKey(); - PrivKey privKey = keyPair.getPrivKey(); PubKey retrievedPubKey = signatureFunction.retrievePubKey(privKey); @@ -93,23 +80,12 @@ public class RSACryptoFunctionTest { assertEquals(pubKey.getRawKeyBytes().length, retrievedPubKey.getRawKeyBytes().length); assertEquals(pubKey.getAlgorithm(), retrievedPubKey.getAlgorithm()); assertArrayEquals(pubKey.toBytes(), retrievedPubKey.toBytes()); - } - @Test - public void signTest() { - byte[] data = new byte[1024]; + byte[] data = new byte[128]; Random random = new Random(); random.nextBytes(data); - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - - PrivKey privKey = keyPair.getPrivKey(); SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); byte[] signatureBytes = signatureDigest.toBytes(); @@ -121,48 +97,16 @@ public class RSACryptoFunctionTest { assertEquals((short) (SIGNATURE_ALGORITHM | ENCRYPTION_ALGORITHM | ASYMMETRIC_KEY | ((byte) 23 & 0x00FF)), signatureDigest.getAlgorithm()); - byte[] algoBytes = BytesUtils.toBytes(signatureDigest.getAlgorithm()); byte[] rawSinatureBytes = signatureDigest.getRawDigest(); assertArrayEquals(BytesUtils.concat(algoBytes, rawSinatureBytes), signatureBytes); - } - @Test - public void verifyTest() { - byte[] data = new byte[1024]; - Random random = new Random(); - random.nextBytes(data); - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - - PubKey pubKey = keyPair.getPubKey(); - PrivKey privKey = keyPair.getPrivKey(); - SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); assertTrue(signatureFunction.verify(signatureDigest, pubKey, data)); - } - - @Test - public void encryptTest() { - - byte[] data = new byte[128]; - Random random = new Random(); - random.nextBytes(data); - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); AsymmetricEncryptionFunction asymmetricEncryptionFunction = Crypto .getAsymmetricEncryptionFunction(algorithm); - AsymmetricKeypair keyPair = asymmetricEncryptionFunction.generateKeypair(); - - PubKey pubKey = keyPair.getPubKey(); - Ciphertext ciphertext = asymmetricEncryptionFunction.encrypt(pubKey, data); byte[] ciphertextBytes = ciphertext.toBytes(); @@ -172,90 +116,32 @@ public class RSACryptoFunctionTest { assertEquals((short) (SIGNATURE_ALGORITHM | ENCRYPTION_ALGORITHM | ASYMMETRIC_KEY | ((byte) 23 & 0x00FF)), ciphertext.getAlgorithm()); - byte[] algoBytes = BytesUtils.toBytes(ciphertext.getAlgorithm()); byte[] rawCiphertextBytes = ciphertext.getRawCiphertext(); assertArrayEquals(BytesUtils.concat(algoBytes, rawCiphertextBytes), ciphertextBytes); - } - @Test - public void decryptTest() { - - byte[] data = new byte[128]; - Random random = new Random(); - random.nextBytes(data); - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - AsymmetricEncryptionFunction asymmetricEncryptionFunction = Crypto - .getAsymmetricEncryptionFunction(algorithm); - - AsymmetricKeypair keyPair = asymmetricEncryptionFunction.generateKeypair(); - - PubKey pubKey = keyPair.getPubKey(); - PrivKey privKey = keyPair.getPrivKey(); - - Ciphertext ciphertext = asymmetricEncryptionFunction.encrypt(pubKey, data); byte[] decryptedPlaintext = asymmetricEncryptionFunction.decrypt(privKey, ciphertext); - assertArrayEquals(data, decryptedPlaintext); - } - - @Test - public void supportPrivKeyTest() { - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - PrivKey privKey = keyPair.getPrivKey(); byte[] privKeyBytes = privKey.toBytes(); - assertTrue(signatureFunction.supportPrivKey(privKeyBytes)); - algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); - byte[] pubKeyTypeBytes = new byte[] { PUBLIC.CODE }; byte[] rawKeyBytes = privKey.getRawKeyBytes(); byte[] ripemd160PubKeyBytes = BytesUtils.concat(algoBytes, pubKeyTypeBytes, rawKeyBytes); - assertFalse(signatureFunction.supportPrivKey(ripemd160PubKeyBytes)); - } - @Test - public void resolvePrivKeyTest() { - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - - PrivKey privKey = keyPair.getPrivKey(); - byte[] privKeyBytes = privKey.toBytes(); PrivKey resolvedPrivKey = signatureFunction.resolvePrivKey(privKeyBytes); - assertEquals(PRIVATE.CODE, resolvedPrivKey.getKeyType().CODE); - assertEquals(1153, resolvedPrivKey.getRawKeyBytes().length); + assertEquals(1155, resolvedPrivKey.getRawKeyBytes().length); assertEquals(ClassicAlgorithm.RSA.code(), resolvedPrivKey.getAlgorithm()); assertEquals((short) (SIGNATURE_ALGORITHM | ENCRYPTION_ALGORITHM | ASYMMETRIC_KEY | ((byte) 23 & 0x00FF)), resolvedPrivKey.getAlgorithm()); assertArrayEquals(privKeyBytes, resolvedPrivKey.toBytes()); - algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); - byte[] pubKeyTypeBytes = new byte[] { PUBLIC.CODE }; - byte[] rawKeyBytes = privKey.getRawKeyBytes(); - byte[] ripemd160PubKeyBytes = BytesUtils.concat(algoBytes, pubKeyTypeBytes, rawKeyBytes); - Class expectedException = CryptoException.class; Exception actualEx = null; try { @@ -265,64 +151,26 @@ public class RSACryptoFunctionTest { } assertNotNull(actualEx); assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); - } - - @Test - public void supportPubKeyTest() { - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - - PubKey pubKey = keyPair.getPubKey(); byte[] pubKeyBytes = pubKey.toBytes(); - assertTrue(signatureFunction.supportPubKey(pubKeyBytes)); - algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); - byte[] privKeyTypeBytes = new byte[] { PRIVATE.CODE }; - byte[] rawKeyBytes = pubKey.getRawKeyBytes(); byte[] ripemd160PrivKeyBytes = BytesUtils.concat(algoBytes, privKeyTypeBytes, rawKeyBytes); - assertFalse(signatureFunction.supportPubKey(ripemd160PrivKeyBytes)); - } - - @Test - public void resolvePubKeyTest() { - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - PubKey pubKey = keyPair.getPubKey(); - byte[] pubKeyBytes = pubKey.toBytes(); PubKey resolvedPubKey = signatureFunction.resolvePubKey(pubKeyBytes); - assertEquals(PUBLIC.CODE, resolvedPubKey.getKeyType().CODE); - assertEquals(257, resolvedPubKey.getRawKeyBytes().length); + assertEquals(259, resolvedPubKey.getRawKeyBytes().length); assertEquals(ClassicAlgorithm.RSA.code(), resolvedPubKey.getAlgorithm()); assertEquals((short) (SIGNATURE_ALGORITHM | ENCRYPTION_ALGORITHM | ASYMMETRIC_KEY | ((byte) 23 & 0x00FF)), resolvedPubKey.getAlgorithm()); assertArrayEquals(pubKeyBytes, resolvedPubKey.toBytes()); - algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); - byte[] privKeyTypeBytes = new byte[] { PRIVATE.CODE }; - byte[] rawKeyBytes = pubKey.getRawKeyBytes(); - byte[] ripemd160PrivKeyBytes = BytesUtils.concat(algoBytes, privKeyTypeBytes, rawKeyBytes); - - Class expectedException = CryptoException.class; - Exception actualEx = null; try { signatureFunction.resolvePrivKey(ripemd160PrivKeyBytes); } catch (Exception e) { @@ -330,57 +178,18 @@ public class RSACryptoFunctionTest { } assertNotNull(actualEx); assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); - } - - @Test - public void supportDigestTest() { - - byte[] data = new byte[1024]; - Random random = new Random(); - random.nextBytes(data); - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - - PrivKey privKey = keyPair.getPrivKey(); - - SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); byte[] signatureDigestBytes = signatureDigest.toBytes(); assertTrue(signatureFunction.supportDigest(signatureDigestBytes)); algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); byte[] rawDigestBytes = signatureDigest.toBytes(); byte[] ripemd160SignatureBytes = BytesUtils.concat(algoBytes, rawDigestBytes); assertFalse(signatureFunction.supportDigest(ripemd160SignatureBytes)); - } - - @Test - public void resolveDigestTest() { - - byte[] data = new byte[1024]; - Random random = new Random(); - random.nextBytes(data); - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); - - AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); - - PrivKey privKey = keyPair.getPrivKey(); - SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); - - byte[] signatureDigestBytes = signatureDigest.toBytes(); SignatureDigest resolvedSignatureDigest = signatureFunction.resolveDigest(signatureDigestBytes); @@ -392,12 +201,8 @@ public class RSACryptoFunctionTest { algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); - byte[] rawDigestBytes = signatureDigest.getRawDigest(); byte[] ripemd160SignatureDigestBytes = BytesUtils.concat(algoBytes, rawDigestBytes); - Class expectedException = CryptoException.class; - Exception actualEx = null; try { signatureFunction.resolveDigest(ripemd160SignatureDigestBytes); } catch (Exception e) { @@ -405,77 +210,24 @@ public class RSACryptoFunctionTest { } assertNotNull(actualEx); assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); - } - - @Test - public void supportCiphertextTest() { - - byte[] data = new byte[128]; - Random random = new Random(); - random.nextBytes(data); - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - AsymmetricEncryptionFunction asymmetricEncryptionFunction = Crypto - .getAsymmetricEncryptionFunction(algorithm); - - AsymmetricKeypair keyPair = asymmetricEncryptionFunction.generateKeypair(); - - PubKey pubKey = keyPair.getPubKey(); - - Ciphertext ciphertext = asymmetricEncryptionFunction.encrypt(pubKey, data); - byte[] ciphertextBytes = ciphertext.toBytes(); assertTrue(asymmetricEncryptionFunction.supportCiphertext(ciphertextBytes)); - algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); - byte[] rawCiphertextBytes = ciphertext.toBytes(); + algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); byte[] ripemd160CiphertextBytes = BytesUtils.concat(algoBytes, rawCiphertextBytes); - assertFalse(asymmetricEncryptionFunction.supportCiphertext(ripemd160CiphertextBytes)); - } - - @Test - public void resolveCiphertextTest() { - - byte[] data = new byte[128]; - Random random = new Random(); - random.nextBytes(data); - - CryptoAlgorithm algorithm = Crypto.getAlgorithm("RSA"); - assertNotNull(algorithm); - - AsymmetricEncryptionFunction asymmetricEncryptionFunction = Crypto - .getAsymmetricEncryptionFunction(algorithm); - - AsymmetricKeypair keyPair = asymmetricEncryptionFunction.generateKeypair(); - PubKey pubKey = keyPair.getPubKey(); - - Ciphertext ciphertext = asymmetricEncryptionFunction.encrypt(pubKey, data); - - byte[] ciphertextBytes = ciphertext.toBytes(); Ciphertext resolvedCiphertext = asymmetricEncryptionFunction.resolveCiphertext(ciphertextBytes); - assertEquals(256, resolvedCiphertext.getRawCiphertext().length); assertEquals(ClassicAlgorithm.RSA.code(), resolvedCiphertext.getAlgorithm()); assertEquals((short) (SIGNATURE_ALGORITHM | ENCRYPTION_ALGORITHM | ASYMMETRIC_KEY | ((byte) 23 & 0x00FF)), resolvedCiphertext.getAlgorithm()); assertArrayEquals(ciphertextBytes, resolvedCiphertext.toBytes()); - algorithm = Crypto.getAlgorithm("ripemd160"); assertNotNull(algorithm); - byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); - byte[] rawCiphertextBytes = ciphertext.getRawCiphertext(); - byte[] ripemd160CiphertextBytes = BytesUtils.concat(algoBytes, rawCiphertextBytes); - - Class expectedException = CryptoException.class; - Exception actualEx = null; try { asymmetricEncryptionFunction.resolveCiphertext(ripemd160CiphertextBytes); } catch (Exception e) { @@ -484,5 +236,4 @@ public class RSACryptoFunctionTest { assertNotNull(actualEx); assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); } - } diff --git a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java index c8497d7e..a8c82e85 100644 --- a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java +++ b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java @@ -1,16 +1,22 @@ package test.com.jd.blockchain.crypto.utils.classic; import com.jd.blockchain.crypto.utils.classic.RSAUtils; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.util.encoders.Hex; import org.junit.Test; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; +import java.io.IOException; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; @@ -27,10 +33,20 @@ import static org.junit.Assert.*; public class RSAUtilsTest { @Test - public void generateKeyPairTest(){ + public void generateKeyPairTest() { AsymmetricCipherKeyPair kp = RSAUtils.generateKeyPair(); - RSAKeyParameters pubKey = (RSAKeyParameters) kp.getPublic(); - RSAPrivateCrtKeyParameters privKey = (RSAPrivateCrtKeyParameters) kp.getPrivate(); + keyPairTest(kp); + } + + @Test + public void generateKeyPair_ShortExpTest() { + AsymmetricCipherKeyPair kp = RSAUtils.generateKeyPair_shortExp(); + keyPairTest(kp); + } + + private void keyPairTest(AsymmetricCipherKeyPair keyPair) { + RSAKeyParameters pubKey = (RSAKeyParameters) keyPair.getPublic(); + RSAPrivateCrtKeyParameters privKey = (RSAPrivateCrtKeyParameters) keyPair.getPrivate(); byte[] pubKeyBytes_RawKey = RSAUtils.pubKey2Bytes_RawKey(pubKey); byte[] pubKeyBytesConverted_RawKey = @@ -42,9 +58,6 @@ public class RSAUtilsTest { RSAUtils.privKey2Bytes_RawKey(RSAUtils.bytes2PrivKey_RawKey(privKeyBytes_RawKey)); assertArrayEquals(privKeyBytes_RawKey,privKeyBytesConverted_RawKey); - System.out.println(pubKeyBytes_RawKey.length); - System.out.println(privKeyBytes_RawKey.length); - byte[] pubKeyBytes_PKCS1 = RSAUtils.pubKey2Bytes_PKCS1(pubKey); byte[] pubKeyBytesConverted_PKCS1 = RSAUtils.pubKey2Bytes_PKCS1(RSAUtils.bytes2PubKey_PKCS1(pubKeyBytes_PKCS1)); @@ -67,7 +80,7 @@ public class RSAUtilsTest { } @Test - public void retrievePublicKeyTest(){ + public void test(){ AsymmetricCipherKeyPair kp = RSAUtils.generateKeyPair(); RSAKeyParameters pubKey = (RSAKeyParameters) kp.getPublic(); @@ -78,38 +91,17 @@ public class RSAUtilsTest { byte[] retrievedPubKeyBytes = RSAUtils.retrievePublicKey(privKeyBytes); assertArrayEquals(pubKeyBytes,retrievedPubKeyBytes); - } - - @Test - public void signTest(){ - byte[] data = new byte[1024]; + byte[] data = new byte[128]; Random random = new Random(); random.nextBytes(data); - AsymmetricCipherKeyPair keyPair = RSAUtils.generateKeyPair(); - AsymmetricKeyParameter privKey = keyPair.getPrivate(); - byte[] privKeyBytes = RSAUtils.privKey2Bytes_RawKey((RSAPrivateCrtKeyParameters) privKey); - byte[] signatureFromPrivKey = RSAUtils.sign(data, privKey); byte[] signatureFromPrivKeyBytes = RSAUtils.sign(data, privKeyBytes); assertNotNull(signatureFromPrivKey); assertEquals(2048 / 8, signatureFromPrivKey.length); assertArrayEquals(signatureFromPrivKeyBytes,signatureFromPrivKey); - } - - @Test - public void verifyTest(){ - - byte[] data = new byte[1024]; - Random random = new Random(); - random.nextBytes(data); - - AsymmetricCipherKeyPair keyPair = RSAUtils.generateKeyPair(); - AsymmetricKeyParameter privKey = keyPair.getPrivate(); - AsymmetricKeyParameter pubKey = keyPair.getPublic(); - byte[] pubKeyBytes = RSAUtils.pubKey2Bytes_RawKey((RSAKeyParameters) pubKey); byte[] signature = RSAUtils.sign(data,privKey); @@ -118,47 +110,23 @@ public class RSAUtilsTest { assertTrue(isValidFromPubKey); assertTrue(isValidFromPubKeyBytes); - } - - @Test - public void encryptTest(){ - - byte[] data = new byte[246]; - Random random = new Random(); - random.nextBytes(data); - - AsymmetricCipherKeyPair keyPair = RSAUtils.generateKeyPair(); - AsymmetricKeyParameter pubKey = keyPair.getPublic(); - byte[] pubKeyBytes = RSAUtils.pubKey2Bytes_RawKey((RSAKeyParameters) pubKey); byte[] ciphertextFromPubKey = RSAUtils.encrypt(data,pubKey); byte[] ciphertextFromPubKeyBytes = RSAUtils.encrypt(data,pubKeyBytes); - assertEquals(512,ciphertextFromPubKey.length); - assertEquals(512,ciphertextFromPubKeyBytes.length); - } - - @Test - public void decryptTest(){ + assertEquals(256,ciphertextFromPubKey.length); + assertEquals(256,ciphertextFromPubKeyBytes.length); - AsymmetricCipherKeyPair keyPair = RSAUtils.generateKeyPair(); - AsymmetricKeyParameter pubKey = keyPair.getPublic(); - AsymmetricKeyParameter privKey = keyPair.getPrivate(); - byte[] privKeyBytes = RSAUtils.privKey2Bytes_RawKey((RSAPrivateCrtKeyParameters) privKey); - byte[] data; - for (int i = 1; i < 1024; i++) { - data = new byte[i]; - Random random = new Random(); - random.nextBytes(data); - byte[] ciphertext = RSAUtils.encrypt(data, pubKey); + data = new byte[1024]; + random.nextBytes(data); + byte[] ciphertext = RSAUtils.encrypt(data, pubKey); - byte[] plaintextFromPrivKey = RSAUtils.decrypt(ciphertext, privKey); - byte[] plaintextFromPrivKeyBytes = RSAUtils.decrypt(ciphertext, privKeyBytes); + byte[] plaintextFromPrivKey = RSAUtils.decrypt(ciphertext, privKey); + byte[] plaintextFromPrivKeyBytes = RSAUtils.decrypt(ciphertext, privKeyBytes); - assertArrayEquals(data, plaintextFromPrivKey); - assertArrayEquals(data, plaintextFromPrivKeyBytes); - } + assertArrayEquals(data, plaintextFromPrivKey); + assertArrayEquals(data, plaintextFromPrivKeyBytes); } diff --git a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/SSHKeyUtilsTest.java b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/SSHKeyUtilsTest.java new file mode 100644 index 00000000..a873ed78 --- /dev/null +++ b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/SSHKeyUtilsTest.java @@ -0,0 +1,231 @@ +//package test.com.jd.blockchain.crypto.utils.classic; +// +//import com.jd.blockchain.crypto.utils.classic.SSHKeyParser; +//import org.bouncycastle.asn1.ASN1Sequence; +//import org.bouncycastle.crypto.params.RSAKeyParameters; +//import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +//import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil; +//import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil; +//import org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec; +//import org.bouncycastle.jce.spec.OpenSSHPublicKeySpec; +//import org.bouncycastle.util.Strings; +//import org.bouncycastle.util.encoders.Base64; +//import org.bouncycastle.util.encoders.Hex; +//import org.bouncycastle.util.io.pem.PemReader; +//import org.junit.Test; +// +//import java.io.IOException; +//import java.io.StringReader; +//import java.math.BigInteger; +// +//import static org.junit.Assert.assertEquals; +// +///** +// * @author zhanglin33 +// * @title: SSHKeyUtilsTest +// * @description: Tests for methods in SSHKeyUtils +// * @date 2019-05-07, 15:14 +// */ +//public class SSHKeyUtilsTest { +// +// @Test +// public void parseRSAPublicKeyTest() { +// +// String pubKeyStr = "AAAAB3NzaC1yc2EAAAADAQABAAABAQCYwLN4EXy7g0Xugv4lQfoujbARi48gPSxVupt" + +// "GsSoGqsS00e9rA7v0qzFKa9Zhnw1WkjCnEXRYAMiCAJYkM/mGI8mb3qkcdNhGWZmPnopV+D46CTFB1" + +// "4yeR9mjoOPXs4pjX3zGveKx5Nx8jvdoFewbTCtdN0x1XWTjNT5bXqP/4gXkLENEU5tLsWVAOu0ME/N" + +// "e/9gMujAtDoolJ181a9P06bvEpIw5cLtUnsm5CtvBuiL7WBXxDJ/IASJrKNGBdK8xib1+Kb8tNLAT6" + +// "Dj25BwylqiRNhb5l1Ni4aKrE2FqSEc5Nx5+csQMEl9MBJ3pEsLHBNbohDL+jbwLguRVD6CJ"; +// +// BigInteger exponent = new BigInteger("010001",16); +// BigInteger modulus = new BigInteger("0098c0b378117cbb8345ee82fe2541fa2e8db0118b8f2" + +// "03d2c55ba9b46b12a06aac4b4d1ef6b03bbf4ab314a6bd6619f0d569230a711745800c88200962" + +// "433f98623c99bdea91c74d84659998f9e8a55f83e3a093141d78c9e47d9a3a0e3d7b38a635f7cc" + +// "6bde2b1e4dc7c8ef76815ec1b4c2b5d374c755d64e3353e5b5ea3ffe205e42c4344539b4bb1654" + +// "03aed0c13f35effd80cba302d0e8a25275f356bd3f4e9bbc4a48c3970bb549ec9b90adbc1ba22f" + +// "b5815f10c9fc801226b28d18174af3189bd7e29bf2d34b013e838f6e41c3296a8913616f997536" + +// "2e1a2ab13616a484739371e7e72c40c125f4c049de912c2c704d6e88432fe8dbc0b82e4550fa089",16); +// String pubKeyFormat = "OpenSSH"; +// String pubKeyType = "ssh-rsa"; +// +// SSHKeyParser parser = new SSHKeyParser(); +// +// RSAKeyParameters pubKey = (RSAKeyParameters) parser.pubKeyParse(pubKeyStr); +// BigInteger e = pubKey.getExponent(); +// BigInteger n = pubKey.getModulus(); +// assertEquals(exponent,e); +// assertEquals(modulus,n); +// assertEquals(pubKeyFormat,parser.getPubKeyFormat()); +// assertEquals(pubKeyType,parser.getPubKeyType()); +// +// String pubKeyStrWithHead = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCYwLN4EXy7g0Xugv4lQfou" + +// "jbARi48gPSxVuptGsSoGqsS00e9rA7v0qzFKa9Zhnw1WkjCnEXRYAMiCAJYkM/mGI8mb3qkcdNhGWZm" + +// "PnopV+D46CTFB14yeR9mjoOPXs4pjX3zGveKx5Nx8jvdoFewbTCtdN0x1XWTjNT5bXqP/4gXkLENEU5" + +// "tLsWVAOu0ME/Ne/9gMujAtDoolJ181a9P06bvEpIw5cLtUnsm5CtvBuiL7WBXxDJ/IASJrKNGBdK8xi" + +// "b1+Kb8tNLAT6Dj25BwylqiRNhb5l1Ni4aKrE2FqSEc5Nx5+csQMEl9MBJ3pEsLHBNbohDL+jbwLguRV" + +// "D6CJ zhanglin33@zhanglin33.local\n"; +// pubKey = (RSAKeyParameters) parser.pubKeyParse(pubKeyStrWithHead); +// e = pubKey.getExponent(); +// n = pubKey.getModulus(); +// assertEquals(exponent,e); +// assertEquals(modulus,n); +// assertEquals(pubKeyFormat,parser.getPubKeyFormat()); +// assertEquals(pubKeyType,parser.getPubKeyType()); +// } +// +// @Test +// public void parseRSAPrivateKeyTest() { +// +// String str2 = "-----BEGIN OPENSSH PRIVATE KEY-----\n" + +// "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n" + +// "NhAAAAAwEAAQAAAQEAwFyeWgHFu/ZMvqWa28QUGlKMDV7vpbzT7kyA/4yuotfprZKHNeEy\n" + +// "GugleJ/Kv5kqHh8Km4IZcfNcerTYds+U5m/uX4bSYpEbXco3DQ2lYQbYo7PBWwPMq2aIdd\n" + +// "i7WxUAlt0z1ugLNimskPzJ7DNra+ax0Wh9RnMsjZkfuBZiKq7wbBm7NyJmpg2B7xo5cz+G\n" + +// "Lw9e0tDlvgeLe+n68WvYWWFP59mfP6Qoy+NwjQnnwrhJi2j4dEexO97KmgnJhL07lu4eCQ\n" + +// "fdv68Tai9+aeDNawe7nmFYf2eNjah2jW/DwOwA/ErXnvgjLSMsgc6WGKfokhytAOFDGgvH\n" + +// "KKNd6BMYZwAAA9A7JircOyYq3AAAAAdzc2gtcnNhAAABAQDAXJ5aAcW79ky+pZrbxBQaUo\n" + +// "wNXu+lvNPuTID/jK6i1+mtkoc14TIa6CV4n8q/mSoeHwqbghlx81x6tNh2z5Tmb+5fhtJi\n" + +// "kRtdyjcNDaVhBtijs8FbA8yrZoh12LtbFQCW3TPW6As2KayQ/MnsM2tr5rHRaH1GcyyNmR\n" + +// "+4FmIqrvBsGbs3ImamDYHvGjlzP4YvD17S0OW+B4t76frxa9hZYU/n2Z8/pCjL43CNCefC\n" + +// "uEmLaPh0R7E73sqaCcmEvTuW7h4JB92/rxNqL35p4M1rB7ueYVh/Z42NqHaNb8PA7AD8St\n" + +// "ee+CMtIyyBzpYYp+iSHK0A4UMaC8coo13oExhnAAAAAwEAAQAAAQAEEvIXnen+LR06/G7n\n" + +// "MKPsWss0jUouDG3AokYpI2WfdUsxreTHM1nIUBpbD6dPn4LQ2H91A7BeRXUz9BiRi5vvtX\n" + +// "cq9sQF6mTV+65mzF8wSuDTtr7lmpL/HlDNjiWJrEwy5cRvTMLQBtnsyC3OntgrlNs3QCtH\n" + +// "DrFm3lNZpr+1f62Vu43dbcTPvLwcc335cJ73BU5WsMGaouCAqVXsVsgfkA66u6+gQs8O3F\n" + +// "IQntdzS8vYpkzH8N9qqNZit7kbFCRUTI7CDLHquJmclzB8uVwO0pR5+Aross+YL3QxPZoJ\n" + +// "+LXLlCi27oSmYk3fx3uh0XwwO3JFDQpeCxOuEsZbOy8BAAAAgCsktFksS0BViRuLyzC2H7\n" + +// "X7Uonf+dr8e4Yn+RgR329KFh/ok28/KZndZHsUnhdmiIjPr+SplFZZMrV/uJDkGezUNWGf\n" + +// "8qn+eEglm7nYfVf2EXTVNhpg8yfPChx90ybc8GYlqpEqf7LiCuEBCPqPJgq6K7i6UKbwn2\n" + +// "SfqUOBcz5BAAAAgQDqszdiNv0cTvZ/Xg3qJPsHXqQuLBYoe2vhU+Pipt9HviruUD1y3Mso\n" + +// "rOL9QBwjE7szGnwVE00J0mLp+s309+kftADLXqMyqFYiy7S8GIWQw0YNB2m8yjq+phHbBm\n" + +// "/Gs2P4+s8yKTcVJvMTyWr02rpCHiLTKDHoXPJcJ8yVMTHFRwAAAIEA0dHB9fXiesEKfwcp\n" + +// "X11IHAV8pTd+7VN81oGwxtRg88U7H2rmQFCxSZah2O/OCCmYLH3PHT95qnMHHqzcsVvoIy\n" + +// "7AfnMpp4KYU0Ic3aFuRjZk2sDsYUniPcCpuCvs8Jb75sDwKDW2EM8MowiNylDnYMmfYj0l\n" + +// "gIhz1/p79hXEI+EAAAAbemhhbmdsaW4zM0B6aGFuZ2xpbjMzLmxvY2Fs\n" + +// "-----END OPENSSH PRIVATE KEY-----"; +// +// byte[] Bytes2 = null; +// try { +// Bytes2 = new PemReader(new StringReader(str2)).readPemObject().getContent(); +// } catch (IOException e1) { +// e1.printStackTrace(); +// } +// assert Bytes2 != null; +// System.out.println(Hex.toHexString(Bytes2)); +// +// String str3 = "-----BEGIN OPENSSH PRIVATE KEY-----\n" + +// "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n" + +// "NhAAAAAwEAAQAAAQEAvummQZm1FUFc/cV5nQBeowhjX4vIU4kBmyPmXHMViX4ORvWvD1yi\n" + +// "oxcaawPpP9QconpzjdCrNbmw0oZNt9UKlmrOU34YTRD5LFlEVOYjr/21/SO5yDGog8xJBU\n" + +// "HQYnXY5L2q9EXKOF45e5P6gSGUovrhePEsaniuQN48GIObPCOFkEN0ZV2DqRsn3It1vY+D\n" + +// "GiSb5EaZ2sNkudyzYfgFxcCbqBXmDa1WeyX5xYh8wldBJLUH+pO4gPoTXXX4UI4yNdDmPD\n" + +// "BWFvPVIOdpfdBnDbEp1AoE5Jx/+tbwFBIEvTPOECtOUKDGIlXXIH0I4waHbwf6EnHD5+BR\n" + +// "N0XwrzSkuwAAA9DYV/7H2Ff+xwAAAAdzc2gtcnNhAAABAQC+6aZBmbUVQVz9xXmdAF6jCG\n" + +// "Nfi8hTiQGbI+ZccxWJfg5G9a8PXKKjFxprA+k/1ByienON0Ks1ubDShk231QqWas5TfhhN\n" + +// "EPksWURU5iOv/bX9I7nIMaiDzEkFQdBiddjkvar0Rco4Xjl7k/qBIZSi+uF48SxqeK5A3j\n" + +// "wYg5s8I4WQQ3RlXYOpGyfci3W9j4MaJJvkRpnaw2S53LNh+AXFwJuoFeYNrVZ7JfnFiHzC\n" + +// "V0EktQf6k7iA+hNddfhQjjI10OY8MFYW89Ug52l90GcNsSnUCgTknH/61vAUEgS9M84QK0\n" + +// "5QoMYiVdcgfQjjBodvB/oSccPn4FE3RfCvNKS7AAAAAwEAAQAAAQArRruxUy6BSvfRbtpK\n" + +// "hLLvMg+UsRMQHJaInHKzskLHkBOcckTkrpMPdUU/zPsqxOJY0nkvRIYK/7TdhCRJ77ker8\n" + +// "dllcfccGSLcRDUTfb5BgIjB94tS1Rvy/chgfHC4APyliwSg197t6BAKyM18m7HIyfJSqJO\n" + +// "4FxfyADHbc3aq654tu+eaUtD7TEN1bH6PKMDvwSioMLgKU43GQeDJZbqamBE9y+KVhVx9y\n" + +// "3DEHrOPkRkZIG33y9j7B/i0vl+WnwUTzmLGRR0U6J9wrzyANL8ODYaAvk4FvUED8hQ72jh\n" + +// "NpAXsSgf6COUE1sUnO5DOwN1zHBNHaSo73Qu7aKZtL4BAAAAgDBW3ItiqU9Ip34KtLaayK\n" + +// "/BkRDDwFNvAxpOw9alpfbLGF5xbVjRN4wy7HJ4eA+7JJnx6A6xYrzykbPP+dnUnfzYuxH8\n" + +// "MrihOkYipw1VaR6/0XH+apmE1SmotuYbl+bpl9dlZYUI0pJ8wldqoDCNlSOcLy77HnKwu9\n" + +// "GpJx9KmW9WAAAAgQDdnrwfVv5trAuZZIcw2vLRWhoDT196k/Ty1GP4zFpDttb8OyZ8Ygpx\n" + +// "oA5PhYyl5M1g/2oR/Rpp3vfKDVThfn/bCnMtAbUHMfvYK3Oufvq5JmzT1rgGr3MEek+JBR\n" + +// "O17I87m4GE7iM1LzCUs2G/fKt2uoVXdniv0Vn0iCiZZc7JmwAAAIEA3IdsccarkUfFcQ2c\n" + +// "4TdHrx/RGmoTAO6k1xOHXZjWPmerinuOspIJL/ymWfqIxABCjub3UHyP7ap+1+AAnk+TMU\n" + +// "eR3tLEp9tRM6n0Td56DnQ9Q+RZhPqR486/teZ33cMBMHg52aIs/3AzMpK9xTFCRgqsKa6e\n" + +// "ednMB4Q1txvHU2EAAAAbemhhbmdsaW4zM0B6aGFuZ2xpbjMzLmxvY2Fs\n" + +// "-----END OPENSSH PRIVATE KEY-----"; +// +// byte[] Bytes3 = null; +// try { +// Bytes3 = new PemReader(new StringReader(str3)).readPemObject().getContent(); +// } catch (IOException e1) { +// e1.printStackTrace(); +// } +// assert Bytes3 != null; +// System.out.println(Hex.toHexString(Bytes3)); +//// System.out.println(Hex.toHexString(Base64.decode("oNE9iA4ZyuZLbpEL7B29NaxGi4puT2Y5RDaMoEkoAKI"))); +//// String test = "1ac477fa"; +//// byte[] testBytes = Hex.decode(test); +//// +//// System.out.println(Base64.toBase64String(testBytes)); +// +// byte[] AUTH_MAGIC = Strings.toByteArray("openssh-key-v1\0"); +// System.out.println(Hex.toHexString(AUTH_MAGIC)); +// System.out.println(Base64.toBase64String(AUTH_MAGIC)); +// String privKeyStr = "-----BEGIN OPENSSH PRIVATE KEY-----\n" + +// "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n" + +// "NhAAAAAwEAAQAAAQEAmMCzeBF8u4NF7oL+JUH6Lo2wEYuPID0sVbqbRrEqBqrEtNHvawO7\n" + +// "9KsxSmvWYZ8NVpIwpxF0WADIggCWJDP5hiPJm96pHHTYRlmZj56KVfg+OgkxQdeMnkfZo6\n" + +// "Dj17OKY198xr3iseTcfI73aBXsG0wrXTdMdV1k4zU+W16j/+IF5CxDRFObS7FlQDrtDBPz\n" + +// "Xv/YDLowLQ6KJSdfNWvT9Om7xKSMOXC7VJ7JuQrbwboi+1gV8QyfyAEiayjRgXSvMYm9fi\n" + +// "m/LTSwE+g49uQcMpaokTYW+ZdTYuGiqxNhakhHOTcefnLEDBJfTASd6RLCxwTW6IQy/o28\n" + +// "C4LkVQ+giQAAA9AaxHf6GsR3+gAAAAdzc2gtcnNhAAABAQCYwLN4EXy7g0Xugv4lQfoujb\n" + +// "ARi48gPSxVuptGsSoGqsS00e9rA7v0qzFKa9Zhnw1WkjCnEXRYAMiCAJYkM/mGI8mb3qkc\n" + +// "dNhGWZmPnopV+D46CTFB14yeR9mjoOPXs4pjX3zGveKx5Nx8jvdoFewbTCtdN0x1XWTjNT\n" + +// "5bXqP/4gXkLENEU5tLsWVAOu0ME/Ne/9gMujAtDoolJ181a9P06bvEpIw5cLtUnsm5CtvB\n" + +// "uiL7WBXxDJ/IASJrKNGBdK8xib1+Kb8tNLAT6Dj25BwylqiRNhb5l1Ni4aKrE2FqSEc5Nx\n" + +// "5+csQMEl9MBJ3pEsLHBNbohDL+jbwLguRVD6CJAAAAAwEAAQAAAQARfhfPSylei9TpUGTs\n" + +// "PVb6F82u5K16QqceFiWL/ePTKaEnF9d0CNRwW15kqF6/hShQ3qLlrvEE1uofQRPwh2cuvl\n" + +// "BrIh95m8PcoowcT0qGN8xgdwcGBDodMhsxSs5suCnD4X53f+1C8/Nv7CtW5xPHuHxKy3dd\n" + +// "BVn1TvaaHgdn2PwJVKtZp+WVG3/UHr25nFHd8mYgpeHZqK9AW16N0UEMXMM1u8ZCubVOoS\n" + +// "IGuMAXpTug0xA+BXHo17FcDGKSzcXFzh+urIz5glRp5zFioHBqxNmkKfQkG6C7UxnPGyS/\n" + +// "/J+3lL2lvl0G8kO/5EDFMBhTMEy1NeR2b629S4G1qUxVAAAAgHDwE9kPiVETcxSzI4wotT\n" + +// "1Ee9nKVVD3oGdRqefvX7EUR8bvdv4nCqHPNBx8C6l8zo7fsQD81YL85F4eWbtrdxEijRHX\n" + +// "5m7J/muh/laY1Hq43WCkZGboO4fZ2HHi7oN096FqrKRpvbQGQi1FLbcISUdsitwrs6ywn3\n" + +// "fNx3q+X3V6AAAAgQDJRo9v+0QvldI33cpJKPKiaop5QvfIDzMatD3vLA1qqycgIi4KOtb5\n" + +// "+LP/jgIpCYah/sk+JpKNz/vsZmZmrfaVu9D3Le2LLBgMpEoSO8jOe9WGI4Ew75C7w7AZCa\n" + +// "SyUnHIVX/9D8Y5tx4cKx6Im9AGbNF35XZoKO4KCk5VMTXhnwAAAIEAwkjKIpTYdeAQVTRf\n" + +// "C13kg84Bu5n4WkiLnp1WOCg2GN5RekqprINtpjIMZoB9Fv292Np99La8yvmRoy5qzNHGdm\n" + +// "Q6AMku8jP123jF2J+wDvF714VtZHNvdCYBGJS+rZ81xtJfHhKtZqRAVtbPertOWZeuRm9V\n" + +// "o+/rEuEzgGYGXNcAAAAbemhhbmdsaW4zM0B6aGFuZ2xpbjMzLmxvY2Fs\n" + +// "-----END OPENSSH PRIVATE KEY-----"; +// +// byte[] privKeyBytes = null; +// try { +// privKeyBytes = new PemReader(new StringReader(privKeyStr)).readPemObject().getContent(); +// } catch (IOException e1) { +// e1.printStackTrace(); +// } +// +// assert privKeyBytes != null; +// System.out.println(Hex.toHexString(privKeyBytes)); +// +// +// OpenSSHPrivateKeySpec privKeySpec = new OpenSSHPrivateKeySpec(privKeyBytes); +// +// String privKeyFormat = privKeySpec.getFormat(); +// System.out.println(privKeyFormat); +// +// RSAKeyParameters privKey = (RSAKeyParameters) OpenSSHPrivateKeyUtil.parsePrivateKeyBlob(privKeyBytes); +// +//// BigInteger e = privKey.getPublicExponent(); +//// BigInteger n = privKey.getModulus(); +//// +//// BigInteger d = privKey.getExponent(); +//// BigInteger p = privKey.getP(); +//// BigInteger q = privKey.getQ(); +//// BigInteger dP = privKey.getDP(); +//// BigInteger dQ = privKey.getDQ(); +//// BigInteger qInv = privKey.getQInv(); +// +//// System.out.println(Hex.toHexString(e.toByteArray())); +//// System.out.println(Hex.toHexString(n.toByteArray())); +//// +//// System.out.println(Hex.toHexString(d.toByteArray())); +//// System.out.println(Hex.toHexString(p.toByteArray())); +//// System.out.println(Hex.toHexString(q.toByteArray())); +//// System.out.println(Hex.toHexString(dP.toByteArray())); +//// System.out.println(Hex.toHexString(dQ.toByteArray())); +//// System.out.println(Hex.toHexString(qInv.toByteArray())); +// +// +// +// } +// +//} diff --git a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/Crypto.java b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/Crypto.java index 86dbf55b..2bca057a 100644 --- a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/Crypto.java +++ b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/Crypto.java @@ -106,6 +106,44 @@ public final class Crypto { private Crypto() { } + public static CryptoProvider[] getProviders() { + Collection> providers = pm.getAllProviders(CryptoService.class); + CryptoProvider[] infos = new CryptoProvider[providers.size()]; + + int i = 0; + for (Provider pd : providers) { + CryptoProviderInfo info = getProviderInfo(pd); + infos[i] = info; + } + + return infos; + } + + private static CryptoProviderInfo getProviderInfo(Provider pd) { + Collection functions = pd.getService().getFunctions(); + CryptoAlgorithm[] algorithms = new CryptoAlgorithm[functions.size()]; + int i = 0; + for (CryptoFunction function : functions) { + algorithms[i] = function.getAlgorithm(); + i++; + } + return new CryptoProviderInfo(pd.getFullName(), algorithms); + } + + /** + * 杩斿洖鎸囧畾鍚嶇О鐨勫瘑鐮佹湇鍔℃彁渚涜咃紱濡傛灉涓嶅瓨鍦紝鍒欒繑鍥 null 锛 + * + * @param providerFullName + * @return + */ + public static CryptoProvider getProvider(String providerFullName) { + Provider pd = pm.getProvider(CryptoService.class, providerFullName); + if (pd == null) { + throw new CryptoException("Crypto service provider named [" + providerFullName + "] does not exist!"); + } + return getProviderInfo(pd); + } + public static Collection getAllAlgorithms() { return algorithms.values(); } diff --git a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithm.java b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithm.java index 4f505ba9..b501626f 100644 --- a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithm.java +++ b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithm.java @@ -9,7 +9,7 @@ import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.consts.DataCodes; import com.jd.blockchain.utils.io.BytesUtils; -//@DataContract(code = DataCodes.CRYPTO_ALGORITHM) +@DataContract(code = DataCodes.CRYPTO_ALGORITHM) public interface CryptoAlgorithm { /** @@ -63,7 +63,7 @@ public interface CryptoAlgorithm { * {@link #EXT_ALGORITHM}) 5 绉嶏級; 鎺ヤ笅鏉4浣嶆爣璇嗗瘑閽ョ被鍨嬶紙鍖呮嫭锛歿@link #SYMMETRIC_KEY}, * {@link #ASYMMETRIC_KEY}锛夛紱 鏈鍚8浣嶆槸绠楁硶鍞竴ID锛 */ -// @DataField(primitiveType = PrimitiveType.INT16, order = 0) + @DataField(order = 0, primitiveType = PrimitiveType.INT16) short code(); /** @@ -75,7 +75,13 @@ public interface CryptoAlgorithm { * * @return */ + @DataField(order = 1, primitiveType = PrimitiveType.TEXT) String name(); + + + public static String getString(CryptoAlgorithm algorithm) { + return String.format("%s[%s]", algorithm.name(), (algorithm.code() & 0xFFFF)); + } /** * diff --git a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithmDefinition.java b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithmDefinition.java index 64b6a3e1..4e9f94b0 100644 --- a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithmDefinition.java +++ b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithmDefinition.java @@ -23,16 +23,14 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { @Override public String toString() { - return name + "[" + (code & 0xFFFF) + "]"; + return CryptoAlgorithm.getString(this); } /** * 澹版槑涓椤瑰搱甯岀畻娉曪紱 * - * @param name - * 绠楁硶鍚嶇О锛 - * @param uid - * 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 + * @param name 绠楁硶鍚嶇О锛 + * @param uid 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 * @return */ public static CryptoAlgorithm defineHash(String name, byte uid) { @@ -43,10 +41,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { /** * 澹版槑涓椤归潪瀵圭О瀵嗙爜绠楁硶锛 * - * @param name - * 绠楁硶鍚嶇О锛 - * @param uid - * 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 + * @param name 绠楁硶鍚嶇О锛 + * @param uid 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 * @return */ public static CryptoAlgorithm defineSignature(String name, boolean encryptable, byte uid) { @@ -62,10 +58,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { /** * 澹版槑涓椤归潪瀵圭О鍔犲瘑绠楁硶锛 * - * @param name - * 绠楁硶鍚嶇О锛 - * @param uid - * 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 + * @param name 绠楁硶鍚嶇О锛 + * @param uid 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 * @return */ public static CryptoAlgorithm defineAsymmetricEncryption(String name, byte uid) { @@ -76,10 +70,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { /** * 澹版槑涓椤瑰绉板瘑鐮佺畻娉曪紱 * - * @param name - * 绠楁硶鍚嶇О锛 - * @param uid - * 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 + * @param name 绠楁硶鍚嶇О锛 + * @param uid 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 * @return */ public static CryptoAlgorithm defineSymmetricEncryption(String name, byte uid) { @@ -90,10 +82,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { /** * 澹版槑涓椤归殢鏈烘暟绠楁硶锛 * - * @param name - * 绠楁硶鍚嶇О锛 - * @param uid - * 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 + * @param name 绠楁硶鍚嶇О锛 + * @param uid 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 * @return */ public static CryptoAlgorithm defineRandom(String name, byte uid) { @@ -104,10 +94,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { /** * 澹版槑涓椤规墿灞曠殑瀵嗙爜绠楁硶锛 * - * @param name - * 绠楁硶鍚嶇О锛 - * @param uid - * 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 + * @param name 绠楁硶鍚嶇О锛 + * @param uid 绠楁硶ID锛涢渶瑕佸湪鍚岀被绠楁硶涓繚鎸佸敮涓鎬э紱 * @return */ public static CryptoAlgorithm definExt(String name, byte uid) { diff --git a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoProvider.java b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoProvider.java new file mode 100644 index 00000000..57b06831 --- /dev/null +++ b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoProvider.java @@ -0,0 +1,17 @@ +package com.jd.blockchain.crypto; + +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.binaryproto.DataField; +import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.consts.DataCodes; + +@DataContract(code = DataCodes.METADATA_CRYPTO_SETTING_PROVIDER) +public interface CryptoProvider { + + @DataField(order = 0, primitiveType = PrimitiveType.TEXT) + String getName(); + + @DataField(order = 1, list = true, refContract = true) + CryptoAlgorithm[] getAlgorithms(); + +} diff --git a/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoProviderInfo.java b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoProviderInfo.java new file mode 100644 index 00000000..b0b17231 --- /dev/null +++ b/source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoProviderInfo.java @@ -0,0 +1,24 @@ +package com.jd.blockchain.crypto; + +class CryptoProviderInfo implements CryptoProvider { + + private String name; + + private CryptoAlgorithm[] algorithms; + + public CryptoProviderInfo(String name, CryptoAlgorithm[] algorithms) { + this.name = name; + this.algorithms = algorithms; + } + + @Override + public String getName() { + return name; + } + + @Override + public CryptoAlgorithm[] getAlgorithms() { + return algorithms.clone(); + } + +} diff --git a/source/crypto/crypto-pki/pom.xml b/source/crypto/crypto-pki/pom.xml new file mode 100644 index 00000000..9c895b21 --- /dev/null +++ b/source/crypto/crypto-pki/pom.xml @@ -0,0 +1,34 @@ + + + + crypto + com.jd.blockchain + 0.9.0-SNAPSHOT + + 4.0.0 + + crypto-pki + + + + com.jd.blockchain + crypto-framework + ${project.version} + + + org.bouncycastle + bcprov-jdk15on + 1.61 + + + + org.bouncycastle + bcpkix-jdk15on + 1.61 + + + + + \ No newline at end of file diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/PKIAlgorithm.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/PKIAlgorithm.java new file mode 100644 index 00000000..0aff4c6b --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/PKIAlgorithm.java @@ -0,0 +1,26 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.CryptoAlgorithm; +import com.jd.blockchain.crypto.CryptoAlgorithmDefinition; + +/** + * @author zhanglin33 + * @title: PKIAlgorithm + * @description: TODO + * @date 2019-05-15, 16:34 + */ +public class PKIAlgorithm { + + public static final CryptoAlgorithm SHA1WITHRSA2048 = CryptoAlgorithmDefinition.defineSignature("SHA1WITHRSA2048", + false, (byte) 31); + + public static final CryptoAlgorithm SHA1WITHRSA4096 = CryptoAlgorithmDefinition.defineSignature("SHA1WITHRSA4096", + false, (byte) 32); + + public static final CryptoAlgorithm SM3WITHSM2 = CryptoAlgorithmDefinition.defineSignature("SM3WITHSM2", + false, (byte) 33); + + private PKIAlgorithm() { + } + +} diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/PKICryptoService.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/PKICryptoService.java new file mode 100644 index 00000000..940d3168 --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/PKICryptoService.java @@ -0,0 +1,38 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.CryptoFunction; +import com.jd.blockchain.crypto.CryptoService; +import com.jd.blockchain.provider.NamedProvider; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * @author zhanglin33 + * @title: PKICryptoService + * @description: TODO + * @date 2019-05-15, 16:35 + */ +@NamedProvider("PKI-SOFTWARE") +public class PKICryptoService implements CryptoService { + + public static final SHA1WITHRSA2048SignatureFunction SHA1WITHRSA2048 = new SHA1WITHRSA2048SignatureFunction(); + + public static final SHA1WITHRSA4096SignatureFunction SHA1WITHRSA4096 = new SHA1WITHRSA4096SignatureFunction(); + + public static final SM3WITHSM2SignatureFunction SM3WITHSM2 = new SM3WITHSM2SignatureFunction(); + + private static final Collection FUNCTIONS; + + static { + List funcs = Arrays.asList(SHA1WITHRSA2048, SHA1WITHRSA4096, SM3WITHSM2); + FUNCTIONS = Collections.unmodifiableList(funcs); + } + + @Override + public Collection getFunctions() { + return FUNCTIONS; + } +} diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA2048SignatureFunction.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA2048SignatureFunction.java new file mode 100644 index 00000000..e8eafdad --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA2048SignatureFunction.java @@ -0,0 +1,220 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.*; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.math.BigInteger; +import java.security.*; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import static com.jd.blockchain.crypto.BaseCryptoKey.KEY_TYPE_BYTES; +import static com.jd.blockchain.crypto.CryptoBytes.ALGORYTHM_CODE_SIZE; +import static com.jd.blockchain.crypto.CryptoKeyType.PRIVATE; +import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; +import static com.jd.blockchain.crypto.service.pki.PKIAlgorithm.SHA1WITHRSA2048; + +/** + * @author zhanglin33 + * @title: SHA1WITHRSA2048SignatureFunction + * @description: TODO + * @date 2019-05-15, 16:37 + */ +public class SHA1WITHRSA2048SignatureFunction implements SignatureFunction { + + private static final int RAW_PUBKEY_SIZE = 259; + private static final int RAW_PRIVKEY_SIZE = 1155; + + private static final int RAW_SIGNATUREDIGEST_SIZE = 256; + + private static final AlgorithmIdentifier RSA_ALGORITHM_IDENTIFIER = + new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); + + @Override + public SignatureDigest sign(PrivKey privKey, byte[] data) { + + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + + if (rawPrivKeyBytes.length < RAW_PRIVKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (privKey.getAlgorithm() != SHA1WITHRSA2048.code()) { + throw new CryptoException("This key is not SHA1WITHRSA2048 private key!"); + } + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivKeyBytes); + + KeyFactory keyFactory; + RSAPrivateCrtKey rawPrivKey; + Signature signer; + byte[] signature; + + try { + keyFactory = KeyFactory.getInstance("RSA"); + rawPrivKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec); + signer = Signature.getInstance("SHA1withRSA"); + signer.initSign(rawPrivKey); + signer.update(data); + signature = signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) { + throw new CryptoException(e.getMessage(), e); + } + + return new SignatureDigest(SHA1WITHRSA2048, signature); + } + + @Override + public boolean verify(SignatureDigest digest, PubKey pubKey, byte[] data) { + + byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); + byte[] rawDigestBytes = digest.getRawDigest(); + + if (rawPubKeyBytes.length < RAW_PUBKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (pubKey.getAlgorithm() != SHA1WITHRSA2048.code()) { + throw new CryptoException("This key is not SHA1WITHRSA2048 public key!"); + } + + if (digest.getAlgorithm() != SHA1WITHRSA2048.code() || rawDigestBytes.length != RAW_SIGNATUREDIGEST_SIZE) { + throw new CryptoException("This is not SHA1WITHRSA2048 signature digest!"); + } + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(rawPubKeyBytes); + + KeyFactory keyFactory; + RSAPublicKey rawPubKey; + Signature verifier; + boolean isValid; + + try { + keyFactory = KeyFactory.getInstance("RSA"); + rawPubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec); + verifier = Signature.getInstance("SHA1withRSA"); + verifier.initVerify(rawPubKey); + verifier.update(data); + isValid = verifier.verify(rawDigestBytes); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) { + throw new CryptoException(e.getMessage(), e); + } + + return isValid; + } + + @Override + public boolean supportPubKey(byte[] pubKeyBytes) { + return pubKeyBytes.length > (ALGORYTHM_CODE_SIZE + KEY_TYPE_BYTES + RAW_PUBKEY_SIZE) + && CryptoAlgorithm.match(SHA1WITHRSA2048, pubKeyBytes) + && pubKeyBytes[ALGORYTHM_CODE_SIZE] == PUBLIC.CODE; + } + + @Override + public PubKey resolvePubKey(byte[] pubKeyBytes) { + if (supportPubKey(pubKeyBytes)) { + return new PubKey(pubKeyBytes); + } else { + throw new CryptoException("pubKeyBytes are invalid!"); + } + } + + @Override + public boolean supportPrivKey(byte[] privKeyBytes) { + return privKeyBytes.length > (ALGORYTHM_CODE_SIZE + KEY_TYPE_BYTES + RAW_PRIVKEY_SIZE) + && CryptoAlgorithm.match(SHA1WITHRSA2048, privKeyBytes) + && privKeyBytes[ALGORYTHM_CODE_SIZE] == PRIVATE.CODE; + } + + @Override + public PrivKey resolvePrivKey(byte[] privKeyBytes) { + if (supportPrivKey(privKeyBytes)) { + return new PrivKey(privKeyBytes); + } else { + throw new CryptoException("privKeyBytes are invalid!"); + } + } + + @Override + public PubKey retrievePubKey(PrivKey privKey) { + + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + + if (rawPrivKeyBytes.length < RAW_PRIVKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (privKey.getAlgorithm() != SHA1WITHRSA2048.code()) { + throw new CryptoException("This key is not SHA1WITHRSA2048 private key!"); + } + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivKeyBytes); + + KeyFactory keyFactory; + RSAPrivateCrtKey rawPrivKey; + byte[] rawPubKeyBytes; + try { + keyFactory = KeyFactory.getInstance("RSA"); + rawPrivKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec); + BigInteger modulus = rawPrivKey.getModulus(); + BigInteger exponent = rawPrivKey.getPublicExponent(); + rawPubKeyBytes = KeyUtil.getEncodedSubjectPublicKeyInfo(RSA_ALGORITHM_IDENTIFIER, + new org.bouncycastle.asn1.pkcs.RSAPublicKey(modulus, exponent)); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new CryptoException(e.getMessage(), e); + } + + return new PubKey(SHA1WITHRSA2048, rawPubKeyBytes); + } + + @Override + public boolean supportDigest(byte[] digestBytes) { + return digestBytes.length == (RAW_SIGNATUREDIGEST_SIZE + ALGORYTHM_CODE_SIZE) + && CryptoAlgorithm.match(SHA1WITHRSA2048, digestBytes); + } + + @Override + public SignatureDigest resolveDigest(byte[] digestBytes) { + if (supportDigest(digestBytes)) { + return new SignatureDigest(digestBytes); + } else { + throw new CryptoException("digestBytes are invalid!"); + } + } + + @Override + public AsymmetricKeypair generateKeypair() { + + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + KeyPairGenerator generator; + PublicKey pubKey; + PrivateKey privKey; + try { + generator = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME); + generator.initialize(2048); + KeyPair keyPair = generator.generateKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + throw new CryptoException(e.getMessage(), e); + } + + byte[] pubKeyBytes = pubKey.getEncoded(); + byte[] privKeyBytes = privKey.getEncoded(); + + return new AsymmetricKeypair(new PubKey(SHA1WITHRSA2048, pubKeyBytes), + new PrivKey(SHA1WITHRSA2048, privKeyBytes)); + } + + @Override + public CryptoAlgorithm getAlgorithm() { + return SHA1WITHRSA2048; + } +} diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA4096SignatureFunction.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA4096SignatureFunction.java new file mode 100644 index 00000000..486096bb --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA4096SignatureFunction.java @@ -0,0 +1,220 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.*; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.math.BigInteger; +import java.security.*; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import static com.jd.blockchain.crypto.BaseCryptoKey.KEY_TYPE_BYTES; +import static com.jd.blockchain.crypto.CryptoBytes.ALGORYTHM_CODE_SIZE; +import static com.jd.blockchain.crypto.CryptoKeyType.PRIVATE; +import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; +import static com.jd.blockchain.crypto.service.pki.PKIAlgorithm.SHA1WITHRSA4096; + +/** + * @author zhanglin33 + * @title: SHA1WITHRSA4096SignatureFunction + * @description: TODO + * @date 2019-05-15, 17:13 + */ +public class SHA1WITHRSA4096SignatureFunction implements SignatureFunction { + private static final int RAW_PUBKEY_SIZE = 515; + private static final int RAW_PRIVKEY_SIZE = 2307; + + private static final int RAW_SIGNATUREDIGEST_SIZE = 512; + + private static final AlgorithmIdentifier RSA_ALGORITHM_IDENTIFIER = + new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); + + @Override + public SignatureDigest sign(PrivKey privKey, byte[] data) { + + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + + if (rawPrivKeyBytes.length < RAW_PRIVKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (privKey.getAlgorithm() != SHA1WITHRSA4096.code()) { + throw new CryptoException("This key is not SHA1WITHRSA4096 private key!"); + } + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivKeyBytes); + + KeyFactory keyFactory; + RSAPrivateCrtKey rawPrivKey; + Signature signer; + byte[] signature; + + try { + keyFactory = KeyFactory.getInstance("RSA"); + rawPrivKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec); + signer = Signature.getInstance("SHA1withRSA"); + signer.initSign(rawPrivKey); + signer.update(data); + signature = signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) { + throw new CryptoException(e.getMessage(), e); + } + + return new SignatureDigest(SHA1WITHRSA4096, signature); + } + + @Override + public boolean verify(SignatureDigest digest, PubKey pubKey, byte[] data) { + + byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); + byte[] rawDigestBytes = digest.getRawDigest(); + + if (rawPubKeyBytes.length < RAW_PUBKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (pubKey.getAlgorithm() != SHA1WITHRSA4096.code()) { + throw new CryptoException("This key is not SHA1WITHRSA4096 public key!"); + } + + if (digest.getAlgorithm() != SHA1WITHRSA4096.code() || rawDigestBytes.length != RAW_SIGNATUREDIGEST_SIZE) { + throw new CryptoException("This is not SHA1WITHRSA4096 signature digest!"); + } + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(rawPubKeyBytes); + + KeyFactory keyFactory; + RSAPublicKey rawPubKey; + Signature verifier; + boolean isValid; + + try { + keyFactory = KeyFactory.getInstance("RSA"); + rawPubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec); + verifier = Signature.getInstance("SHA1withRSA"); + verifier.initVerify(rawPubKey); + verifier.update(data); + isValid = verifier.verify(rawDigestBytes); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) { + throw new CryptoException(e.getMessage(), e); + } + + return isValid; + } + + @Override + public boolean supportPubKey(byte[] pubKeyBytes) { + return pubKeyBytes.length > (ALGORYTHM_CODE_SIZE + KEY_TYPE_BYTES + RAW_PUBKEY_SIZE) + && CryptoAlgorithm.match(SHA1WITHRSA4096, pubKeyBytes) + && pubKeyBytes[ALGORYTHM_CODE_SIZE] == PUBLIC.CODE; + } + + @Override + public PubKey resolvePubKey(byte[] pubKeyBytes) { + if (supportPubKey(pubKeyBytes)) { + return new PubKey(pubKeyBytes); + } else { + throw new CryptoException("pubKeyBytes are invalid!"); + } + } + + @Override + public boolean supportPrivKey(byte[] privKeyBytes) { + return privKeyBytes.length > (ALGORYTHM_CODE_SIZE + KEY_TYPE_BYTES + RAW_PRIVKEY_SIZE) + && CryptoAlgorithm.match(SHA1WITHRSA4096, privKeyBytes) + && privKeyBytes[ALGORYTHM_CODE_SIZE] == PRIVATE.CODE; + } + + @Override + public PrivKey resolvePrivKey(byte[] privKeyBytes) { + if (supportPrivKey(privKeyBytes)) { + return new PrivKey(privKeyBytes); + } else { + throw new CryptoException("privKeyBytes are invalid!"); + } + } + + @Override + public PubKey retrievePubKey(PrivKey privKey) { + + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + + if (rawPrivKeyBytes.length < RAW_PRIVKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (privKey.getAlgorithm() != SHA1WITHRSA4096.code()) { + throw new CryptoException("This key is not SHA1WITHRSA4096 private key!"); + } + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivKeyBytes); + + KeyFactory keyFactory; + RSAPrivateCrtKey rawPrivKey; + byte[] rawPubKeyBytes; + try { + keyFactory = KeyFactory.getInstance("RSA"); + rawPrivKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec); + BigInteger modulus = rawPrivKey.getModulus(); + BigInteger exponent = rawPrivKey.getPublicExponent(); + rawPubKeyBytes = KeyUtil.getEncodedSubjectPublicKeyInfo(RSA_ALGORITHM_IDENTIFIER, + new org.bouncycastle.asn1.pkcs.RSAPublicKey(modulus, exponent)); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new CryptoException(e.getMessage(), e); + } + + return new PubKey(SHA1WITHRSA4096, rawPubKeyBytes); + } + + @Override + public boolean supportDigest(byte[] digestBytes) { + return digestBytes.length == (RAW_SIGNATUREDIGEST_SIZE + ALGORYTHM_CODE_SIZE) + && CryptoAlgorithm.match(SHA1WITHRSA4096, digestBytes); + } + + @Override + public SignatureDigest resolveDigest(byte[] digestBytes) { + if (supportDigest(digestBytes)) { + return new SignatureDigest(digestBytes); + } else { + throw new CryptoException("digestBytes are invalid!"); + } + } + + @Override + public AsymmetricKeypair generateKeypair() { + + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + KeyPairGenerator generator; + PublicKey pubKey; + PrivateKey privKey; + try { + generator = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME); + generator.initialize(4096); + KeyPair keyPair = generator.generateKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + throw new CryptoException(e.getMessage(), e); + } + + byte[] pubKeyBytes = pubKey.getEncoded(); + byte[] privKeyBytes = privKey.getEncoded(); + + return new AsymmetricKeypair(new PubKey(SHA1WITHRSA4096, pubKeyBytes), + new PrivKey(SHA1WITHRSA4096, privKeyBytes)); + } + + + @Override + public CryptoAlgorithm getAlgorithm() { + return SHA1WITHRSA4096; + } +} diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SM3WITHSM2SignatureFunction.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SM3WITHSM2SignatureFunction.java new file mode 100644 index 00000000..5b9978d7 --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/service/pki/SM3WITHSM2SignatureFunction.java @@ -0,0 +1,236 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.*; +import org.bouncycastle.asn1.gm.GMObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.custom.gm.SM2P256V1Curve; + +import java.math.BigInteger; +import java.security.*; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import static com.jd.blockchain.crypto.BaseCryptoKey.KEY_TYPE_BYTES; +import static com.jd.blockchain.crypto.CryptoBytes.ALGORYTHM_CODE_SIZE; +import static com.jd.blockchain.crypto.CryptoKeyType.PRIVATE; +import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; +import static com.jd.blockchain.crypto.service.pki.PKIAlgorithm.SM3WITHSM2; + +/** + * @author zhanglin33 + * @title: SM3WITHSM2SignatureFunction + * @description: TODO + * @date 2019-05-15, 16:39 + */ +public class SM3WITHSM2SignatureFunction implements SignatureFunction { + private static final int RAW_PUBKEY_SIZE = 65; + private static final int RAW_PRIVKEY_SIZE = 32 + 65; + + private static final int RAW_SIGNATUREDIGEST_SIZE = 64; + + private static final SM2P256V1Curve CURVE = new SM2P256V1Curve(); + private static final BigInteger GX = new BigInteger("32C4AE2C1F1981195F9904466A39C994" + + "8FE30BBFF2660BE1715A4589334C74C7", 16); + private static final BigInteger GY = new BigInteger("BC3736A2F4F6779C59BDCEE36B692153" + + "D0A9877CC62A474002DF32E52139F0A0", 16); + private static final ECPoint G = CURVE.createPoint(GX, GY); + + private static final AlgorithmIdentifier SM2_ALGORITHM_IDENTIFIER = new AlgorithmIdentifier( + X9ObjectIdentifiers.id_ecPublicKey, GMObjectIdentifiers.sm2p256v1); + + + @Override + public SignatureDigest sign(PrivKey privKey, byte[] data) { + + Security.addProvider(new BouncyCastleProvider()); + + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + + if (rawPrivKeyBytes.length < RAW_PRIVKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (privKey.getAlgorithm() != SM3WITHSM2.code()) { + throw new CryptoException("This key is not SM3WITHSM2 private key!"); + } + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivKeyBytes); + + KeyFactory keyFactory; + ECPrivateKey rawPrivKey; + Signature signer; + byte[] signature; + + try { + keyFactory = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME); + rawPrivKey = (ECPrivateKey) keyFactory.generatePrivate(keySpec); + signer = Signature.getInstance("SM3withSM2", BouncyCastleProvider.PROVIDER_NAME); + + signer.initSign(rawPrivKey); + signer.update(data); + signature = signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | + InvalidKeySpecException | NoSuchProviderException e) { + throw new CryptoException(e.getMessage(), e); + } + + return new SignatureDigest(SM3WITHSM2, signature); + } + + @Override + public boolean verify(SignatureDigest digest, PubKey pubKey, byte[] data) { + + Security.addProvider(new BouncyCastleProvider()); + + byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); + byte[] rawDigestBytes = digest.getRawDigest(); + + if (rawPubKeyBytes.length < RAW_PUBKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (pubKey.getAlgorithm() != SM3WITHSM2.code()) { + throw new CryptoException("This key is not SM3WITHSM2 public key!"); + } + + if (digest.getAlgorithm() != SM3WITHSM2.code() || rawDigestBytes.length < RAW_SIGNATUREDIGEST_SIZE) { + throw new CryptoException("This is not SM3WITHSM2 signature digest!"); + } + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(rawPubKeyBytes); + + KeyFactory keyFactory; + ECPublicKey rawPubKey; + Signature verifier; + boolean isValid; + + try { + keyFactory = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME); + rawPubKey = (ECPublicKey) keyFactory.generatePublic(keySpec); + verifier = Signature.getInstance("SM3withSM2", BouncyCastleProvider.PROVIDER_NAME); + verifier.initVerify(rawPubKey); + verifier.update(data); + isValid = verifier.verify(rawDigestBytes); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException + | NoSuchProviderException e) { + throw new CryptoException(e.getMessage(), e); + } + + return isValid; + } + + @Override + public boolean supportPubKey(byte[] pubKeyBytes) { + return pubKeyBytes.length > (ALGORYTHM_CODE_SIZE + KEY_TYPE_BYTES + RAW_PUBKEY_SIZE) + && CryptoAlgorithm.match(SM3WITHSM2, pubKeyBytes) + && pubKeyBytes[ALGORYTHM_CODE_SIZE] == PUBLIC.CODE; + } + + @Override + public PubKey resolvePubKey(byte[] pubKeyBytes) { + if (supportPubKey(pubKeyBytes)) { + return new PubKey(pubKeyBytes); + } else { + throw new CryptoException("pubKeyBytes are invalid!"); + } + } + + @Override + public boolean supportPrivKey(byte[] privKeyBytes) { + return privKeyBytes.length > (ALGORYTHM_CODE_SIZE + KEY_TYPE_BYTES + RAW_PRIVKEY_SIZE) + && CryptoAlgorithm.match(SM3WITHSM2, privKeyBytes) + && privKeyBytes[ALGORYTHM_CODE_SIZE] == PRIVATE.CODE; + } + + @Override + public PrivKey resolvePrivKey(byte[] privKeyBytes) { + if (supportPrivKey(privKeyBytes)) { + return new PrivKey(privKeyBytes); + } else { + throw new CryptoException("privKeyBytes are invalid!"); + } + } + + @Override + public PubKey retrievePubKey(PrivKey privKey) { + + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + + if (rawPrivKeyBytes.length < RAW_PRIVKEY_SIZE) { + throw new CryptoException("This key has wrong format!"); + } + + if (privKey.getAlgorithm() != SM3WITHSM2.code()) { + throw new CryptoException("This key is not SM3WITHSM2 private key!"); + } + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivKeyBytes); + + KeyFactory keyFactory; + ECPrivateKey rawPrivKey; + byte[] rawPubKeyBytes; + try { + keyFactory = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME); + rawPrivKey = (ECPrivateKey) keyFactory.generatePrivate(keySpec); + BigInteger d = rawPrivKey.getS(); + ECPoint Q = G.multiply(d).normalize(); + rawPubKeyBytes = KeyUtil.getEncodedSubjectPublicKeyInfo(SM2_ALGORITHM_IDENTIFIER, + Q.getEncoded(false)); + } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchProviderException e) { + throw new CryptoException(e.getMessage(), e); + } + + return new PubKey(SM3WITHSM2, rawPubKeyBytes); + } + + @Override + public boolean supportDigest(byte[] digestBytes) { + return digestBytes.length > (RAW_SIGNATUREDIGEST_SIZE + ALGORYTHM_CODE_SIZE) + && CryptoAlgorithm.match(SM3WITHSM2, digestBytes); + } + + @Override + public SignatureDigest resolveDigest(byte[] digestBytes) { + if (supportDigest(digestBytes)) { + return new SignatureDigest(digestBytes); + } else { + throw new CryptoException("digestBytes are invalid!"); + } + } + + @Override + public AsymmetricKeypair generateKeypair() { + + Security.addProvider(new BouncyCastleProvider()); + KeyPairGenerator generator; + PublicKey pubKey; + PrivateKey privKey; + try { + generator = KeyPairGenerator.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME); + generator.initialize(new ECNamedCurveGenParameterSpec("sm2p256v1")); + KeyPair keyPair = generator.generateKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) { + throw new CryptoException(e.getMessage(), e); + } + + byte[] pubKeyBytes = pubKey.getEncoded(); + byte[] privKeyBytes = privKey.getEncoded(); + + return new AsymmetricKeypair(new PubKey(SM3WITHSM2, pubKeyBytes), + new PrivKey(SM3WITHSM2, privKeyBytes)); + } + @Override + public CryptoAlgorithm getAlgorithm() { + return SM3WITHSM2; + } +} diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/utils/CSRBuilder.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/utils/CSRBuilder.java new file mode 100644 index 00000000..790cb7db --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/utils/CSRBuilder.java @@ -0,0 +1,129 @@ +package com.jd.blockchain.crypto.utils; + +import com.jd.blockchain.crypto.CryptoException; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.X500NameBuilder; +import org.bouncycastle.asn1.x500.style.BCStrictStyle; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; +import org.bouncycastle.util.encoders.Base64; + +import java.io.IOException; +import java.security.*; + +/** + * @author zhanglin33 + * @title: CSRBuilder + * @description: A builder for certificate signing request, supporting rsa and sm2 + * @date 2019-05-10, 15:10 + */ +public class CSRBuilder { + + private String BC = BouncyCastleProvider.PROVIDER_NAME; + + private PublicKey pubKey; + private PrivateKey privKey; + + private String algoName; + + public void init() { + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + algoName = "SHA1withRSA"; + KeyPairGenerator generator; + try { + generator = KeyPairGenerator.getInstance("RSA", BC); + generator.initialize(2048); + KeyPair keyPair = generator.generateKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + throw new CryptoException(e.getMessage(), e); + } + } + + public void init(String algoName, int KeyLength) { + + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + this.algoName = algoName; + + KeyPairGenerator generator; + KeyPair keyPair; + String[] hashAndSignature = algoName.split("with"); + + try { + switch (hashAndSignature[1]) { + case "RSA": { + generator = KeyPairGenerator.getInstance("RSA", BC); + generator.initialize(KeyLength); + keyPair = generator.generateKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + break; + } + + case "SM2": { + generator = KeyPairGenerator.getInstance("EC", BC); + if (KeyLength != 256) { + throw new CryptoException("SM3withSM2 with unsupported key length [" + + KeyLength +"] in CSR!"); + } + generator.initialize(new ECNamedCurveGenParameterSpec("sm2p256v1")); + keyPair = generator.generateKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + break; + } + + default: throw new CryptoException("Unsupported algorithm [" + algoName + "] with key length [" + + KeyLength +"] in CSR!"); + } + } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) { + throw new CryptoException(e.getMessage(), e); + } + } + + public String buildRequest(String countryName, String stateName, String cityName, + String organizationName, String departmentName, String domainName, + String emailName) { + + String result; + X500NameBuilder nameBuilder = new X500NameBuilder(BCStrictStyle.INSTANCE); + + nameBuilder.addRDN(BCStyle.C, countryName); // a country name, and China is short as CN + nameBuilder.addRDN(BCStyle.ST, stateName); // a state or province name + nameBuilder.addRDN(BCStyle.L, cityName); // a city name + nameBuilder.addRDN(BCStyle.O, organizationName); // an organization or corporation name + nameBuilder.addRDN(BCStyle.OU, departmentName); // a division of your organization name + nameBuilder.addRDN(BCStyle.CN, domainName); // a fully qualified domain name + nameBuilder.addRDN(BCStyle.E, emailName); // an email address + + try { + X500Name x500Name = nameBuilder.build(); + + PKCS10CertificationRequestBuilder requestBuilder + = new JcaPKCS10CertificationRequestBuilder(x500Name, pubKey); + PKCS10CertificationRequest request + = requestBuilder.build(new JcaContentSignerBuilder(algoName).setProvider(BC).build(privKey)); + byte[] csrBytes = request.getEncoded(); + result = Base64.toBase64String(csrBytes); + } catch (OperatorCreationException | IOException e) { + throw new CryptoException(e.getMessage(), e); + } + + return result; + } + + public PublicKey getPubKey() { + return pubKey; + } + + public PrivateKey getPrivKey() { + return privKey; + } +} diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/utils/CertParser.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/utils/CertParser.java new file mode 100644 index 00000000..8267d28b --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/utils/CertParser.java @@ -0,0 +1,131 @@ +package com.jd.blockchain.crypto.utils; + +import com.jd.blockchain.crypto.CryptoException; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.io.pem.PemReader; + +import javax.security.auth.x500.X500Principal; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.StringReader; +import java.security.*; +import java.security.cert.*; +import java.util.Date; + +/** + * @author zhanglin33 + * @title: CertParser + * @description: A parser for standard certificate, along with validation process + * @date 2019-05-10, 15:17 + */ +public class CertParser { + + private PublicKey pubKey; + private String sigAlgName; + private String userName; + private String issuerName; + + private Date startTime; + private Date endTime; + + public void parse(String userCertificate, String issuerCertificate) { + + X509Certificate issuerCert = parseWithoutValidationProcess(issuerCertificate); + + // ensure that the certificate is within the validity period + try { + issuerCert.checkValidity(); + } catch (CertificateExpiredException | CertificateNotYetValidException e) { + throw new CryptoException(e.getMessage(), e); + } + PublicKey issuerPubKey = issuerCert.getPublicKey(); + X500Principal issuerPrincipal = issuerCert.getSubjectX500Principal(); + + X509Certificate userCert = parseWithoutValidationProcess(userCertificate); + + // check consistency between issuer's names in userCertificate and issuerCertificate + if (!userCert.getIssuerX500Principal().equals(issuerPrincipal)) { + throw new CryptoException("Issuer in the targeted certificate is not " + + "compliance with the parent certificate锛"); + } + + try { + userCert.checkValidity(); + } catch (CertificateExpiredException | CertificateNotYetValidException e) { + throw new CryptoException(e.getMessage(), e); + } + + // verify the signature in certificate with issuer's public key + try { + userCert.verify(issuerPubKey); + } catch (CertificateException | NoSuchAlgorithmException + | InvalidKeyException | NoSuchProviderException | SignatureException e) { + throw new CryptoException(e.getMessage(), e); + } + + startTime = userCert.getNotBefore(); + endTime = userCert.getNotAfter(); + + pubKey = userCert.getPublicKey(); + sigAlgName = userCert.getSigAlgName(); + issuerName = userCert.getIssuerX500Principal().getName(); + userName = userCert.getSubjectX500Principal().getName(); + } + + // certificate string in Base64 format + public X509Certificate parseWithoutValidationProcess(String certificate) { + + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + + byte[] certificateBytes; + String BEGIN = "-----BEGIN CERTIFICATE-----"; + String END = "-----END CERTIFICATE-----"; + if (!certificate.startsWith(BEGIN)) { + certificate = certificate.replaceAll("\\n", ""); + certificate = certificate.replaceAll(END, ""); + certificateBytes = Base64.decode(certificate); + } else { + try { + certificateBytes = new PemReader(new StringReader(certificate)).readPemObject().getContent(); + } catch (IOException e) { + throw new CryptoException(e.getMessage(), e); + } + } + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(certificateBytes); + CertificateFactory factory; + X509Certificate cert; + try { + factory = CertificateFactory.getInstance("X509", BouncyCastleProvider.PROVIDER_NAME); + cert = (X509Certificate) factory.generateCertificate(bytesIn); + } catch (CertificateException | NoSuchProviderException e) { + throw new CryptoException(e.getMessage(), e); + } + return cert; + } + + public PublicKey getPubKey() { + return pubKey; + } + + public String getSigAlgName() { + return sigAlgName; + } + + public String getUserName() { + return userName; + } + + public String getIssuerName() { + return issuerName; + } + + public Date getStartTime() { + return startTime; + } + + public Date getEndTime() { + return endTime; + } +} diff --git a/source/crypto/crypto-pki/src/main/resources/META-INF/services/com.jd.blockchain.crypto.CryptoService b/source/crypto/crypto-pki/src/main/resources/META-INF/services/com.jd.blockchain.crypto.CryptoService new file mode 100644 index 00000000..14a8682f --- /dev/null +++ b/source/crypto/crypto-pki/src/main/resources/META-INF/services/com.jd.blockchain.crypto.CryptoService @@ -0,0 +1 @@ +com.jd.blockchain.crypto.service.pki.PKICryptoService \ No newline at end of file diff --git a/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA2048SignatureFunctionTest.java b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA2048SignatureFunctionTest.java new file mode 100644 index 00000000..b7c7d831 --- /dev/null +++ b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA2048SignatureFunctionTest.java @@ -0,0 +1,128 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.*; +import com.jd.blockchain.utils.io.BytesUtils; +import org.junit.Test; + +import java.util.Random; + +import static com.jd.blockchain.crypto.CryptoAlgorithm.*; +import static com.jd.blockchain.crypto.CryptoKeyType.PRIVATE; +import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; +import static org.junit.Assert.*; + +/** + * @author zhanglin33 + * @title: SHA1WITHRSA2048SignatureFunctionTest + * @description: TODO + * @date 2019-05-16, 10:49 + */ +public class SHA1WITHRSA2048SignatureFunctionTest { + + @Test + public void getAlgorithmTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SHA1WITHRSA2048"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + assertEquals(signatureFunction.getAlgorithm().name(), algorithm.name()); + assertEquals(signatureFunction.getAlgorithm().code(), algorithm.code()); + + algorithm = Crypto.getAlgorithm("SHA1withRsa2048"); + assertNotNull(algorithm); + + assertEquals(signatureFunction.getAlgorithm().name(), algorithm.name()); + assertEquals(signatureFunction.getAlgorithm().code(), algorithm.code()); + + algorithm = Crypto.getAlgorithm("rsa2048"); + assertNull(algorithm); + } + + @Test + public void test() { + + // generateKeyPairTest + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SHA1WITHRSA2048"); + assertNotNull(algorithm); + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + PubKey pubKey = keyPair.getPubKey(); + PrivKey privKey = keyPair.getPrivKey(); + assertEquals(PUBLIC.CODE, pubKey.getKeyType().CODE); + assertTrue(pubKey.getRawKeyBytes().length > 259); + assertEquals(PRIVATE.CODE, privKey.getKeyType().CODE); + assertTrue(privKey.getRawKeyBytes().length > 1155); + assertEquals(algorithm.code(), pubKey.getAlgorithm()); + assertEquals(algorithm.code(), privKey.getAlgorithm()); + byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); + byte[] pubKeyTypeBytes = new byte[] { PUBLIC.CODE }; + byte[] privKeyTypeBytes = new byte[] { PRIVATE.CODE }; + byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + assertArrayEquals(BytesUtils.concat(algoBytes, pubKeyTypeBytes, rawPubKeyBytes), pubKey.toBytes()); + assertArrayEquals(BytesUtils.concat(algoBytes, privKeyTypeBytes, rawPrivKeyBytes), privKey.toBytes()); + + // retrievePubKeyTest + PubKey retrievedPubKey = signatureFunction.retrievePubKey(privKey); + assertEquals(pubKey.getKeyType(), retrievedPubKey.getKeyType()); + assertEquals(pubKey.getRawKeyBytes().length, retrievedPubKey.getRawKeyBytes().length); + assertEquals(pubKey.getAlgorithm(), retrievedPubKey.getAlgorithm()); + assertArrayEquals(pubKey.toBytes(), retrievedPubKey.toBytes()); + + // signTest + byte[] data = new byte[1024]; + Random random = new Random(); + random.nextBytes(data); + SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); + byte[] signatureBytes = signatureDigest.toBytes(); + assertEquals(2 + 256, signatureBytes.length); + assertEquals(algorithm.code(), signatureDigest.getAlgorithm()); + assertEquals(PKIAlgorithm.SHA1WITHRSA2048.code(), signatureDigest.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 31 & 0x00FF)), + signatureDigest.getAlgorithm()); + + byte[] rawSinatureBytes = signatureDigest.getRawDigest(); + assertArrayEquals(BytesUtils.concat(algoBytes, rawSinatureBytes), signatureBytes); + + // verifyTest + assertTrue(signatureFunction.verify(signatureDigest, pubKey, data)); + + // supportPrivKeyTest + byte[] privKeyBytes = privKey.toBytes(); + assertTrue(signatureFunction.supportPrivKey(privKeyBytes)); + + // resolvePrivKeyTest + PrivKey resolvedPrivKey = signatureFunction.resolvePrivKey(privKeyBytes); + assertEquals(PRIVATE.CODE, resolvedPrivKey.getKeyType().CODE); + assertEquals(PKIAlgorithm.SHA1WITHRSA2048.code(), resolvedPrivKey.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 31 & 0x00FF)), + resolvedPrivKey.getAlgorithm()); + assertArrayEquals(privKeyBytes, resolvedPrivKey.toBytes()); + + // supportPubKeyTest + byte[] pubKeyBytes = pubKey.toBytes(); + assertTrue(signatureFunction.supportPubKey(pubKeyBytes)); + + // resolvedPubKeyTest + PubKey resolvedPubKey = signatureFunction.resolvePubKey(pubKeyBytes); + assertEquals(PUBLIC.CODE, resolvedPubKey.getKeyType().CODE); + assertEquals(PKIAlgorithm.SHA1WITHRSA2048.code(), resolvedPubKey.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 31 & 0x00FF)), + resolvedPubKey.getAlgorithm()); + assertArrayEquals(pubKeyBytes, resolvedPubKey.toBytes()); + + //supportDigestTest + byte[] signatureDigestBytes = signatureDigest.toBytes(); + assertTrue(signatureFunction.supportDigest(signatureDigestBytes)); + + // resolveDigestTest + SignatureDigest resolvedSignatureDigest = signatureFunction.resolveDigest(signatureDigestBytes); + assertEquals(256, resolvedSignatureDigest.getRawDigest().length); + assertEquals(PKIAlgorithm.SHA1WITHRSA2048.code(), resolvedSignatureDigest.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 31 & 0x00FF)), + resolvedSignatureDigest.getAlgorithm()); + assertArrayEquals(signatureDigestBytes, resolvedSignatureDigest.toBytes()); + } +} diff --git a/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA4096SignatureFunctionTest.java b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA4096SignatureFunctionTest.java new file mode 100644 index 00000000..9444771b --- /dev/null +++ b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SHA1WITHRSA4096SignatureFunctionTest.java @@ -0,0 +1,128 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.*; +import com.jd.blockchain.utils.io.BytesUtils; +import org.junit.Test; + +import java.util.Random; + +import static com.jd.blockchain.crypto.CryptoAlgorithm.ASYMMETRIC_KEY; +import static com.jd.blockchain.crypto.CryptoAlgorithm.SIGNATURE_ALGORITHM; +import static com.jd.blockchain.crypto.CryptoKeyType.PRIVATE; +import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; +import static org.junit.Assert.*; + +/** + * @author zhanglin33 + * @title: SHA1WITHRSA4096SignatureFunctionTest + * @description: TODO + * @date 2019-05-16, 10:49 + */ +public class SHA1WITHRSA4096SignatureFunctionTest { + + @Test + public void getAlgorithmTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SHA1WITHRSA4096"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + assertEquals(signatureFunction.getAlgorithm().name(), algorithm.name()); + assertEquals(signatureFunction.getAlgorithm().code(), algorithm.code()); + + algorithm = Crypto.getAlgorithm("SHA1withRsa4096"); + assertNotNull(algorithm); + + assertEquals(signatureFunction.getAlgorithm().name(), algorithm.name()); + assertEquals(signatureFunction.getAlgorithm().code(), algorithm.code()); + + algorithm = Crypto.getAlgorithm("rsa2048"); + assertNull(algorithm); + } + + //@Test + public void generateKeyPairTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SHA1WITHRSA4096"); + assertNotNull(algorithm); + + AsymmetricKeypair keyPair = Crypto.getSignatureFunction(algorithm).generateKeypair(); + + PubKey pubKey = keyPair.getPubKey(); + PrivKey privKey = keyPair.getPrivKey(); + + assertEquals(PUBLIC.CODE, pubKey.getKeyType().CODE); + assertTrue(pubKey.getRawKeyBytes().length > 515); + assertEquals(PRIVATE.CODE, privKey.getKeyType().CODE); + assertTrue(privKey.getRawKeyBytes().length > 2307); + + assertEquals(algorithm.code(), pubKey.getAlgorithm()); + assertEquals(algorithm.code(), privKey.getAlgorithm()); + + byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); + byte[] pubKeyTypeBytes = new byte[] { PUBLIC.CODE }; + byte[] privKeyTypeBytes = new byte[] { PRIVATE.CODE }; + byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + assertArrayEquals(BytesUtils.concat(algoBytes, pubKeyTypeBytes, rawPubKeyBytes), pubKey.toBytes()); + assertArrayEquals(BytesUtils.concat(algoBytes, privKeyTypeBytes, rawPrivKeyBytes), privKey.toBytes()); + + // retrievePubKeyTest + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + PubKey retrievedPubKey = signatureFunction.retrievePubKey(privKey); + assertEquals(pubKey.getKeyType(), retrievedPubKey.getKeyType()); + assertEquals(pubKey.getRawKeyBytes().length, retrievedPubKey.getRawKeyBytes().length); + assertEquals(pubKey.getAlgorithm(), retrievedPubKey.getAlgorithm()); + assertArrayEquals(pubKey.toBytes(), retrievedPubKey.toBytes()); + + + // signAndVerifyTest + byte[] data = new byte[1024]; + Random random = new Random(); + random.nextBytes(data); + + SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); + byte[] signatureBytes = signatureDigest.toBytes(); + assertEquals(2 + 512, signatureBytes.length); + assertEquals(algorithm.code(), signatureDigest.getAlgorithm()); + assertEquals(PKIAlgorithm.SHA1WITHRSA4096.code(), signatureDigest.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 32 & 0x00FF)), + signatureDigest.getAlgorithm()); + algoBytes = BytesUtils.toBytes(signatureDigest.getAlgorithm()); + byte[] rawSinatureBytes = signatureDigest.getRawDigest(); + assertArrayEquals(BytesUtils.concat(algoBytes, rawSinatureBytes), signatureBytes); + assertTrue(signatureFunction.verify(signatureDigest, pubKey, data)); + + // supportAndResolvePrivKeyTest + byte[] privKeyBytes = privKey.toBytes(); + assertTrue(signatureFunction.supportPrivKey(privKeyBytes)); + PrivKey resolvedPrivKey = signatureFunction.resolvePrivKey(privKeyBytes); + assertEquals(PRIVATE.CODE, resolvedPrivKey.getKeyType().CODE); + assertEquals(PKIAlgorithm.SHA1WITHRSA4096.code(), resolvedPrivKey.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 32 & 0x00FF)), + resolvedPrivKey.getAlgorithm()); + assertArrayEquals(privKeyBytes, resolvedPrivKey.toBytes()); + + // supportAndResolvePubKeyTest + byte[] pubKeyBytes = pubKey.toBytes(); + assertTrue(signatureFunction.supportPubKey(pubKeyBytes)); + PubKey resolvedPubKey = signatureFunction.resolvePubKey(pubKeyBytes); + assertEquals(PUBLIC.CODE, resolvedPubKey.getKeyType().CODE); + assertEquals(PKIAlgorithm.SHA1WITHRSA4096.code(), resolvedPubKey.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 32 & 0x00FF)), + resolvedPubKey.getAlgorithm()); + assertArrayEquals(pubKeyBytes, resolvedPubKey.toBytes()); + + + // supportAndResolveDigestTest + byte[] signatureDigestBytes = signatureDigest.toBytes(); + assertTrue(signatureFunction.supportDigest(signatureDigestBytes)); + SignatureDigest resolvedSignatureDigest = signatureFunction.resolveDigest(signatureDigestBytes); + assertEquals(512, resolvedSignatureDigest.getRawDigest().length); + assertEquals(PKIAlgorithm.SHA1WITHRSA4096.code(), resolvedSignatureDigest.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 32 & 0x00FF)), + resolvedSignatureDigest.getAlgorithm()); + assertArrayEquals(signatureDigestBytes, resolvedSignatureDigest.toBytes()); + } +} diff --git a/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SM3WITHSM2SignatureFunctionTest.java b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SM3WITHSM2SignatureFunctionTest.java new file mode 100644 index 00000000..0b8063a9 --- /dev/null +++ b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/service/pki/SM3WITHSM2SignatureFunctionTest.java @@ -0,0 +1,273 @@ +package com.jd.blockchain.crypto.service.pki; + +import com.jd.blockchain.crypto.*; +import com.jd.blockchain.utils.io.BytesUtils; +import org.junit.Test; + +import java.util.Random; + +import static com.jd.blockchain.crypto.CryptoAlgorithm.ASYMMETRIC_KEY; +import static com.jd.blockchain.crypto.CryptoAlgorithm.SIGNATURE_ALGORITHM; +import static com.jd.blockchain.crypto.CryptoKeyType.PRIVATE; +import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; +import static org.junit.Assert.*; + +/** + * @author zhanglin33 + * @title: SM3WITHSM2SignatureFunctionTest + * @description: TODO + * @date 2019-05-16, 17:04 + */ +public class SM3WITHSM2SignatureFunctionTest { + + @Test + public void getAlgorithmTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + assertEquals(signatureFunction.getAlgorithm().name(), algorithm.name()); + assertEquals(signatureFunction.getAlgorithm().code(), algorithm.code()); + + algorithm = Crypto.getAlgorithm("sm3withsm2"); + assertNotNull(algorithm); + + assertEquals(signatureFunction.getAlgorithm().name(), algorithm.name()); + assertEquals(signatureFunction.getAlgorithm().code(), algorithm.code()); + + algorithm = Crypto.getAlgorithm("sm3withs"); + assertNull(algorithm); + } + + @Test + public void generateKeyPairTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PubKey pubKey = keyPair.getPubKey(); + PrivKey privKey = keyPair.getPrivKey(); + + assertEquals(PUBLIC.CODE, pubKey.getKeyType().CODE); + assertTrue(pubKey.getRawKeyBytes().length > 32); + assertEquals(PRIVATE.CODE, privKey.getKeyType().CODE); + assertTrue(privKey.getRawKeyBytes().length > 65 + 32); + + assertEquals(algorithm.code(), pubKey.getAlgorithm()); + assertEquals(algorithm.code(), privKey.getAlgorithm()); + + byte[] algoBytes = CryptoAlgorithm.getCodeBytes(algorithm); + byte[] pubKeyTypeBytes = new byte[] { PUBLIC.CODE }; + byte[] privKeyTypeBytes = new byte[] { PRIVATE.CODE }; + byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); + byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); + assertArrayEquals(BytesUtils.concat(algoBytes, pubKeyTypeBytes, rawPubKeyBytes), pubKey.toBytes()); + assertArrayEquals(BytesUtils.concat(algoBytes, privKeyTypeBytes, rawPrivKeyBytes), privKey.toBytes()); + } + + @Test + public void retrievePubKeyTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PubKey pubKey = keyPair.getPubKey(); + PrivKey privKey = keyPair.getPrivKey(); + + PubKey retrievedPubKey = signatureFunction.retrievePubKey(privKey); + + assertEquals(pubKey.getKeyType(), retrievedPubKey.getKeyType()); + assertEquals(pubKey.getRawKeyBytes().length, retrievedPubKey.getRawKeyBytes().length); + assertEquals(pubKey.getAlgorithm(), retrievedPubKey.getAlgorithm()); + assertArrayEquals(pubKey.toBytes(), retrievedPubKey.toBytes()); + } + + @Test + public void signTest() { + + byte[] data = new byte[1024]; + Random random = new Random(); + random.nextBytes(data); + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PrivKey privKey = keyPair.getPrivKey(); + SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); + + byte[] signatureBytes = signatureDigest.toBytes(); + + assertTrue(signatureBytes.length > 2 + 64); + assertEquals(algorithm.code(), signatureDigest.getAlgorithm()); + + assertEquals(PKIAlgorithm.SM3WITHSM2.code(), signatureDigest.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 33 & 0x00FF)), + signatureDigest.getAlgorithm()); + + byte[] algoBytes = BytesUtils.toBytes(signatureDigest.getAlgorithm()); + byte[] rawSinatureBytes = signatureDigest.getRawDigest(); + assertArrayEquals(BytesUtils.concat(algoBytes, rawSinatureBytes), signatureBytes); + } + + @Test + public void verifyTest() { + byte[] data = new byte[1024]; + Random random = new Random(); + random.nextBytes(data); + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PubKey pubKey = keyPair.getPubKey(); + PrivKey privKey = keyPair.getPrivKey(); + SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); + + System.out.println(signatureDigest.getRawDigest().length); + assertTrue(signatureFunction.verify(signatureDigest, pubKey, data)); + } + + @Test + public void supportPrivKeyTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PrivKey privKey = keyPair.getPrivKey(); + byte[] privKeyBytes = privKey.toBytes(); + + assertTrue(signatureFunction.supportPrivKey(privKeyBytes)); + } + + @Test + public void resolvePrivKeyTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PrivKey privKey = keyPair.getPrivKey(); + byte[] privKeyBytes = privKey.toBytes(); + + PrivKey resolvedPrivKey = signatureFunction.resolvePrivKey(privKeyBytes); + + assertEquals(PRIVATE.CODE, resolvedPrivKey.getKeyType().CODE); + assertEquals(PKIAlgorithm.SM3WITHSM2.code(), resolvedPrivKey.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 33 & 0x00FF)), + resolvedPrivKey.getAlgorithm()); + assertArrayEquals(privKeyBytes, resolvedPrivKey.toBytes()); + } + + @Test + public void supportPubKeyTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PubKey pubKey = keyPair.getPubKey(); + byte[] pubKeyBytes = pubKey.toBytes(); + + assertTrue(signatureFunction.supportPubKey(pubKeyBytes)); + } + + @Test + public void resolvePubKeyTest() { + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PubKey pubKey = keyPair.getPubKey(); + byte[] pubKeyBytes = pubKey.toBytes(); + + PubKey resolvedPubKey = signatureFunction.resolvePubKey(pubKeyBytes); + + assertEquals(PUBLIC.CODE, resolvedPubKey.getKeyType().CODE); + assertEquals(PKIAlgorithm.SM3WITHSM2.code(), resolvedPubKey.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 33 & 0x00FF)), + resolvedPubKey.getAlgorithm()); + assertArrayEquals(pubKeyBytes, resolvedPubKey.toBytes()); + } + + @Test + public void supportDigestTest() { + + byte[] data = new byte[1024]; + Random random = new Random(); + random.nextBytes(data); + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PrivKey privKey = keyPair.getPrivKey(); + + SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); + + byte[] signatureDigestBytes = signatureDigest.toBytes(); + assertTrue(signatureFunction.supportDigest(signatureDigestBytes)); + } + + @Test + public void resolveDigestTest() { + + byte[] data = new byte[1024]; + Random random = new Random(); + random.nextBytes(data); + + CryptoAlgorithm algorithm = Crypto.getAlgorithm("SM3WITHSM2"); + assertNotNull(algorithm); + + SignatureFunction signatureFunction = Crypto.getSignatureFunction(algorithm); + + AsymmetricKeypair keyPair = signatureFunction.generateKeypair(); + + PrivKey privKey = keyPair.getPrivKey(); + + SignatureDigest signatureDigest = signatureFunction.sign(privKey, data); + + byte[] signatureDigestBytes = signatureDigest.toBytes(); + + SignatureDigest resolvedSignatureDigest = signatureFunction.resolveDigest(signatureDigestBytes); + + assertTrue(resolvedSignatureDigest.getRawDigest().length > 64); + assertEquals(PKIAlgorithm.SM3WITHSM2.code(), resolvedSignatureDigest.getAlgorithm()); + assertEquals((short) (SIGNATURE_ALGORITHM | ASYMMETRIC_KEY | ((byte) 33 & 0x00FF)), + resolvedSignatureDigest.getAlgorithm()); + assertArrayEquals(signatureDigestBytes, resolvedSignatureDigest.toBytes()); + } +} diff --git a/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/utils/CSRBuilderTest.java b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/utils/CSRBuilderTest.java new file mode 100644 index 00000000..62dc4dc2 --- /dev/null +++ b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/utils/CSRBuilderTest.java @@ -0,0 +1,396 @@ +package com.jd.blockchain.crypto.utils; + +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; +import org.bouncycastle.asn1.x500.RDN; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.util.encoders.Base64; +import org.junit.Test; + +import java.io.IOException; +import java.security.*; + +import static org.junit.Assert.*; + +/** + * @author zhanglin33 + * @title: CSRBuilderTest + * @description: TODO + * @date 2019-05-10, 17:22 + */ +public class CSRBuilderTest { + + @Test + public void defaultCSRTest(){ + + String countryName = "CN"; + String stateName = "Beijing"; + String cityName = "Beijing"; + String organizationName = "JD.com"; + String departmentName = "Blockchain Department"; + String domainName = "ledger.jd.com"; + String emailName = "zhanglin33@jd.com"; + + CSRBuilder builder = new CSRBuilder(); + + builder.init(); + String csr = builder.buildRequest(countryName,stateName,cityName, + organizationName,departmentName,domainName, + emailName); + + PublicKey pubKey = builder.getPubKey(); + PrivateKey privKey = builder.getPrivKey(); + + byte[] crsBytes = Base64.decode(csr); + PKCS10CertificationRequest request = null; + try { + request = new PKCS10CertificationRequest(crsBytes); + } catch (IOException e) { + e.printStackTrace(); + } + assertNotNull(request); + assertEquals("1.2.840.113549.1.1.5",request.getSignatureAlgorithm().getAlgorithm().getId()); + byte[] pubKeyBytes = new byte[0]; + try { + pubKeyBytes = request.getSubjectPublicKeyInfo().getEncoded(); + } catch (IOException e) { + e.printStackTrace(); + } + assertArrayEquals(pubKeyBytes,pubKey.getEncoded()); + + RDN[] rdns = request.getSubject().getRDNs(); + assertEquals(BCStyle.C, rdns[0].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.ST, rdns[1].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.L, rdns[2].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.O, rdns[3].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.OU, rdns[4].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.CN, rdns[5].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.E, rdns[6].getFirst().getType().toASN1Primitive()); + + assertEquals("CN", rdns[0].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[1].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[2].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("JD.com", rdns[3].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Blockchain Department", rdns[4].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("ledger.jd.com", rdns[5].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("zhanglin33@jd.com", rdns[6].getFirst().getValue().toASN1Primitive().toString()); + + byte[] signature = request.getSignature(); + + CertificationRequestInfo requestInfo = new CertificationRequestInfo(request.getSubject(),request.getSubjectPublicKeyInfo(),new DERSet()); + byte[] message = new byte[0]; + try { + message = requestInfo.getEncoded(ASN1Encoding.DER); + } catch (IOException e) { + e.printStackTrace(); + } + + Signature signer; + byte[] result = new byte[0]; + try { + signer = Signature.getInstance("SHA1withRSA"); + signer.initSign(privKey); + signer.update(message); + result = signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertArrayEquals(result,signature); + + Signature verifier; + boolean isValid = false; + try { + verifier = Signature.getInstance("SHA1withRSA"); + verifier.initVerify(pubKey); + verifier.update(message); + isValid = verifier.verify(signature); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertTrue(isValid); + } + + @Test + public void SHA1withRSA2048CSRTest(){ + + String countryName = "CN"; + String stateName = "Beijing"; + String cityName = "Beijing"; + String organizationName = "JD.com"; + String departmentName = "Blockchain Department"; + String domainName = "ledger.jd.com"; + String emailName = "zhanglin33@jd.com"; + + CSRBuilder builder = new CSRBuilder(); + + builder.init("SHA1withRSA",2048); + String csr = builder.buildRequest(countryName,stateName,cityName, + organizationName,departmentName,domainName, + emailName); + + PublicKey pubKey = builder.getPubKey(); + PrivateKey privKey = builder.getPrivKey(); + + byte[] crsBytes = Base64.decode(csr); + PKCS10CertificationRequest request = null; + try { + request = new PKCS10CertificationRequest(crsBytes); + } catch (IOException e) { + e.printStackTrace(); + } + assertNotNull(request); + assertEquals("1.2.840.113549.1.1.5",request.getSignatureAlgorithm().getAlgorithm().getId()); + byte[] pubKeyBytes = new byte[0]; + try { + pubKeyBytes = request.getSubjectPublicKeyInfo().getEncoded(); + } catch (IOException e) { + e.printStackTrace(); + } + assertArrayEquals(pubKeyBytes,pubKey.getEncoded()); + + RDN[] rdns = request.getSubject().getRDNs(); + assertEquals(BCStyle.C, rdns[0].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.ST, rdns[1].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.L, rdns[2].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.O, rdns[3].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.OU, rdns[4].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.CN, rdns[5].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.E, rdns[6].getFirst().getType().toASN1Primitive()); + + assertEquals("CN", rdns[0].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[1].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[2].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("JD.com", rdns[3].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Blockchain Department", rdns[4].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("ledger.jd.com", rdns[5].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("zhanglin33@jd.com", rdns[6].getFirst().getValue().toASN1Primitive().toString()); + + byte[] signature = request.getSignature(); + + CertificationRequestInfo requestInfo = new CertificationRequestInfo(request.getSubject(),request.getSubjectPublicKeyInfo(),new DERSet()); + byte[] message = new byte[0]; + try { + message = requestInfo.getEncoded(ASN1Encoding.DER); + } catch (IOException e) { + e.printStackTrace(); + } + + Signature signer; + byte[] result = new byte[0]; + try { + signer = Signature.getInstance("SHA1withRSA"); + signer.initSign(privKey); + signer.update(message); + result = signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertArrayEquals(result,signature); + + Signature verifier; + boolean isValid = false; + try { + verifier = Signature.getInstance("SHA1withRSA"); + verifier.initVerify(pubKey); + verifier.update(message); + isValid = verifier.verify(signature); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertTrue(isValid); + } + + +// @Test + public void SHA1withRSA4096CSRTest(){ + + String countryName = "CN"; + String stateName = "Beijing"; + String cityName = "Beijing"; + String organizationName = "JD.com"; + String departmentName = "Blockchain Department"; + String domainName = "ledger.jd.com"; + String emailName = "zhanglin33@jd.com"; + + CSRBuilder builder = new CSRBuilder(); + + builder.init("SHA1withRSA",4096); + String csr = builder.buildRequest(countryName,stateName,cityName, + organizationName,departmentName,domainName, + emailName); + + PublicKey pubKey = builder.getPubKey(); + PrivateKey privKey = builder.getPrivKey(); + + byte[] crsBytes = Base64.decode(csr); + PKCS10CertificationRequest request = null; + try { + request = new PKCS10CertificationRequest(crsBytes); + } catch (IOException e) { + e.printStackTrace(); + } + assertNotNull(request); + assertEquals("1.2.840.113549.1.1.5",request.getSignatureAlgorithm().getAlgorithm().getId()); + byte[] pubKeyBytes = new byte[0]; + try { + pubKeyBytes = request.getSubjectPublicKeyInfo().getEncoded(); + } catch (IOException e) { + e.printStackTrace(); + } + assertArrayEquals(pubKeyBytes,pubKey.getEncoded()); + + RDN[] rdns = request.getSubject().getRDNs(); + assertEquals(BCStyle.C, rdns[0].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.ST, rdns[1].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.L, rdns[2].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.O, rdns[3].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.OU, rdns[4].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.CN, rdns[5].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.E, rdns[6].getFirst().getType().toASN1Primitive()); + + assertEquals("CN", rdns[0].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[1].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[2].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("JD.com", rdns[3].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Blockchain Department", rdns[4].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("ledger.jd.com", rdns[5].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("zhanglin33@jd.com", rdns[6].getFirst().getValue().toASN1Primitive().toString()); + + byte[] signature = request.getSignature(); + + CertificationRequestInfo requestInfo = new CertificationRequestInfo(request.getSubject(),request.getSubjectPublicKeyInfo(),new DERSet()); + byte[] message = new byte[0]; + try { + message = requestInfo.getEncoded(ASN1Encoding.DER); + } catch (IOException e) { + e.printStackTrace(); + } + + Signature signer; + byte[] result = new byte[0]; + try { + signer = Signature.getInstance("SHA1withRSA"); + signer.initSign(privKey); + signer.update(message); + result = signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertArrayEquals(result,signature); + + Signature verifier; + boolean isValid = false; + try { + verifier = Signature.getInstance("SHA1withRSA"); + verifier.initVerify(pubKey); + verifier.update(message); + isValid = verifier.verify(signature); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertTrue(isValid); + } + + + @Test + public void SM3withSM2CSRTest(){ + + String countryName = "CN"; + String stateName = "Beijing"; + String cityName = "Beijing"; + String organizationName = "JD.com"; + String departmentName = "Blockchain Department"; + String domainName = "ledger.jd.com"; + String emailName = "zhanglin33@jd.com"; + + CSRBuilder builder = new CSRBuilder(); + + builder.init("SM3withSM2",256); + String csr = builder.buildRequest(countryName,stateName,cityName, + organizationName,departmentName,domainName, + emailName); + + System.out.println(csr); + PublicKey pubKey = builder.getPubKey(); + PrivateKey privKey = builder.getPrivKey(); + + byte[] crsBytes = Base64.decode(csr); + PKCS10CertificationRequest request = null; + try { + request = new PKCS10CertificationRequest(crsBytes); + } catch (IOException e) { + e.printStackTrace(); + } + assertNotNull(request); + assertEquals("1.2.156.10197.1.501",request.getSignatureAlgorithm().getAlgorithm().getId()); + byte[] pubKeyBytes = new byte[0]; + try { + pubKeyBytes = request.getSubjectPublicKeyInfo().getEncoded(); + } catch (IOException e) { + e.printStackTrace(); + } + assertArrayEquals(pubKeyBytes,pubKey.getEncoded()); + + RDN[] rdns = request.getSubject().getRDNs(); + assertEquals(BCStyle.C, rdns[0].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.ST, rdns[1].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.L, rdns[2].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.O, rdns[3].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.OU, rdns[4].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.CN, rdns[5].getFirst().getType().toASN1Primitive()); + assertEquals(BCStyle.E, rdns[6].getFirst().getType().toASN1Primitive()); + + assertEquals("CN", rdns[0].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[1].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Beijing", rdns[2].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("JD.com", rdns[3].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("Blockchain Department", rdns[4].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("ledger.jd.com", rdns[5].getFirst().getValue().toASN1Primitive().toString()); + assertEquals("zhanglin33@jd.com", rdns[6].getFirst().getValue().toASN1Primitive().toString()); + + byte[] signature = request.getSignature(); + + CertificationRequestInfo requestInfo = new CertificationRequestInfo(request.getSubject(),request.getSubjectPublicKeyInfo(),new DERSet()); + byte[] message = new byte[0]; + try { + message = requestInfo.getEncoded(ASN1Encoding.DER); + } catch (IOException e) { + e.printStackTrace(); + } + + Signature signer; + byte[] result = new byte[0]; + try { + signer = Signature.getInstance("SM3withSM2"); + signer.initSign(privKey); + signer.update(message); + result = signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + + Signature verifier; + boolean isValid = false; + try { + verifier = Signature.getInstance("SM3withSM2"); + verifier.initVerify(pubKey); + verifier.update(message); + isValid = verifier.verify(signature); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertTrue(isValid); + + try { + verifier = Signature.getInstance("SM3withSM2"); + verifier.initVerify(pubKey); + verifier.update(message); + isValid = verifier.verify(result); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + e.printStackTrace(); + } + assertTrue(isValid); + } +} diff --git a/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/utils/CertParserTest.java b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/utils/CertParserTest.java new file mode 100644 index 00000000..24cdc414 --- /dev/null +++ b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/utils/CertParserTest.java @@ -0,0 +1,146 @@ +package com.jd.blockchain.crypto.utils; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author zhanglin33 + * @title: CertParserTest + * @description: TODO + * @date 2019-05-13, 10:05 + */ +public class CertParserTest { + + @Test + public void parseSHA1WITHRSA2048Test() { + CertParser parser = new CertParser(); + String issuerCert = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDzzCCAregAwIBAgIKUalCR1Mt5ZSK8jANBgkqhkiG9w0BAQUFADBZMQswCQYD\n" + + "VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g\n" + + "QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODI5MDU1\n" + + "NDM2WhcNMzIwODI0MDU1NDM2WjBZMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp\n" + + "bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRgwFgYDVQQDEw9D\n" + + "RkNBIFRFU1QgT0NBMTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8\n" + + "jn0n8Fp6hcRdACdn1+Y6GAkC6KGgNdKyHPrmsdmhCjnd/i4qUFwnG8cp3D4lFw1G\n" + + "jmjSO5yVYbik/NbS6lbNpRgTK3fDfMFvLJpRIC+IFhG9SdAC2hwjsH9qTpL9cK2M\n" + + "bSdrC6pBdDgnbzaM9AGBF4Y6vXhj5nah4ZMsBvDp19LzXjlGuTPLuAgv9ZlWknsd\n" + + "RN70PIAmvomd10uqX4GIJ4Jq/FdKXOLZ2DNK/NhRyN6Yq71L3ham6tutXeZow5t5\n" + + "0254AnUlo1u6SeH9F8itER653o/oMLFwp+63qXAcqrHUlOQPX+JI8fkumSqZ4F2F\n" + + "t/HfVMnqdtFNCnh5+eIBAgMBAAGjgZgwgZUwHwYDVR0jBBgwFoAUdN7FjQp9EBqq\n" + + "aYNbTSHOhpvMcTgwDAYDVR0TBAUwAwEB/zA4BgNVHR8EMTAvMC2gK6AphidodHRw\n" + + "Oi8vMjEwLjc0LjQyLjMvdGVzdHJjYS9SU0EvY3JsMS5jcmwwCwYDVR0PBAQDAgEG\n" + + "MB0GA1UdDgQWBBT8C7xEmg4xoYOpgYcnHgVCxr9W+DANBgkqhkiG9w0BAQUFAAOC\n" + + "AQEAb7W0K9fZPA+JPw6lRiMDaUJ0oh052yEXreMBfoPulxkBj439qombDiFggRLc\n" + + "3g8wIEKzMOzOKXTWtnzYwN3y/JQSuJb/M1QqOEEM2PZwCxI4AkBuH6jg03RjlkHg\n" + + "/kTtuIFp9ItBCC2/KkKlp0ENfn4XgVg2KtAjZ7lpyVU0LPnhEqqUVY/xthjlCSa7\n" + + "/XHNStRxsfCTIBUWJ8n2FZyQhfV/UkMNHDBIiJR0v6C4Ai0/290WvbPEIAq+03Si\n" + + "fsHzBeA0C8lP5VzfAr6wWePaZMCpStpLaoXNcAqReKxQllElOqAhRxC5VKH+rnIQ\n" + + "OMRZvB7FRyE9IfwKApngcZbA5g==\n" + + "-----END CERTIFICATE-----"; + + String userCert = "MIIEQDCCAyigAwIBAgIFICdVYzEwDQYJKoZIhvcNAQEFBQAwWTELMAkGA1UEBhMCQ04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEYMBYGA1UEAxMPQ0ZDQSBURVNUIE9DQTExMB4XDTE5MDUxMDExMjAyNFoXDTIxMDUxMDExMjAyNFowcjELMAkGA1UEBhMCQ04xGDAWBgNVBAoTD0NGQ0EgVEVTVCBPQ0ExMTERMA8GA1UECxMITG9jYWwgUkExFTATBgNVBAsTDEluZGl2aWR1YWwtMTEfMB0GA1UEAxQWMDUxQGFhYWFhQFpIMDkzNTgwMjhAMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJx3F2WD1dJPzK/nRHO7d1TJ1hTjzGTmv0PQ7ECsJAh3U3BtnGTpCB+b4+JMI4LO8nHkKIBQ3P9XnF+Bf1iXdWNAQ4aWCxa2nV7lCp4w0GliPu/EMgIfmsSDUtgqbM3cr8sR8r9m1xG3gt2TIQJ+jT7sAiguU/kyNzpjaccOUIgUFa8IDFq9UeB76MXtCuhlERRZQCl47e+9w7ZoxmE7e6IZORxPp7rQWVBHlR9ntWjJfNDTm3gMP5ehP+yIZnKx1LudxkBLQxpMmspzOyH1zqx5nkKe49AfWWpDxxRvYkriyYC3aE81qLsU/bhLwNEKOju7BGDF/mhJLZUedojM0gMCAwEAAaOB9TCB8jAfBgNVHSMEGDAWgBT8C7xEmg4xoYOpgYcnHgVCxr9W+DBIBgNVHSAEQTA/MD0GCGCBHIbvKgECMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTUuaHRtMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly8yMTAuNzQuNDIuMy9PQ0ExMS9SU0EvY3JsMjU2OTMuY3JsMAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQU5oKGaQs7Jt5Gfbt1XhFTWAySEKswHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBBQUAA4IBAQAlmPRaImZV51iKjtpMKuyLMw7dX8L0lY3tl+pVZZSxHuwsN4GCCtV0Ej50up+/6EbfL4NUTiuHVAjCroKKvb+94CrdEwdnQGM5IbGSjT78nQpeASXbIWuUwA+ImjvZOzvq/0b56AzonNzBxOMGko/bj5smM6X8jrgJ0NQppo2KNSVNC4JbuoNWI4FM94SE4DUi9H7EYl4JdOtDaDtCsq49o/A1CZyYrmoOPCgxpQQXmuB3lGq/jyoOlW2aW8uee/hYG1JJcSHLBjF0WBwdxssgbBotA5f1PebiIMSbFgjk57bd4M80hhU/rI4Hkn9pcp5R7NsX95TtyDIg90LboBnW"; + + parser.parse(userCert, issuerCert); + assertEquals("SHA1WITHRSA",parser.getSigAlgName()); + } + + @Test + public void parseSHA1WITHRSA4096Test() { + CertParser parser = new CertParser(); + String issuerCert = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDzzCCAregAwIBAgIKUalCR1Mt5ZSK8jANBgkqhkiG9w0BAQUFADBZMQswCQYD\n" + + "VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g\n" + + "QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODI5MDU1\n" + + "NDM2WhcNMzIwODI0MDU1NDM2WjBZMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp\n" + + "bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRgwFgYDVQQDEw9D\n" + + "RkNBIFRFU1QgT0NBMTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8\n" + + "jn0n8Fp6hcRdACdn1+Y6GAkC6KGgNdKyHPrmsdmhCjnd/i4qUFwnG8cp3D4lFw1G\n" + + "jmjSO5yVYbik/NbS6lbNpRgTK3fDfMFvLJpRIC+IFhG9SdAC2hwjsH9qTpL9cK2M\n" + + "bSdrC6pBdDgnbzaM9AGBF4Y6vXhj5nah4ZMsBvDp19LzXjlGuTPLuAgv9ZlWknsd\n" + + "RN70PIAmvomd10uqX4GIJ4Jq/FdKXOLZ2DNK/NhRyN6Yq71L3ham6tutXeZow5t5\n" + + "0254AnUlo1u6SeH9F8itER653o/oMLFwp+63qXAcqrHUlOQPX+JI8fkumSqZ4F2F\n" + + "t/HfVMnqdtFNCnh5+eIBAgMBAAGjgZgwgZUwHwYDVR0jBBgwFoAUdN7FjQp9EBqq\n" + + "aYNbTSHOhpvMcTgwDAYDVR0TBAUwAwEB/zA4BgNVHR8EMTAvMC2gK6AphidodHRw\n" + + "Oi8vMjEwLjc0LjQyLjMvdGVzdHJjYS9SU0EvY3JsMS5jcmwwCwYDVR0PBAQDAgEG\n" + + "MB0GA1UdDgQWBBT8C7xEmg4xoYOpgYcnHgVCxr9W+DANBgkqhkiG9w0BAQUFAAOC\n" + + "AQEAb7W0K9fZPA+JPw6lRiMDaUJ0oh052yEXreMBfoPulxkBj439qombDiFggRLc\n" + + "3g8wIEKzMOzOKXTWtnzYwN3y/JQSuJb/M1QqOEEM2PZwCxI4AkBuH6jg03RjlkHg\n" + + "/kTtuIFp9ItBCC2/KkKlp0ENfn4XgVg2KtAjZ7lpyVU0LPnhEqqUVY/xthjlCSa7\n" + + "/XHNStRxsfCTIBUWJ8n2FZyQhfV/UkMNHDBIiJR0v6C4Ai0/290WvbPEIAq+03Si\n" + + "fsHzBeA0C8lP5VzfAr6wWePaZMCpStpLaoXNcAqReKxQllElOqAhRxC5VKH+rnIQ\n" + + "OMRZvB7FRyE9IfwKApngcZbA5g==\n" + + "-----END CERTIFICATE-----"; + + String userCert = "MIIFRjCCBC6gAwIBAgIFICdWiDMwDQYJKoZIhvcNAQEFBQAwWTELMAkGA1UEBhMCQ04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEYMBYGA1UEAxMPQ0ZDQSBURVNUIE9DQTExMB4XDTE5MDUxNjA3MDcyMloXDTIxMDUxNjA3MDcyMloweDELMAkGA1UEBhMCQ04xGDAWBgNVBAoTD0NGQ0EgVEVTVCBPQ0ExMTERMA8GA1UECxMITG9jYWwgUkExFTATBgNVBAsTDEluZGl2aWR1YWwtMTElMCMGA1UEAxQcMDUxQHpoYW5nbGluIUBaMTg2MTIyMjkyOTVAMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL0rTOxd8rsjPtFJ0aGVh9bZPy5Xo0SADaP7BbJsG4+ykLQMZHg9hTf/6fv1OsD2HEKFoMpIkW2gwCJW2nvicHcVql/shCoktc6ZBW6Dr/DxOgbO9tpoGxZ50xdI4Q0NsrxqtbCldW4ozPHdjgRJ83i1KSFh7evNrVByN/mB+jchrVGLWyJ1uIRgUUgpRZmZPoOHaizVJqrqWJGGk6xbDLR2gUQ1hTzetQaz1OeKtelHDk9FY08XSmNGssSMpuSjrxn78S888VW5WIxyo4cwrXSXFk3J7LNTy70Oga16HZjJD/vLTM6a4riPa8+uivPinKxK38/++nlBPNwhx6n46uYkd9Zvw+SJiJgpnuPJLtMZpKpJx7V1BDVEydKPUthilTdsmJtkBFSlFw0G1aKfuciBGzzJ3SKngJF/JqJAWIonVAFBGb6Gokp1Sw+T4KqXrdbjxYxiyyjZ++8O1vydgFAkx/NjsuwJnpKETiRKFJmY7YawcUvC4ixF7XQc0luFWRDYcbxOppir+ieMqhGXyaFhLUuB4WXv+rFxfa3NmkBW8q5TPzt/PwWcXpITsYTZYla/E/grB+OeZLYgjigT5YlgytPHG6Gt1ySCCd8WXFWpkBbQfXzqcvtU27RCcAUgfXk5NLb7NZCQg7heGjgzOdYJCPsa1d3m7l04+VIKGCZdAgMBAAGjgfUwgfIwHwYDVR0jBBgwFoAU/Au8RJoOMaGDqYGHJx4FQsa/VvgwSAYDVR0gBEEwPzA9BghggRyG7yoBAjAxMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmNmY2EuY29tLmNuL3VzL3VzLTE1Lmh0bTA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8vMjEwLjc0LjQyLjMvT0NBMTEvUlNBL2NybDI1NzE3LmNybDALBgNVHQ8EBAMCA+gwHQYDVR0OBBYEFMjh6AzDCuNkD+pqQfiS6bqPGpI4MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDANBgkqhkiG9w0BAQUFAAOCAQEApZaLXS6/6FudPA3l2xom5U7nJUOpQ1E6DO/ic9dFGtLE0WgyAqB3JVPvXEntppX55x/dAV7rvvz9NaEdiAe8DAj7qyoPDvC8ZWQK8U4n9l8N78QwALOURxzQNs+CBatJQzbu2w1RKVwkfE6xEIVnu+wjiAtymfwdLHMagHxDIC/eOPbTnbbtITJk2ukFfoc0WJ6Awg5lW+x7nGokEn/XAjKyRHCpkRUFGQm4ww41zlrqCqQqnVGVABJtjbdtFf7nh33QHl0fkj19nfMox9eGuntPyM0bNA0XqPMA+FWSCqeDT6uLbyaOKWxlhv53U/NCJl76U3tssMEWsm9amEDDQg=="; + + parser.parse(userCert, issuerCert); + assertEquals("SHA1WITHRSA",parser.getSigAlgName()); + } + + @Test + public void parseSM3WITHSM2Test() { + CertParser parser = new CertParser(); + String issuerCert = + "-----BEGIN CERTIFICATE-----\n" + + "MIICTzCCAfOgAwIBAgIKJFSZ4SRVDndYUTAMBggqgRzPVQGDdQUAMF0xCzAJBgNV\n" + + "BAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBB\n" + + "dXRob3JpdHkxHDAaBgNVBAMME0NGQ0EgVEVTVCBDUyBTTTIgQ0EwHhcNMTIwODI5\n" + + "MDU0ODQ3WhcNMzIwODI0MDU0ODQ3WjBdMQswCQYDVQQGEwJDTjEwMC4GA1UECgwn\n" + + "Q2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQD\n" + + "DBNDRkNBIFRFU1QgU00yIE9DQTExMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE\n" + + "L1mx4wriQUojGsIkNL14kslv9nwiqsiVpELOZauzghrbccNlPYKNYKZOCvXwIIqU\n" + + "9QY02d4weqKqo/JMcNsKEaOBmDCBlTAfBgNVHSMEGDAWgBS12JBvXPDYM9JjvX6y\n" + + "w43GTxJ6YTAMBgNVHRMEBTADAQH/MDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly8y\n" + + "MTAuNzQuNDIuMy90ZXN0cmNhL1NNMi9jcmwxLmNybDALBgNVHQ8EBAMCAQYwHQYD\n" + + "VR0OBBYEFL6mfk09fI+gVebBLwkuLCBDs0J/MAwGCCqBHM9VAYN1BQADSAAwRQIh\n" + + "AKuk7s3eYCZDck5NWU0eNQmLhBN/1zmKs517qFrDrkJWAiAP4cVfLtdza/OkwU9P\n" + + "PrIDl+E4aL3FypntFXHG3T+Keg==\n" + + "-----END CERTIFICATE-----"; + + String userCert = "MIICwDCCAmWgAwIBAgIFICdWkWgwDAYIKoEcz1UBg3UFADBdMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQDDBNDRkNBIFRFU1QgU00yIE9DQTExMB4XDTE5MDUxNjA4MTA1MVoXDTIxMDUxNjA4MTA1MVoweDELMAkGA1UEBhMCQ04xGDAWBgNVBAoMD0NGQ0EgVEVTVCBPQ0ExMTERMA8GA1UECwwITG9jYWwgUkExFTATBgNVBAsMDEluZGl2aWR1YWwtMTElMCMGA1UEAwwcMDUxQHpoYW5nbGluIUBaMTg2MTIyMjkyOTVAMzBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABPvNXpdZ4/4g+wx5qKS94CPkMqpEDhlnXYYW7ZzsbNI4d28sVBz5Ji6dTT1Zx627Kvw4tdUaUt7BVMvZsu3BFlyjgfQwgfEwHwYDVR0jBBgwFoAUvqZ+TT18j6BV5sEvCS4sIEOzQn8wSAYDVR0gBEEwPzA9BghggRyG7yoBAjAxMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmNmY2EuY29tLmNuL3VzL3VzLTE1Lmh0bTA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vMjEwLjc0LjQyLjMvT0NBMTEvU00yL2NybDIxMDkuY3JsMAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUxR5C/VjASus5zrAAFS4ulMpRjKgwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMAwGCCqBHM9VAYN1BQADRwAwRAIgVBzVi/fgkknr+2BH2wXeGMXC+Pa6p7rbldUsYMOYoyUCIAmQ4KEk2U1xJZSBpOPy5jN9kmRb+0YH6x04O/2tqCgq"; + + parser.parse(userCert, issuerCert); + assertEquals("SM3WITHSM2",parser.getSigAlgName()); + } + + @Test + public void authenticateIssuerByCATest() { + CertParser parser = new CertParser(); + String CACert = + "-----BEGIN CERTIFICATE-----\n" + + "MIICFDCCAbegAwIBAgIKPYozwkCO86Nd9TAMBggqgRzPVQGDdQUAMF0xCzAJBgNV\n" + + "BAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBB\n" + + "dXRob3JpdHkxHDAaBgNVBAMME0NGQ0EgVEVTVCBDUyBTTTIgQ0EwHhcNMTIwODI5\n" + + "MDMyOTQ2WhcNMzIwODI5MDMyOTQ2WjBdMQswCQYDVQQGEwJDTjEwMC4GA1UECgwn\n" + + "Q2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQD\n" + + "DBNDRkNBIFRFU1QgQ1MgU00yIENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE\n" + + "tTjB3O4JueYFDDOtxH678HBZbEmrsgd3BDIdGf0BekyA26n9S0/pKPnjBh/zLouS\n" + + "8+GB5EEnjbn4An24yo1Gv6NdMFswHwYDVR0jBBgwFoAUtdiQb1zw2DPSY71+ssON\n" + + "xk8SemEwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFLXYkG9c\n" + + "8Ngz0mO9frLDjcZPEnphMAwGCCqBHM9VAYN1BQADSQAwRgIhAKwuuqoBS1bwDowW\n" + + "a4IU//UsvudswJYSlltqrd/PQ9q+AiEAyTUAjFdaGI+8yPdr3A93UiA38wtGPf9e\n" + + "6B6O/6abyWE=\n" + + "-----END CERTIFICATE-----"; + + String issuerCert = "-----BEGIN CERTIFICATE-----\n" + + "MIICTzCCAfOgAwIBAgIKJFSZ4SRVDndYUTAMBggqgRzPVQGDdQUAMF0xCzAJBgNV\n" + + "BAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBB\n" + + "dXRob3JpdHkxHDAaBgNVBAMME0NGQ0EgVEVTVCBDUyBTTTIgQ0EwHhcNMTIwODI5\n" + + "MDU0ODQ3WhcNMzIwODI0MDU0ODQ3WjBdMQswCQYDVQQGEwJDTjEwMC4GA1UECgwn\n" + + "Q2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQD\n" + + "DBNDRkNBIFRFU1QgU00yIE9DQTExMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE\n" + + "L1mx4wriQUojGsIkNL14kslv9nwiqsiVpELOZauzghrbccNlPYKNYKZOCvXwIIqU\n" + + "9QY02d4weqKqo/JMcNsKEaOBmDCBlTAfBgNVHSMEGDAWgBS12JBvXPDYM9JjvX6y\n" + + "w43GTxJ6YTAMBgNVHRMEBTADAQH/MDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly8y\n" + + "MTAuNzQuNDIuMy90ZXN0cmNhL1NNMi9jcmwxLmNybDALBgNVHQ8EBAMCAQYwHQYD\n" + + "VR0OBBYEFL6mfk09fI+gVebBLwkuLCBDs0J/MAwGCCqBHM9VAYN1BQADSAAwRQIh\n" + + "AKuk7s3eYCZDck5NWU0eNQmLhBN/1zmKs517qFrDrkJWAiAP4cVfLtdza/OkwU9P\n" + + "PrIDl+E4aL3FypntFXHG3T+Keg==\n" + + "-----END CERTIFICATE-----"; + parser.parse(issuerCert, CACert); + assertEquals("SM3WITHSM2",parser.getSigAlgName()); + } +} diff --git a/source/crypto/pom.xml b/source/crypto/pom.xml index fb6e71ba..f8b66416 100644 --- a/source/crypto/pom.xml +++ b/source/crypto/pom.xml @@ -16,6 +16,7 @@ crypto-sm crypto-adv + crypto-pki \ No newline at end of file diff --git a/source/deployment/deployment-peer/src/main/resources/config/init/ledger-init.conf b/source/deployment/deployment-peer/src/main/resources/config/init/ledger-init.conf deleted file mode 100644 index e6af54f4..00000000 --- a/source/deployment/deployment-peer/src/main/resources/config/init/ledger-init.conf +++ /dev/null @@ -1,67 +0,0 @@ -#璐︽湰鐨勭瀛愶紱涓娈16杩涘埗瀛楃锛屾渶闀垮彲浠ュ寘鍚64涓瓧绗︼紱鍙互鐢ㄥ瓧绗︹-鈥濆垎闅旓紝浠ヤ究鏇村鏄撹鍙栵紱 -#涓嶅悓鐨勮处鏈紝绉嶅瓙涓嶈兘鐩稿悓 -ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe - -#璐︽湰鐨勬弿杩板悕绉帮紱姝ゅ睘鎬т笉鍙備笌鍏辫瘑锛屼粎浠呭湪褰撳墠鍙備笌鏂圭殑鏈湴鑺傜偣鐢ㄤ簬鎻忚堪鐢ㄩ旓紱 -#ledger.name= - -#鍙備笌鏂圭殑涓暟锛屽悗缁互cons_parti.id鍒嗗埆鏍囪瘑姣忎竴涓弬涓庢柟鐨勯厤缃紱 -cons_parti.count=4 - - -#绗0涓弬涓庢柟鐨勫悕绉帮紙涓嶅悓鍙備笌鏂瑰悕绉颁笉鑳界浉鍚岋級 -cons_parti.0.name= -#绗0涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰 -cons_parti.0.pubkey-path= -#绗0涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紝姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟 -cons_parti.0.pubkey= -#绗0涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満 -cons_parti.0.initializer.host=127.0.0.1 -#绗0涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛 -cons_parti.0.initializer.port=17000 -#绗0涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺 -cons_parti.0.initializer.secure=false - - -#绗1涓弬涓庢柟鐨勫悕绉 -cons_parti.1.name= -#绗1涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰 -cons_parti.1.pubkey-path= -#绗1涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紝姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟 -cons_parti.1.pubkey= -#绗1涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満 -cons_parti.1.initializer.host=127.0.0.1 -#绗1涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛 -cons_parti.1.initializer.port=17010 -#绗1涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺 -cons_parti.1.initializer.secure=false - - -#绗2涓弬涓庢柟鐨勫悕绉 -cons_parti.2.name= -#绗2涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰 -cons_parti.2.pubkey-path= -#绗2涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紝姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟 -cons_parti.2.pubkey= -#绗2涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満 -cons_parti.2.initializer.host=127.0.0.1 -#绗2涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛 -cons_parti.2.initializer.port=17020 -#绗2涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺 -cons_parti.2.initializer.secure=false - - -#绗3涓弬涓庢柟鐨勫悕绉 -cons_parti.3.name= -#绗3涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰 -cons_parti.3.pubkey-path= -#绗3涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紝姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟 -cons_parti.3.pubkey= -#绗3涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満 -cons_parti.3.initializer.host=127.0.0.1 -#绗3涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛 -cons_parti.3.initializer.port=17030 -#绗3涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺 -cons_parti.3.initializer.secure=false - - diff --git a/source/deployment/deployment-peer/src/main/resources/config/init/ledger.init b/source/deployment/deployment-peer/src/main/resources/config/init/ledger.init new file mode 100644 index 00000000..9df38d79 --- /dev/null +++ b/source/deployment/deployment-peer/src/main/resources/config/init/ledger.init @@ -0,0 +1,97 @@ + +#璐︽湰鐨勭瀛愶紱涓娈16杩涘埗瀛楃锛屾渶闀垮彲浠ュ寘鍚64涓瓧绗︼紱鍙互鐢ㄥ瓧绗︹-鈥濆垎闅旓紝浠ヤ究鏇村鏄撹鍙栵紱 +ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe + +#璐︽湰鐨勬弿杩板悕绉帮紱姝ゅ睘鎬т笉鍙備笌鍏辫瘑锛屼粎浠呭湪褰撳墠鍙備笌鏂圭殑鏈湴鑺傜偣鐢ㄤ簬鎻忚堪鐢ㄩ旓紱 +ledger.name= + + +#鍏辫瘑鏈嶅姟鎻愪緵鑰咃紱蹇呴』锛 +consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider + +#鍏辫瘑鏈嶅姟鐨勫弬鏁伴厤缃紱蹇呴』锛 +consensus.conf=classpath:bftsmart.config + +#瀵嗙爜鏈嶅姟鎻愪緵鑰呭垪琛紝浠ヨ嫳鏂囬楃偣鈥,鈥濆垎闅旓紱蹇呴』锛 +crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ +com.jd.blockchain.crypto.service.sm.SMCryptoService + + +#鍙備笌鏂圭殑涓暟锛屽悗缁互 cons_parti.id 鍒嗗埆鏍囪瘑姣忎竴涓弬涓庢柟鐨勯厤缃紱 +cons_parti.count=4 + +#绗0涓弬涓庢柟鐨勫悕绉帮紱 +cons_parti.0.name=jd.com +#绗0涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰勶紱 +cons_parti.0.pubkey-path=keys/jd-com.pub +#绗0涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紱姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟锛 +cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 +#绗0涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑涓绘満鍦板潃锛 +cons_parti.0.consensus.host=127.0.0.1 +#绗0涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑绔彛锛 +cons_parti.0.consensus.port=8900 +#绗0涓弬涓庢柟鐨勫叡璇嗘湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.0.consensus.secure=true +#绗0涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満锛 +cons_parti.0.initializer.host=127.0.0.1 +#绗0涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛锛 +cons_parti.0.initializer.port=8800 +#绗0涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.0.initializer.secure=true + +#绗1涓弬涓庢柟鐨勫悕绉帮紱 +cons_parti.1.name=at.com +#绗1涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰勶紱 +cons_parti.1.pubkey-path=keys/at-com.pub +#绗1涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紱姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟锛 +cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX +#绗1涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑涓绘満鍦板潃锛 +cons_parti.1.consensus.host=127.0.0.1 +#绗1涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑绔彛锛 +cons_parti.1.consensus.port=8910 +#绗1涓弬涓庢柟鐨勫叡璇嗘湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.1.consensus.secure=false +#绗1涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満锛 +cons_parti.1.initializer.host=127.0.0.1 +#绗1涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛锛 +cons_parti.1.initializer.port=8810 +#绗1涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.1.initializer.secure=false + +#绗2涓弬涓庢柟鐨勫悕绉帮紱 +cons_parti.2.name=bt.com +#绗2涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰勶紱 +cons_parti.2.pubkey-path=classpath:keys/parti2.pub +#绗2涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紱姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟锛 +cons_parti.2.pubkey= +#绗2涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑涓绘満鍦板潃锛 +cons_parti.2.consensus.host=127.0.0.1 +#绗2涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑绔彛锛 +cons_parti.2.consensus.port=8920 +#绗2涓弬涓庢柟鐨勫叡璇嗘湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.2.consensus.secure=false +#绗2涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満锛 +cons_parti.2.initializer.host=127.0.0.1 +#绗2涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛锛 +cons_parti.2.initializer.port=8820 +#绗2涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.2.initializer.secure=true + +#绗3涓弬涓庢柟鐨勫悕绉帮紱 +cons_parti.3.name=xt.com +#绗3涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰勶紱 +cons_parti.3.pubkey-path=keys/xt-com.pub +#绗3涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紱姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟锛 +cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk +#绗3涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑涓绘満鍦板潃锛 +cons_parti.3.consensus.host=127.0.0.1 +#绗3涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑绔彛锛 +cons_parti.3.consensus.port=8930 +#绗3涓弬涓庢柟鐨勫叡璇嗘湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.3.consensus.secure=false +#绗3涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑涓绘満锛 +cons_parti.3.initializer.host=127.0.0.1 +#绗3涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔$殑绔彛锛 +cons_parti.3.initializer.port=8830 +#绗3涓弬涓庢柟鐨勮处鏈垵濮嬫湇鍔℃槸鍚﹀紑鍚畨鍏ㄨ繛鎺ワ紱 +cons_parti.3.initializer.secure=false diff --git a/source/deployment/deployment-peer/src/main/resources/config/init/local.conf b/source/deployment/deployment-peer/src/main/resources/config/init/local.conf index b182823e..27652184 100644 --- a/source/deployment/deployment-peer/src/main/resources/config/init/local.conf +++ b/source/deployment/deployment-peer/src/main/resources/config/init/local.conf @@ -22,11 +22,3 @@ ledger.db.uri= #璐︽湰鏁版嵁搴撶殑杩炴帴鍙d护 ledger.db.pwd= -#鍏辫瘑閰嶇疆鏂囦欢璺緞 -#鎺ㄨ崘浣跨敤缁濆璺緞锛岀浉瀵硅矾寰勪互褰撳墠鏂囦欢(local.conf锛夋墍鍦ㄧ洰褰曚负鍩哄噯 -consensus.conf=bftsmart.config - -#鍏辫瘑Providers閰嶇疆 -#BftSmart鍏辫瘑Provider锛歝om.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider -#绠鍗曟秷鎭叡璇哖rovider锛歝om.jd.blockchain.consensus.mq.MsgQueueConsensusProvider -consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java index 71e34a7c..1a6c0267 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java @@ -81,7 +81,7 @@ public class GatewayQueryServiceHandler implements GatewayQueryService { ledgerInitSettings.setSeed(initSeed(ledgerMetadata.getSeed())); // 璁剧疆鍏辫瘑鍗忚 - ledgerInitSettings.setConsensusProtocol(consensusProtocol(ledgerMetadata.getSetting().getConsensusProvider())); + ledgerInitSettings.setConsensusProtocol(ledgerMetadata.getSetting().getConsensusProvider()); return ledgerInitSettings; } @@ -110,24 +110,6 @@ public class GatewayQueryServiceHandler implements GatewayQueryService { return seed.toString(); } - /** - * 鐢熸垚鍏辫瘑鍗忚 - * - * @param consensusProvider - * 鍏辫瘑鍗忚鎻愭彁渚涜 - * @return - */ - private int consensusProtocol(String consensusProvider) { - - if (consensusProvider.equals(BftsmartConsensusProvider.NAME)) { - return LedgerInitSettings.CONSENSUS_PROTOCOL.BFTSMART.code(); - } else if (consensusProvider.equals(MsgQueueConsensusProvider.NAME)) { - return LedgerInitSettings.CONSENSUS_PROTOCOL.MSGQUEUE.code(); - } - - return LedgerInitSettings.CONSENSUS_PROTOCOL.UNKNOWN.code(); - } - /** * 鍒濆鍖栧叡璇嗛厤缃 * diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java index 381cc50f..66f94b97 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java @@ -239,6 +239,13 @@ public class BlockBrowserController implements BlockchainExtendQueryService { return peerService.getQueryService().getDataEntries(ledgerHash, address, keys); } + @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") + public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, + @PathVariable("address") String address, + @RequestBody KVInfoVO kvInfoVO) { + return peerService.getQueryService().getDataEntries(ledgerHash, address, kvInfoVO); + } + @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") @Override public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java index 6244d018..2b905d6b 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java @@ -1,22 +1,37 @@ package com.jd.blockchain.ledger.core; +import java.util.HashMap; + import com.jd.blockchain.crypto.CryptoAlgorithm; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.ledger.CryptoSetting; public class CryptoConfig implements CryptoSetting { + private CryptoProvider[] cryptoProviders; + private short hashAlgorithm; private boolean autoVerifyHash; + HashMap providers; + HashMap nameAlgorithms; + HashMap codeAlgorithms; + public CryptoConfig() { } public CryptoConfig(CryptoSetting setting) { - this.hashAlgorithm = setting.getHashAlgorithm(); + setSupportedProviders(setting.getSupportedProviders()); + setHashAlgorithm(setting.getHashAlgorithm()); this.autoVerifyHash = setting.getAutoVerifyHash(); } + @Override + public CryptoProvider[] getSupportedProviders() { + return cryptoProviders == null ? null : cryptoProviders.clone(); + } + @Override public short getHashAlgorithm() { return hashAlgorithm; @@ -27,11 +42,47 @@ public class CryptoConfig implements CryptoSetting { return autoVerifyHash; } + public void setSupportedProviders(CryptoProvider[] supportedProviders) { + HashMap providers = new HashMap(); + HashMap nameAlgorithms = new HashMap(); + HashMap codeAlgorithms = new HashMap(); + if (supportedProviders != null) { + // 妫鏌ユ槸鍚﹀瓨鍦ㄩ噸澶嶇殑鎻愪緵鑰呬互鍙婄畻娉曪紱 + for (CryptoProvider cryptoProvider : supportedProviders) { + if (providers.containsKey(cryptoProvider.getName())) { + throw new LedgerException("Duplicate crypto providers [" + cryptoProvider.getName() + "]!"); + } + CryptoAlgorithm[] algorithms = cryptoProvider.getAlgorithms(); + for (CryptoAlgorithm alg : algorithms) { + if (nameAlgorithms.containsKey(alg.name())) { + throw new LedgerException("Duplicate crypto algorithms [" + alg.toString() + "] from provider " + + cryptoProvider.getName() + "!"); + } + if (codeAlgorithms.containsKey(alg.code())) { + throw new LedgerException("Duplicate crypto algorithms [" + alg.toString() + "] from provider" + + cryptoProvider.getName() + "!"); + } + nameAlgorithms.put(alg.name(), alg); + codeAlgorithms.put(alg.code(), alg); + } + providers.put(cryptoProvider.getName(), cryptoProvider); + } + } + this.providers = providers; + this.nameAlgorithms = nameAlgorithms; + this.codeAlgorithms = codeAlgorithms; + + this.cryptoProviders = supportedProviders; + } + public void setHashAlgorithm(CryptoAlgorithm hashAlgorithm) { - this.hashAlgorithm = hashAlgorithm.code(); + setHashAlgorithm(hashAlgorithm.code()); } public void setHashAlgorithm(short hashAlgorithm) { + if (codeAlgorithms == null || !codeAlgorithms.containsKey(hashAlgorithm)) { + throw new LedgerException("The specified algorithm[" + hashAlgorithm + "] has no provider!"); + } this.hashAlgorithm = hashAlgorithm; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java index aa51901a..0655cb24 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java @@ -157,6 +157,9 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @return return total count; */ public long getDataEntriesTotalCount() { + if(baseAccount == null){ + return 0; + } return baseAccount.dataset.getDataCount(); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java index 93842206..4525ed9d 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java @@ -3,10 +3,15 @@ package com.jd.blockchain.ledger.core.impl; import java.util.HashMap; import java.util.Map; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoAlgorithm; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.LedgerInitSetting; import com.jd.blockchain.ledger.core.LedgerConsts; import com.jd.blockchain.ledger.core.LedgerEditor; +import com.jd.blockchain.ledger.core.LedgerException; import com.jd.blockchain.ledger.core.LedgerManage; import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.storage.service.ExPolicyKVStorage; @@ -57,26 +62,83 @@ public class LedgerManager implements LedgerManage { @Override public LedgerRepository register(HashDigest ledgerHash, KVStorageService storageService) { + // 鍔犺浇璐︽湰鏁版嵁搴擄紱 VersioningKVStorage ledgerVersioningStorage = storageService.getVersioningKVStorage(); ExPolicyKVStorage ledgerExPolicyStorage = storageService.getExPolicyKVStorage(); LedgerRepository ledgerRepo = new LedgerRepositoryImpl(ledgerHash, LEDGER_PREFIX, ledgerExPolicyStorage, ledgerVersioningStorage); - LedgerRepositoryContext ledgerCtx = new LedgerRepositoryContext(); - ledgerCtx.ledgerRepo = ledgerRepo; - ledgerCtx.storageService = storageService; + // 鏍¢獙 crypto service provider 锛 + CryptoSetting cryptoSetting = ledgerRepo.getAdminAccount().getSetting().getCryptoSetting(); + checkCryptoSetting(cryptoSetting, ledgerHash); + + // 鍒涘缓璐︽湰涓婁笅鏂囷紱 + LedgerRepositoryContext ledgerCtx = new LedgerRepositoryContext(ledgerRepo, storageService); ledgers.put(ledgerHash, ledgerCtx); return ledgerRepo; } + /** + * 妫鏌ヨ处鏈殑瀵嗙爜鍙傛暟璁剧疆涓庢湰鍦拌妭鐐圭殑杩愯鏃剁幆澧冩槸鍚﹀尮閰嶏紱 + * + * @param cryptoSetting + * @param ledgerHash + */ + private void checkCryptoSetting(CryptoSetting cryptoSetting, HashDigest ledgerHash) { + CryptoProvider[] cryptoProviders = cryptoSetting.getSupportedProviders(); + if (cryptoProviders == null || cryptoProviders.length == 0) { + throw new LedgerException("No supported crypto service providers has been setted in the ledger[" + + ledgerHash.toBase58() + "]!"); + } + for (CryptoProvider cp : cryptoProviders) { + CryptoProvider regCp = Crypto.getProvider(cp.getName()); + checkCryptoProviderConsistency(regCp, cp); + } + } + + /** + * 妫鏌ュ瘑鐮佹湇鍔℃彁渚涜呯殑淇℃伅鏄惁鍖归厤锛 + * + * @param registeredProvider + * @param settingProvider + */ + private void checkCryptoProviderConsistency(CryptoProvider registeredProvider, CryptoProvider settingProvider) { + if (registeredProvider == null) { + throw new LedgerException("Crypto service provider[" + settingProvider.getName() + + "] has not registered in the runtime environment of current peer!"); + } + + CryptoAlgorithm[] runtimeAlgothms = registeredProvider.getAlgorithms(); + CryptoAlgorithm[] settingAlgothms = settingProvider.getAlgorithms(); + if (runtimeAlgothms.length != settingAlgothms.length) { + throw new LedgerException("Crypto service provider[" + settingProvider.getName() + + "] has not registered in runtime of current peer!"); + } + HashMap runtimeAlgothmMap = new HashMap(); + for (CryptoAlgorithm alg : runtimeAlgothms) { + runtimeAlgothmMap.put(alg.code(), alg); + } + for (CryptoAlgorithm alg : settingAlgothms) { + CryptoAlgorithm regAlg = runtimeAlgothmMap.get(alg.code()); + if (regAlg == null) { + throw new LedgerException( + String.format("Crypto algorithm[%s] is not defined by provider[%s] in runtime of current peer!", + alg.toString(), registeredProvider.getName())); + } + if (!regAlg.name().equals(alg.name())) { + throw new LedgerException(String.format( + "Crypto algorithm[%s] do not match the same code algorithm[%s] defined by provider[%s] in runtime of current peer!", + CryptoAlgorithm.getString(alg), CryptoAlgorithm.getString(regAlg), + registeredProvider.getName())); + } + } + } + @Override public void unregister(HashDigest ledgerHash) { - LedgerRepositoryContext ledgerCtx = ledgers.get(ledgerHash); + LedgerRepositoryContext ledgerCtx = ledgers.remove(ledgerHash); if (ledgerCtx != null) { ledgerCtx.ledgerRepo.close(); - ledgers.remove(ledgerHash); - ledgerCtx.ledgerRepo = null; - ledgerCtx.storageService = null; } } @@ -88,18 +150,6 @@ public class LedgerManager implements LedgerManage { */ @Override public LedgerEditor newLedger(LedgerInitSetting initSetting, KVStorageService storageService) { - // GenesisLedgerStorageProxy genesisStorageProxy = new - // GenesisLedgerStorageProxy(); - // BufferedKVStorage bufferedStorage = new - // BufferedKVStorage(genesisStorageProxy, genesisStorageProxy, false); - - // LedgerEditor genesisBlockEditor = - // LedgerTransactionalEditor.createEditor(initSetting, - // bufferedStorage, bufferedStorage); - - // return new LedgerInitializer(genesisBlockEditor, bufferedStorage, - // genesisStorageProxy, storageService, this); - LedgerEditor genesisBlockEditor = LedgerTransactionalEditor.createEditor(initSetting, LEDGER_PREFIX, storageService.getExPolicyKVStorage(), storageService.getVersioningKVStorage()); return genesisBlockEditor; @@ -110,10 +160,16 @@ public class LedgerManager implements LedgerManage { return LEDGER_PREFIX + base58LedgerHash + LedgerConsts.KEY_SEPERATOR; } + private static class LedgerRepositoryContext { - private LedgerRepository ledgerRepo; + public final LedgerRepository ledgerRepo; - private KVStorageService storageService; + public final KVStorageService storageService; + + public LedgerRepositoryContext(LedgerRepository ledgerRepo, KVStorageService storageService) { + this.ledgerRepo = ledgerRepo; + this.storageService = storageService; + } } } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerQueryService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerQueryService.java index 086b18ff..fba47095 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerQueryService.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerQueryService.java @@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core.impl; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.contract.ContractException; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.*; import com.jd.blockchain.ledger.core.ContractAccountSet; @@ -15,6 +16,10 @@ import com.jd.blockchain.ledger.core.UserAccountSet; import com.jd.blockchain.transaction.BlockchainQueryService; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.QueryUtil; +import com.jd.blockchain.utils.StringUtils; + +import java.util.ArrayList; +import java.util.List; public class LedgerQueryService implements BlockchainQueryService { @@ -263,6 +268,9 @@ public class LedgerQueryService implements BlockchainQueryService { long ver; for (int i = 0; i < entries.length; i++) { ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); + + dataAccount.getBytes(Bytes.fromString(keys[i]),1); + if (ver < 0) { entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); }else { @@ -275,6 +283,60 @@ public class LedgerQueryService implements BlockchainQueryService { return entries; } + public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { + //parse kvInfoVO; + List keyList = new ArrayList<>(); + List versionList = new ArrayList<>(); + if(kvInfoVO != null){ + for(KVDataVO kvDataVO : kvInfoVO.getData()){ + for(Long version : kvDataVO.getVersion()){ + keyList.add(kvDataVO.getKey()); + versionList.add(version); + } + } + } + String[] keys = keyList.toArray(new String[keyList.size()]); + Long[] versions = versionList.toArray(new Long[versionList.size()]); + + if (keys == null || keys.length == 0) { + return null; + } + if (versions == null || versions.length == 0) { + return null; + } + if(keys.length != versions.length){ + throw new ContractException("keys.length!=versions.length!"); + } + + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + + KVDataEntry[] entries = new KVDataEntry[keys.length]; + long ver = -1; + for (int i = 0; i < entries.length; i++) { +// ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); +// dataAccount.getBytes(Bytes.fromString(keys[i]),1); + ver = versions[i]; + if (ver < 0) { + entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); + }else { + if(dataAccount.getDataEntriesTotalCount()==0 || + dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null){ + //is the address is not exist; the result is null; + entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); + } else { + byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + BytesValue decodeData = BinaryProtocol.decode(value); + entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); + } + } + } + + return entries; + } + @Override public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java index 2d51c185..43595152 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java @@ -156,6 +156,11 @@ public class ContractLedgerContext implements LedgerContext { return innerQueryService.getDataEntries(ledgerHash, address, keys); } + @Override + public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { + return innerQueryService.getDataEntries(ledgerHash, address, kvInfoVO); + } + @Override public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { return innerQueryService.getDataEntries(ledgerHash, address, fromIndex, count); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/AccountSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/AccountSetTest.java index 1334bdf5..5b69b118 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/AccountSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/AccountSetTest.java @@ -6,8 +6,12 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.core.AccountSet; @@ -17,6 +21,11 @@ import com.jd.blockchain.ledger.core.impl.OpeningAccessPolicy; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; public class AccountSetTest { + + + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + @Test public void test() { @@ -24,7 +33,12 @@ public class AccountSetTest { MemoryKVStorage storage = new MemoryKVStorage(); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } CryptoConfig cryptoConf = new CryptoConfig(); + cryptoConf.setSupportedProviders(supportedProviders); cryptoConf.setAutoVerifyHash(true); cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java index 5d11b337..23b3445a 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java @@ -5,7 +5,11 @@ import static org.junit.Assert.assertFalse; import org.junit.Test; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.core.BaseAccount; @@ -22,12 +26,21 @@ import com.jd.blockchain.utils.io.BytesUtils; */ public class BaseAccountTest { + public static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + @Test public void basicTest() { String keyPrefix = ""; MemoryKVStorage testStorage = new MemoryKVStorage(); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoConf = new CryptoConfig(); + cryptoConf.setSupportedProviders(supportedProviders); cryptoConf.setAutoVerifyHash(true); cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java index 823b3397..1293a9d8 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java @@ -13,8 +13,12 @@ import com.jd.blockchain.ledger.LedgerMetadata; import org.junit.Test; import com.jd.blockchain.crypto.AddressEncoding; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.ParticipantNode; @@ -30,6 +34,9 @@ import com.jd.blockchain.utils.net.NetworkAddress; public class LedgerAdminAccountTest { + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + private Random rand = new Random(); @Test @@ -55,7 +62,13 @@ public class LedgerAdminAccountTest { initSetting.setConsensusSettings(new Bytes(csSysSettingBytes)); initSetting.setConsensusProvider("consensus-provider"); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoSetting = new CryptoConfig(); + cryptoSetting.setSupportedProviders(supportedProviders); cryptoSetting.setAutoVerifyHash(true); cryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); initSetting.setCryptoSetting(cryptoSetting); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java index 621aa6fc..3ae78c32 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java @@ -11,8 +11,11 @@ import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.SignatureFunction; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInitSetting; @@ -34,6 +37,10 @@ import com.jd.blockchain.utils.io.BytesUtils; import com.jd.blockchain.utils.net.NetworkAddress; public class LedgerEditerTest { + + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + static { DataContractRegistry.register(com.jd.blockchain.ledger.TransactionContent.class); @@ -109,8 +116,14 @@ public class LedgerEditerTest { private LedgerInitSetting createLedgerInitSetting() { SignatureFunction signFunc = Crypto.getSignatureFunction("ED25519"); + + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } CryptoConfig defCryptoSetting = new CryptoConfig(); + defCryptoSetting.setSupportedProviders(supportedProviders); defCryptoSetting.setAutoVerifyHash(true); defCryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java index e9ae7693..9cee71df 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java @@ -12,7 +12,11 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.AddressEncoding; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.LedgerInitOperation; @@ -27,6 +31,9 @@ import com.jd.blockchain.utils.net.NetworkAddress; public class LedgerInitOperationTest { + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + byte[] seed = null; byte[] csSysSettingBytes = null; LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData(); @@ -44,7 +51,12 @@ public class LedgerInitOperationTest { csSysSettingBytes = new byte[64]; rand.nextBytes(csSysSettingBytes); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setAutoVerifyHash(true); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java similarity index 89% rename from source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingTest.java rename to source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java index 7f9a4e7c..f867ae9b 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java @@ -12,7 +12,11 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.AddressEncoding; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.LedgerInitSetting; @@ -24,12 +28,15 @@ import com.jd.blockchain.transaction.LedgerInitSettingData; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.net.NetworkAddress; -public class LedgerInitSettingTest { +public class LedgerInitSettingSerializeTest { byte[] seed = null; byte[] csSysSettingBytes = null; LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData(); LedgerInitOpTemplate template = new LedgerInitOpTemplate(); + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + @Before public void initCfg() { @@ -41,7 +48,13 @@ public class LedgerInitSettingTest { csSysSettingBytes = new byte[64]; rand.nextBytes(csSysSettingBytes); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setAutoVerifyHash(true); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); @@ -71,7 +84,7 @@ public class LedgerInitSettingTest { ConsensusParticipantData[] parties1 = Arrays.copyOf(parties, 4); ledgerInitSettingData.setConsensusParticipants(parties1); - + byte[] encode = BinaryProtocol.encode(ledgerInitSettingData, LedgerInitSetting.class); LedgerInitSetting decode = BinaryProtocol.decode(encode); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java index 9974d5d8..cdbece82 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java @@ -13,9 +13,12 @@ import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.SignatureFunction; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockBody; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; @@ -54,8 +57,12 @@ public class LedgerManagerTest { DataContractRegistry.register(UserRegisterOperation.class); DataContractRegistry.register(DataAccountRegisterOperation.class); DataContractRegistry.register(BlockBody.class); + DataContractRegistry.register(CryptoProvider.class); } + public static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + private SignatureFunction signatureFunction; @Before @@ -170,7 +177,16 @@ public class LedgerManagerTest { } private LedgerInitSetting createLedgerInitSetting() { + + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig defCryptoSetting = new CryptoConfig(); + + defCryptoSetting.setSupportedProviders(supportedProviders); + defCryptoSetting.setAutoVerifyHash(true); defCryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java index f744780d..401c5de2 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java @@ -15,9 +15,13 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.AddressEncoding; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.ledger.core.CryptoConfig; @@ -30,6 +34,10 @@ import com.jd.blockchain.utils.Bytes; * Created by zhangshuang3 on 2018/8/31. */ public class LedgerMetaDataTest { + + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + byte[] seed = null; String consensusProvider = "test-provider"; byte[] consensusSettingBytes = null; @@ -56,7 +64,13 @@ public class LedgerMetaDataTest { // ConsensusConfig consensusConfig = new ConsensusConfig(); // consensusConfig.setValue(settingValue);ClassicCryptoService.ED25519_ALGORITHM + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setAutoVerifyHash(true); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); @@ -93,7 +107,13 @@ public class LedgerMetaDataTest { // ConsensusConfig consensusConfig = new ConsensusConfig(); // consensusConfig.setValue(settingValue); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setAutoVerifyHash(true); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); @@ -133,7 +153,14 @@ public class LedgerMetaDataTest { @Test public void testSerialize_CryptoSetting() { // LedgerCodes.METADATA_LEDGER_SETTING_CRYPTO + + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setAutoVerifyHash(true); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); byte[] encodeBytes = BinaryProtocol.encode(cryptoConfig, CryptoSetting.class); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java index 33dafeec..52f050c4 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java @@ -4,10 +4,13 @@ import java.util.Random; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.crypto.SignatureFunction; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainIdentityData; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.PreparedTransaction; @@ -22,6 +25,9 @@ public class LedgerTestUtils { // private static ThreadLocalRandom rand = ThreadLocalRandom.current(); + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + private static Random rand = new Random(); public static TransactionRequest createTxRequest(HashDigest ledgerHash) { @@ -76,7 +82,14 @@ public class LedgerTestUtils { } public static CryptoSetting createDefaultCryptoSetting() { + + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoSetting = new CryptoConfig(); + cryptoSetting.setSupportedProviders(supportedProviders); cryptoSetting.setAutoVerifyHash(true); cryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); return cryptoSetting; diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java index 2e966c50..fbb5eb09 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java @@ -14,8 +14,12 @@ import java.util.Set; import org.junit.Test; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.core.CryptoConfig; import com.jd.blockchain.ledger.core.MerkleDataSet; import com.jd.blockchain.ledger.core.MerkleProof; @@ -26,13 +30,23 @@ import com.jd.blockchain.utils.io.BytesUtils; public class MerkleDataSetTest { + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + /** * 娴嬭瘯瀛樺偍鐨勫闀匡紱 */ @Test public void testStorageIncreasement() { + + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + String keyPrefix = ""; CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); cryptoConfig.setAutoVerifyHash(true); @@ -116,7 +130,13 @@ public class MerkleDataSetTest { String keyPrefix = ""; Random rand = new Random(); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); cryptoConfig.setAutoVerifyHash(true); @@ -281,7 +301,13 @@ public class MerkleDataSetTest { String keyPrefix = ""; Random rand = new Random(); + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(supportedProviders); cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); cryptoConfig.setAutoVerifyHash(true); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractEventSendOperation.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractEventSendOperation.java index a9bd77e8..b5ee3b5a 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractEventSendOperation.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractEventSendOperation.java @@ -1,26 +1,48 @@ -package com.jd.blockchain.ledger; - -import com.jd.blockchain.binaryproto.DataContract; -import com.jd.blockchain.binaryproto.DataField; -import com.jd.blockchain.binaryproto.PrimitiveType; -import com.jd.blockchain.consts.DataCodes; -import com.jd.blockchain.utils.Bytes; - -/** - * @author huanghaiquan - * - */ -@DataContract(code= DataCodes.TX_OP_CONTRACT_EVENT_SEND) -public interface ContractEventSendOperation extends Operation { - - @DataField(order=2, primitiveType=PrimitiveType.BYTES) - Bytes getContractAddress(); - - @DataField(order=3, primitiveType=PrimitiveType.TEXT) - String getEvent(); - - - @DataField(order=4, primitiveType=PrimitiveType.BYTES) - byte[] getArgs(); - -} +package com.jd.blockchain.ledger; + +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.binaryproto.DataField; +import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.consts.DataCodes; +import com.jd.blockchain.utils.Bytes; + +/** + * @author huanghaiquan + * + */ +@DataContract(code = DataCodes.TX_OP_CONTRACT_EVENT_SEND) +public interface ContractEventSendOperation extends Operation { + + /** + * 鍝嶅簲浜嬩欢鐨勫悎绾﹀湴鍧锛 + * + * @return + */ + @DataField(order = 2, primitiveType = PrimitiveType.BYTES) + Bytes getContractAddress(); + + /** + * 浜嬩欢鍚嶏紱 + * + * @return + */ + @DataField(order = 3, primitiveType = PrimitiveType.TEXT) + String getEvent(); + + /** + * 浜嬩欢鍙傛暟锛 + * + * @return + */ + @DataField(order = 4, primitiveType = PrimitiveType.BYTES) + byte[] getArgs(); + + /** + * 鏃堕棿鎴筹紱 + * + * @return + */ + @DataField(order = 5, primitiveType = PrimitiveType.INT64) + long getTs(); + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CryptoProviderInfo.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CryptoProviderInfo.java deleted file mode 100644 index 01527459..00000000 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CryptoProviderInfo.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.jd.blockchain.ledger; - -import com.jd.blockchain.crypto.CryptoAlgorithm; - -public interface CryptoProviderInfo { - - String getName(); - - CryptoAlgorithm[] getAlgorithms(); - - -} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CryptoSetting.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CryptoSetting.java index cb41c645..9f24322c 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CryptoSetting.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CryptoSetting.java @@ -4,6 +4,7 @@ import com.jd.blockchain.binaryproto.DataContract; import com.jd.blockchain.binaryproto.DataField; import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.consts.DataCodes; +import com.jd.blockchain.crypto.CryptoProvider; /** * 榛樺厠灏旀爲绠楁硶鐩稿叧鐨勯厤缃紱 @@ -14,6 +15,16 @@ import com.jd.blockchain.consts.DataCodes; @DataContract(code = DataCodes.METADATA_CRYPTO_SETTING) public interface CryptoSetting { + /** + * 绯荤粺鏀寔鐨勫瘑鐮佹湇鍔℃彁渚涜咃紱 + * + * @return + */ + @DataField(order = 0, refContract = true, list = true) + public CryptoProvider[] getSupportedProviders(); + + + /** * 绯荤粺涓娇鐢ㄧ殑 Hash 绠楁硶锛
* @@ -27,7 +38,7 @@ public interface CryptoSetting { public short getHashAlgorithm(); /** - * 褰撴湁瀹屾暣鎬ц瘉鏄庣殑鏁版嵁琚粠鎸佷箙鍖栦粙璐ㄤ腑鍔犺浇鏃讹紝鏄惁瀵瑰叾杩涜瀹屾暣鎬ф牎楠岋紙閲嶆柊璁$畻 hash 姣斿鏄惁涓鑷达級锛
+ * 褰撴湁鍔犺浇闄勫甫鍝堝笇鎽樿鐨勬暟鎹椂锛屾槸鍚﹂噸鏂拌绠楀搱甯屾憳瑕佽繘琛屽畬鏁存ф牎楠岋紱
* * 濡傛灉涓 true 锛屽垯鑷姩杩涜鏍¢獙锛屽鏋滄牎楠屽け璐ワ紝浼氬紩鍙戝紓甯革紱
* @@ -37,5 +48,6 @@ public interface CryptoSetting { */ @DataField(order = 2, primitiveType = PrimitiveType.BOOLEAN) public boolean getAutoVerifyHash(); + } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataVO.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataVO.java new file mode 100644 index 00000000..4fc214d0 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataVO.java @@ -0,0 +1,26 @@ +package com.jd.blockchain.ledger; + +/** + * @author zhaogw + * date 2019/5/14 14:17 + */ +public class KVDataVO { + private String key; + private long[] version; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public long[] getVersion() { + return version; + } + + public void setVersion(long[] version) { + this.version = version; + } +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVInfoVO.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVInfoVO.java new file mode 100644 index 00000000..5f49e3de --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVInfoVO.java @@ -0,0 +1,18 @@ +package com.jd.blockchain.ledger; + +/** + * for BlockBrowserController.java, param is json ,then match it; + * @author zhaogw + * date 2019/5/14 14:19 + */ +public class KVInfoVO { + private KVDataVO[] data; + + public KVDataVO[] getData() { + return data; + } + + public void setData(KVDataVO[] data) { + this.data = data; + } +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java index c8974d1c..dd2c62fa 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java @@ -22,6 +22,7 @@ public interface ParticipantNode {// extends ConsensusNode, ParticipantInfo { * * @return */ + @DataField(order = 0, primitiveType = PrimitiveType.INT32) int getId(); /** diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContent.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContent.java index 5203835a..96cdf58b 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContent.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContent.java @@ -1,21 +1,21 @@ -package com.jd.blockchain.ledger; - -import com.jd.blockchain.binaryproto.DataContract; -import com.jd.blockchain.binaryproto.DataField; -import com.jd.blockchain.binaryproto.PrimitiveType; -import com.jd.blockchain.consts.DataCodes; -import com.jd.blockchain.crypto.HashDigest; - -/** - * 浜ゆ槗鍐呭锛 - * - * @author huanghaiquan - * - */ -@DataContract(code= DataCodes.TX_CONTENT) -public interface TransactionContent extends TransactionContentBody, HashObject { - @Override - @DataField(order=1, primitiveType = PrimitiveType.BYTES) - HashDigest getHash(); - -} +package com.jd.blockchain.ledger; + +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.binaryproto.DataField; +import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.consts.DataCodes; +import com.jd.blockchain.crypto.HashDigest; + +/** + * 浜ゆ槗鍐呭锛 + * + * @author huanghaiquan + * + */ +@DataContract(code= DataCodes.TX_CONTENT) +public interface TransactionContent extends TransactionContentBody, HashObject { + @Override + @DataField(order=1, primitiveType = PrimitiveType.BYTES) + HashDigest getHash(); + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContentBody.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContentBody.java index 14ce61ac..e1819224 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContentBody.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionContentBody.java @@ -1,36 +1,36 @@ -package com.jd.blockchain.ledger; - -import com.jd.blockchain.binaryproto.DataContract; -import com.jd.blockchain.binaryproto.DataField; -import com.jd.blockchain.binaryproto.PrimitiveType; -import com.jd.blockchain.consts.DataCodes; -import com.jd.blockchain.crypto.HashDigest; - -/** - * 浜ゆ槗鍐呭锛 - * - * @author huanghaiquan - * - */ -@DataContract(code = DataCodes.TX_CONTENT_BODY) -public interface TransactionContentBody { - - /** - * 鎵ц浜ゆ槗鐨勮处鏈湴鍧锛 - * - * 娉細闄や簡璐︽湰鐨勫垱涓栦氦鏄撲箣澶栵紝浠讳綍浜ゆ槗鐨勮处鏈湴鍧閮戒笉鍏佽涓 null; - * - * @return - */ - @DataField(order = 1, primitiveType = PrimitiveType.BYTES) - HashDigest getLedgerHash(); - - /** - * 鎿嶄綔鍒楄〃锛 - * - * @return - */ - @DataField(order = 2, list = true, refContract = true, genericContract = true) - Operation[] getOperations(); - -} +package com.jd.blockchain.ledger; + +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.binaryproto.DataField; +import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.consts.DataCodes; +import com.jd.blockchain.crypto.HashDigest; + +/** + * 浜ゆ槗鍐呭锛 + * + * @author huanghaiquan + * + */ +@DataContract(code = DataCodes.TX_CONTENT_BODY) +public interface TransactionContentBody { + + /** + * 鎵ц浜ゆ槗鐨勮处鏈湴鍧锛 + * + * 娉細闄や簡璐︽湰鐨勫垱涓栦氦鏄撲箣澶栵紝浠讳綍浜ゆ槗鐨勮处鏈湴鍧閮戒笉鍏佽涓 null; + * + * @return + */ + @DataField(order = 1, primitiveType = PrimitiveType.BYTES) + HashDigest getLedgerHash(); + + /** + * 鎿嶄綔鍒楄〃锛 + * + * @return + */ + @DataField(order = 2, list = true, refContract = true, genericContract = true) + Operation[] getOperations(); + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java index f32f2cc1..e89d41b6 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java @@ -29,6 +29,11 @@ public enum TransactionState { */ LEDGER_ERROR((byte) 2), + /** + * 鏁版嵁搴忓垪鏇存柊閿欒锛 + */ + DATA_SEQUENCE_UPDATE_ERROR((byte) 3), + /** * 绯荤粺閿欒锛 */ diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java index 45301f13..1b46f1aa 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java @@ -261,6 +261,8 @@ public interface BlockchainQueryService { */ KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys); + KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO); + /** * 杩斿洖鎸囧畾鏁版嵁璐︽埛涓璌V鏁版嵁鐨勬绘暟锛
* diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOpTemplate.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOpTemplate.java index 29777b96..aa3a7b6a 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOpTemplate.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOpTemplate.java @@ -1,40 +1,50 @@ -package com.jd.blockchain.transaction; - -import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.ledger.ContractEventSendOperation; -import com.jd.blockchain.utils.Bytes; - -public class ContractEventSendOpTemplate implements ContractEventSendOperation { - static { - DataContractRegistry.register(ContractEventSendOperation.class); - } - - private Bytes contractAddress; - private byte[] args; - private String event; - - public ContractEventSendOpTemplate() { - } - - public ContractEventSendOpTemplate(Bytes contractAddress, String event, byte[] args) { - this.contractAddress = contractAddress; - this.event = event; - this.args = args; - } - - @Override - public Bytes getContractAddress() { - return contractAddress; - } - - @Override - public String getEvent() { - return event; - } - - @Override - public byte[] getArgs() { - return args; - } - -} +package com.jd.blockchain.transaction; + +import com.jd.blockchain.binaryproto.DataContractRegistry; +import com.jd.blockchain.ledger.ContractEventSendOperation; +import com.jd.blockchain.utils.Bytes; + +public class ContractEventSendOpTemplate implements ContractEventSendOperation { + static { + DataContractRegistry.register(ContractEventSendOperation.class); + } + + private Bytes contractAddress; + private byte[] args; + private String event; + + private long ts; + + public ContractEventSendOpTemplate() { + } + + public ContractEventSendOpTemplate(Bytes contractAddress, String event, byte[] args) { + this.contractAddress = contractAddress; + this.event = event; + this.args = args; + } + + @Override + public Bytes getContractAddress() { + return contractAddress; + } + + @Override + public String getEvent() { + return event; + } + + @Override + public byte[] getArgs() { + return args; + } + + @Override + public long getTs() { + return ts; + } + + public void setTs(long ts) { + this.ts = ts; + } +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java index 7c54e4e8..b60153fc 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java @@ -4,18 +4,19 @@ import com.jd.blockchain.ledger.ContractEventSendOperation; import com.jd.blockchain.utils.Bytes; @Deprecated -class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder{ - +class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder { @Override public ContractEventSendOperation send(String address, String event, byte[] args) { ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(Bytes.fromBase58(address), event, args); + op.setTs(System.currentTimeMillis()); return op; } - + @Override public ContractEventSendOperation send(Bytes address, String event, byte[] args) { ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args); + op.setTs(System.currentTimeMillis()); return op; } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOpTemplate.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOpTemplate.java index 5a1b48ab..a9873c4c 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOpTemplate.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOpTemplate.java @@ -49,7 +49,7 @@ public class DataAccountKVSetOpTemplate implements DataAccountKVSetOperation { public void set(String key, BytesValue value, long expVersion) { if (kvset.containsKey(key)) { - throw new IllegalArgumentException("Cann't set the same key repeatly!"); + throw new IllegalArgumentException("Cann't set the same key repeatedly!"); } KVData kvdata = new KVData(key, value, expVersion); kvset.put(key, kvdata); @@ -57,7 +57,7 @@ public class DataAccountKVSetOpTemplate implements DataAccountKVSetOperation { public void set(KVData kvData) { if (kvset.containsKey(kvData.getKey())) { - throw new IllegalArgumentException("Cann't set the same key repeatly!"); + throw new IllegalArgumentException("Cann't set the same key repeatedly!"); } kvset.put(kvData.getKey(), kvData); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java index 904f3adc..12fe552f 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java @@ -1,96 +1,96 @@ -package com.jd.blockchain.transaction; - -import com.jd.blockchain.binaryproto.BinaryProtocol; -import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.crypto.Crypto; -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.TransactionBuilder; -import com.jd.blockchain.ledger.TransactionContent; -import com.jd.blockchain.ledger.TransactionContentBody; -import com.jd.blockchain.ledger.TransactionRequestBuilder; -import com.jd.blockchain.utils.Bytes; - -public class TxBuilder implements TransactionBuilder { - - static { - DataContractRegistry.register(TransactionContentBody.class); - } - - private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); - - private static final String DEFAULT_HASH_ALGORITHM = "SHA256"; - - private HashDigest ledgerHash; - - public TxBuilder(HashDigest ledgerHash) { - this.ledgerHash = ledgerHash; - } - - @Override - public HashDigest getLedgerHash() { - return ledgerHash; - } - - @Override - public TransactionRequestBuilder prepareRequest() { - TransactionContent txContent = prepareContent(); - return new TxRequestBuilder(txContent); - } - - @Override - public TransactionContent prepareContent() { - TxContentBlob txContent = new TxContentBlob(ledgerHash); - txContent.addOperations(opFactory.getOperations()); - - byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); - HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); - txContent.setHash(contentHash); - - return txContent; - } - - @Override - public LedgerInitOperationBuilder ledgers() { - return opFactory.ledgers(); - } - - @Override - public UserRegisterOperationBuilder users() { - return opFactory.users(); - } - - @Override - public DataAccountRegisterOperationBuilder dataAccounts() { - return opFactory.dataAccounts(); - } - - @Override - public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { - return opFactory.dataAccount(accountAddress); - } - - @Override - public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) { - return opFactory.dataAccount(accountAddress); - } - - @Override - public ContractCodeDeployOperationBuilder contracts() { - return opFactory.contracts(); - } - - public ContractEventSendOperationBuilder contractEvents() { - return opFactory.contractEvents(); - } - - @Override - public T contract(Bytes address, Class contractIntf) { - return opFactory.contract(address, contractIntf); - } - - @Override - public T contract(String address, Class contractIntf) { - return opFactory.contract(address, contractIntf); - } - -} +package com.jd.blockchain.transaction; + +import com.jd.blockchain.binaryproto.BinaryProtocol; +import com.jd.blockchain.binaryproto.DataContractRegistry; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.TransactionBuilder; +import com.jd.blockchain.ledger.TransactionContent; +import com.jd.blockchain.ledger.TransactionContentBody; +import com.jd.blockchain.ledger.TransactionRequestBuilder; +import com.jd.blockchain.utils.Bytes; + +public class TxBuilder implements TransactionBuilder { + + static { + DataContractRegistry.register(TransactionContentBody.class); + } + + private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); + + private static final String DEFAULT_HASH_ALGORITHM = "SHA256"; + + private HashDigest ledgerHash; + + public TxBuilder(HashDigest ledgerHash) { + this.ledgerHash = ledgerHash; + } + + @Override + public HashDigest getLedgerHash() { + return ledgerHash; + } + + @Override + public TransactionRequestBuilder prepareRequest() { + TransactionContent txContent = prepareContent(); + return new TxRequestBuilder(txContent); + } + + @Override + public TransactionContent prepareContent() { + TxContentBlob txContent = new TxContentBlob(ledgerHash); + txContent.addOperations(opFactory.getOperations()); + + byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); + HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); + txContent.setHash(contentHash); + + return txContent; + } + + @Override + public LedgerInitOperationBuilder ledgers() { + return opFactory.ledgers(); + } + + @Override + public UserRegisterOperationBuilder users() { + return opFactory.users(); + } + + @Override + public DataAccountRegisterOperationBuilder dataAccounts() { + return opFactory.dataAccounts(); + } + + @Override + public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { + return opFactory.dataAccount(accountAddress); + } + + @Override + public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) { + return opFactory.dataAccount(accountAddress); + } + + @Override + public ContractCodeDeployOperationBuilder contracts() { + return opFactory.contracts(); + } + + public ContractEventSendOperationBuilder contractEvents() { + return opFactory.contractEvents(); + } + + @Override + public T contract(Bytes address, Class contractIntf) { + return opFactory.contract(address, contractIntf); + } + + @Override + public T contract(String address, Class contractIntf) { + return opFactory.contract(address, contractIntf); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxContentBlob.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxContentBlob.java index f1cb2993..ccbe3a98 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxContentBlob.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxContentBlob.java @@ -1,91 +1,91 @@ -package com.jd.blockchain.transaction; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.Operation; -import com.jd.blockchain.ledger.TransactionContent; -import com.jd.blockchain.utils.io.NumberMask; - -/** - * 浜ゆ槗鍐呭鐨勬暟鎹潡锛 - *

- * - * 鍖呭惈鍘熷浜ゆ槗璇锋眰鐨勬暟鎹潡锛 - * - * @author huanghaiquan - * - */ -public class TxContentBlob implements TransactionContent { - - /** - * 鎿嶄綔鏁伴噺鐨勬渶澶у硷紱 - */ - public static final int MAX_OP_COUNT = NumberMask.SHORT.MAX_BOUNDARY_SIZE; - - private List operationList = new ArrayList(); - - private HashDigest hash; - - private HashDigest ledgerHash; - - public TxContentBlob(HashDigest ledgerHash) { - this.ledgerHash = ledgerHash; - } - - /** - * 浜ゆ槗鍐呭鐨勫搱甯屽硷紱 - */ - @Override - public HashDigest getHash() { - return this.hash; - } - - /** - * 鏇存柊浜ゆ槗鍐呭鐨勫搱甯屽硷紱 - *

- * 娉細褰撳墠瀵硅薄鍙厖褰撳煎璞★紝涓嶆牎楠屾寚瀹氬搱甯屽肩殑瀹屾暣鎬э紝璋冪敤鑰呭簲璇ュ湪澶栭儴瀹炴柦瀹屾暣鎬ф牎楠岋紱 - * - * @param hash - */ - public void setHash(HashDigest hash) { - this.hash = hash; - } - - /** - * 浜ゆ槗璇锋眰閾剧殑hash - * - * @return - */ - @Override - public HashDigest getLedgerHash() { - return ledgerHash; - } - - public void setLedgerHash(HashDigest ledgerHash) { - this.ledgerHash = ledgerHash; - } - - @Override - public Operation[] getOperations() { - return operationList.toArray(new Operation[operationList.size()]); - } - - public void setOperations(Object[] operations) { - // in array's case ,cast will failed! - for (Object operation : operations) { - Operation op = (Operation) operation; - addOperation(op); - } - } - - public void addOperation(Operation operation) { - operationList.add(operation); - } - - public void addOperations(Collection operations) { - operationList.addAll(operations); - } -} +package com.jd.blockchain.transaction; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.Operation; +import com.jd.blockchain.ledger.TransactionContent; +import com.jd.blockchain.utils.io.NumberMask; + +/** + * 浜ゆ槗鍐呭鐨勬暟鎹潡锛 + *

+ * + * 鍖呭惈鍘熷浜ゆ槗璇锋眰鐨勬暟鎹潡锛 + * + * @author huanghaiquan + * + */ +public class TxContentBlob implements TransactionContent { + + /** + * 鎿嶄綔鏁伴噺鐨勬渶澶у硷紱 + */ + public static final int MAX_OP_COUNT = NumberMask.SHORT.MAX_BOUNDARY_SIZE; + + private List operationList = new ArrayList(); + + private HashDigest hash; + + private HashDigest ledgerHash; + + public TxContentBlob(HashDigest ledgerHash) { + this.ledgerHash = ledgerHash; + } + + /** + * 浜ゆ槗鍐呭鐨勫搱甯屽硷紱 + */ + @Override + public HashDigest getHash() { + return this.hash; + } + + /** + * 鏇存柊浜ゆ槗鍐呭鐨勫搱甯屽硷紱 + *

+ * 娉細褰撳墠瀵硅薄鍙厖褰撳煎璞★紝涓嶆牎楠屾寚瀹氬搱甯屽肩殑瀹屾暣鎬э紝璋冪敤鑰呭簲璇ュ湪澶栭儴瀹炴柦瀹屾暣鎬ф牎楠岋紱 + * + * @param hash + */ + public void setHash(HashDigest hash) { + this.hash = hash; + } + + /** + * 浜ゆ槗璇锋眰閾剧殑hash + * + * @return + */ + @Override + public HashDigest getLedgerHash() { + return ledgerHash; + } + + public void setLedgerHash(HashDigest ledgerHash) { + this.ledgerHash = ledgerHash; + } + + @Override + public Operation[] getOperations() { + return operationList.toArray(new Operation[operationList.size()]); + } + + public void setOperations(Object[] operations) { + // in array's case ,cast will failed! + for (Object operation : operations) { + Operation op = (Operation) operation; + addOperation(op); + } + } + + public void addOperation(Operation operation) { + operationList.add(operation); + } + + public void addOperations(Collection operations) { + operationList.addAll(operations); + } +} diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceReaderImpl.java b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceReaderImpl.java new file mode 100644 index 00000000..71161411 --- /dev/null +++ b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceReaderImpl.java @@ -0,0 +1,132 @@ +//package com.jd.blockchain.peer.statetransfer; +// +//import com.jd.blockchain.binaryproto.BinaryEncodingUtils; +//import com.jd.blockchain.crypto.hash.HashDigest; +//import com.jd.blockchain.ledger.LedgerBlock; +//import com.jd.blockchain.ledger.LedgerTransaction; +//import com.jd.blockchain.ledger.core.LedgerManage; +//import com.jd.blockchain.ledger.core.LedgerRepository; +//import com.jd.blockchain.ledger.core.TransactionSet; +//import com.jd.blockchain.statetransfer.DataSequenceElement; +//import com.jd.blockchain.statetransfer.DataSequenceInfo; +//import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +//import com.jd.blockchain.storage.service.DbConnection; +//import com.jd.blockchain.storage.service.DbConnectionFactory; +//import com.jd.blockchain.tools.initializer.LedgerBindingConfig; +//import com.jd.blockchain.utils.codec.Base58Utils; +//import com.jd.blockchain.utils.codec.HexUtils; +//import org.springframework.beans.factory.annotation.Autowired; +// +///** +// *鏁版嵁搴忓垪宸紓鐨勬彁渚涜呴渶瑕佷娇鐢ㄧ殑鍥炶皟鎺ュ彛瀹炵幇绫 +// * @author zhangshuang +// * @create 2019/4/11 +// * @since 1.0.0 +// */ +//public class DataSequenceReaderImpl implements DataSequenceReader { +// +// private LedgerManage ledgerManager; +// +// private DbConnectionFactory connFactory; +// +// private LedgerBindingConfig config; +// +// public DataSequenceReaderImpl(LedgerBindingConfig config, LedgerManage ledgerManager, DbConnectionFactory connFactory) { +// this.config = config; +// this.ledgerManager = ledgerManager; +// this.connFactory = connFactory; +// } +// +// +// /** +// * @param id 璐︽湰鍝堝笇鐨凚ase58缂栫爜 +// * @return DataSequenceInfo 鏁版嵁搴忓垪淇℃伅 +// */ +// @Override +// public DataSequenceInfo getDSInfo(String id) { +// +// byte[] hashBytes = Base58Utils.decode(id); +// +// HashDigest ledgerHash = new HashDigest(hashBytes); +// +// LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); +// DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), +// bindingConfig.getDbConnection().getPassword()); +// LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); +// +// return new DataSequenceInfo(id, ledgerRepository.getLatestBlockHeight()); +// } +// +// /** +// * +// * @param id 璐︽湰鍝堝笇鐨凚ase58缂栫爜 +// * @param from 鏁版嵁搴忓垪澶嶅埗鐨勮捣濮嬮珮搴 +// * @param to 鏁版嵁搴忓垪澶嶅埗鐨勭粨鏉熼珮搴 +// * @return DataSequenceElement銆愩戞暟鎹簭鍒楀樊寮傛暟鎹厓绱犵殑鏁扮粍 +// */ +// @Override +// public DataSequenceElement[] getDSDiffContent(String id, long from, long to) { +// +// DataSequenceElement[] dataSequenceElements = new DataSequenceElement[(int)(to - from + 1)]; +// for (long i = from; i < to + 1; i++) { +// dataSequenceElements[(int)(i - from)] = getDSDiffContent(id, i); +// } +// +// return dataSequenceElements; +// } +// +// /** +// * 璐︽湰浜ゆ槗搴忓垪鍖 +// * @param transaction 璐︽湰浜ゆ槗 +// * @return byte[] 瀵硅处鏈氦鏄撹繘琛屽簭鍒楀寲鐨勭粨鏋 +// */ +// private byte[] serialize(LedgerTransaction transaction) { +// return BinaryEncodingUtils.encode(transaction, LedgerTransaction.class); +// } +// +// /** +// * 鑾峰緱璐︽湰鏌愪竴楂樺害鍖哄潡涓婄殑鎵鏈変氦鏄 +// * @param id 璐︽湰鍝堝笇鐨凚ase58缂栫爜 +// * @param height 璐︽湰鐨勬煇涓尯鍧楅珮搴 +// * @return DataSequenceElement 鏁版嵁搴忓垪宸紓鏁版嵁鍏冪礌 +// */ +// @Override +// public DataSequenceElement getDSDiffContent(String id, long height) { +// +// int lastHeightTxTotalNums = 0; +// +// byte[][] transacionDatas = null; +// +// byte[] hashBytes = Base58Utils.decode(id); +// +// HashDigest ledgerHash = new HashDigest(hashBytes); +// +// LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); +// DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), +// bindingConfig.getDbConnection().getPassword()); +// LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); +// +// LedgerBlock ledgerBlock = ledgerRepository.getBlock(height); +// TransactionSet transactionSet = ledgerRepository.getTransactionSet(ledgerBlock); +// +// if (height > 0) { +// lastHeightTxTotalNums = (int) ledgerRepository.getTransactionSet(ledgerRepository.getBlock(height - 1)).getTotalCount(); +// } +// +// int currentHeightTxTotalNums = (int)ledgerRepository.getTransactionSet(ledgerRepository.getBlock(height)).getTotalCount(); +// +// // get all transactions from current height block +// int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; +// +// LedgerTransaction[] transactions = transactionSet.getTxs(lastHeightTxTotalNums , currentHeightTxNums); +// +// for (int i = 0; i < transactions.length; i++) { +// byte[] transactionData = serialize(transactions[i]); +// transacionDatas[i] = transactionData; +// } +// +// return new DataSequenceElement(id, height, transacionDatas); +// } +// +// +//} diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceWriterImpl.java b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceWriterImpl.java new file mode 100644 index 00000000..774e69b5 --- /dev/null +++ b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceWriterImpl.java @@ -0,0 +1,170 @@ +//package com.jd.blockchain.peer.statetransfer; +// +//import com.jd.blockchain.consensus.service.MessageHandle; +//import com.jd.blockchain.ledger.TransactionState; +//import com.jd.blockchain.statetransfer.DataSequenceElement; +//import com.jd.blockchain.statetransfer.DataSequenceInfo; +//import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; +//import com.jd.blockchain.statetransfer.comparator.DataSequenceComparator; +// +//import java.util.ArrayList; +//import java.util.Collections; +// +///** +// *鏁版嵁搴忓垪宸紓鐨勮姹傝呴渶瑕佷娇鐢ㄧ殑鍥炶皟鎺ュ彛瀹炵幇绫 +// * @author zhangshuang +// * @create 2019/4/11 +// * @since 1.0.0 +// */ +//public class DataSequenceWriterImpl implements DataSequenceWriter { +// +// private long currHeight; +// private ArrayList deceidedElements = new ArrayList(); +// +// private MessageHandle batchMessageHandle; +// +// +// public DataSequenceWriterImpl(MessageHandle batchMessageHandle) { +// this.batchMessageHandle = batchMessageHandle; +// } +// +// /** +// * 妫鏌ユ暟鎹簭鍒楀樊寮傚厓绱犱腑鐨勯珮搴︽槸鍚﹀悎鐞嗭紱 +// * @param currHeight 褰撳墠缁撶偣鐨勮处鏈珮搴 +// * @param dsUpdateElements 闇瑕佹洿鏂板埌鏈湴缁撶偣鐨勬暟鎹簭鍒楀厓绱燣ist +// * @return +// */ +// private int checkElementsHeight(long currHeight, ArrayList dsUpdateElements) { +// boolean lossMiddleElements = false; +// +// // lose first element +// if (currHeight + 1 < dsUpdateElements.get(0).getHeight()){ +// System.out.println("Diff response loss first element error!"); +// return DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE; +// } +// else { +// for (int i = 0; i < dsUpdateElements.size(); i++) { +// if (dsUpdateElements.get(i).getHeight() == currHeight + 1 + i) { +// deceidedElements.add(dsUpdateElements.get(i)); +// } +// // lose middle elements +// else { +// lossMiddleElements = true; +// break; +// } +// } +// +// if (lossMiddleElements) { +// System.out.println("Diff response loss middle elements error!"); +// return DataSequenceErrorType.DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT.CODE; +// } +// +// System.out.println("Diff response elements height normal!"); +// return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; +// } +// +// } +// +// /** +// * 瀵规湰鍦扮粨鐐规墽琛岃处鏈洿鏂 +// * @param realmName 璐︽湰鍝堝笇鐨凚ase58缂栫爜 +// * @return void +// */ +// private void exeUpdate(String realmName) { +// +// for (int i = 0; i < deceidedElements.size(); i++) { +// byte[][] element = deceidedElements.get(i).getData(); +// +// String batchId = batchMessageHandle.beginBatch(realmName); +// try { +// int msgId = 0; +// for (byte[] txContent : element) { +// batchMessageHandle.processOrdered(msgId++, txContent, realmName, batchId); +// } +// // 缁撳潡 +// batchMessageHandle.completeBatch(realmName, batchId); +// batchMessageHandle.commitBatch(realmName, batchId); +// } catch (Exception e) { +// // todo 闇瑕佸鐞嗗簲绛旂爜 404 +// batchMessageHandle.rollbackBatch(realmName, batchId, TransactionState.DATA_SEQUENCE_UPDATE_ERROR.CODE); +// } +// } +// +// } +// +// /** +// * @param dsInfo 褰撳墠缁撶偣鐨勬暟鎹簭鍒椾俊鎭 +// * @param diffContents 鏁版嵁搴忓垪宸紓鐨勬暟鎹厓绱犳暟缁 +// * @return int 鏇存柊缁撴灉鐮 +// */ +// @Override +// public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement[] diffContents) { +// int result = 0; +// +// try { +// ArrayList dsUpdateElements = new ArrayList(); +// //remove unexpected elements +// for (int i = 0 ; i < diffContents.length; i++) { +// if (diffContents[i].getId().equals(dsInfo.getId())) { +// dsUpdateElements.add(diffContents[i]); +// } +// } +// +// // sort elements by height +// Collections.sort(dsUpdateElements, new DataSequenceComparator()); +// +// currHeight = dsInfo.getHeight(); +// +// // check element's height +// result = checkElementsHeight(currHeight, dsUpdateElements); +// +// // cann't exe update +// if (result == DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE) { +// return result; +// } +// // exe elements update +// else { +// exeUpdate(dsInfo.getId()); +// return result; +// } +// } catch (Exception e) { +// System.out.println(e.getMessage()); +// e.printStackTrace(); +// } +// +// return result; +// } +// +// @Override +// public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContents) { +// return 0; +// } +// +// +// /** +// * 鏁版嵁搴忓垪鏇存柊閿欒鐮 +// * @param +// * @return +// */ +// public enum DataSequenceErrorType { +// DATA_SEQUENCE_LOSS_FIRST_ELEMENT((byte) 0x1), +// DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT((byte) 0x2), +// DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL((byte) 0x3), +// ; +// public final int CODE; +// +// private DataSequenceErrorType(byte code) { +// this.CODE = code; +// } +// +// public static DataSequenceErrorType valueOf(byte code) { +// for (DataSequenceErrorType errorType : DataSequenceErrorType.values()) { +// if (errorType.CODE == code) { +// return errorType; +// } +// } +// throw new IllegalArgumentException("Unsupported code[" + code + "] of errorType!"); +// } +// } +// +//} diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java b/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java index 6db9674c..222d7bf6 100644 --- a/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java +++ b/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java @@ -1,21 +1,30 @@ package com.jd.blockchain.peer.web; +import com.jd.blockchain.contract.ContractException; import com.jd.blockchain.ledger.*; -import com.jd.blockchain.ledger.core.*; +import com.jd.blockchain.utils.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.core.ContractAccountSet; +import com.jd.blockchain.ledger.core.DataAccount; +import com.jd.blockchain.ledger.core.DataAccountSet; +import com.jd.blockchain.ledger.core.LedgerAdministration; +import com.jd.blockchain.ledger.core.LedgerRepository; +import com.jd.blockchain.ledger.core.LedgerService; +import com.jd.blockchain.ledger.core.ParticipantCertData; +import com.jd.blockchain.ledger.core.TransactionSet; +import com.jd.blockchain.ledger.core.UserAccountSet; import com.jd.blockchain.transaction.BlockchainQueryService; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.QueryUtil; +import java.util.ArrayList; +import java.util.List; + @RestController @RequestMapping(path = "/") public class LedgerQueryController implements BlockchainQueryService { @@ -342,6 +351,63 @@ public class LedgerQueryController implements BlockchainQueryService { return entries; } + @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") + @Override + public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "address") String address, + @RequestBody KVInfoVO kvInfoVO) { + //parse kvInfoVO; + List keyList = new ArrayList<>(); + List versionList = new ArrayList<>(); + if(kvInfoVO != null){ + for(KVDataVO kvDataVO : kvInfoVO.getData()){ + for(Long version : kvDataVO.getVersion()){ + keyList.add(kvDataVO.getKey()); + versionList.add(version); + } + } + } + String[] keys = keyList.toArray(new String[keyList.size()]); + Long[] versions = versionList.toArray(new Long[versionList.size()]); + + if (keys == null || keys.length == 0) { + return null; + } + if (versions == null || versions.length == 0) { + return null; + } + if(keys.length != versions.length){ + throw new ContractException("keys.length!=versions.length!"); + } + + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + + KVDataEntry[] entries = new KVDataEntry[keys.length]; + long ver = -1; + for (int i = 0; i < entries.length; i++) { +// ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); + ver = versions[i]; + if (ver < 0) { + entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); + }else { + if(dataAccount.getDataEntriesTotalCount()==0 || + dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null){ + //is the address is not exist; the result is null; + entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); + } else { + byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + BytesValue decodeData = BinaryProtocol.decode(value); + entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); + } + } + } + + return entries; + } + @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") @Override public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/web/ManagementController.java b/source/peer/src/main/java/com/jd/blockchain/peer/web/ManagementController.java index 0e8c863e..ac95d361 100644 --- a/source/peer/src/main/java/com/jd/blockchain/peer/web/ManagementController.java +++ b/source/peer/src/main/java/com/jd/blockchain/peer/web/ManagementController.java @@ -5,10 +5,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -import com.jd.blockchain.ledger.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -35,6 +31,21 @@ import com.jd.blockchain.consensus.service.NodeServer; import com.jd.blockchain.consensus.service.ServerSettings; import com.jd.blockchain.consensus.service.StateMachineReplicate; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.ContractCodeDeployOperation; +import com.jd.blockchain.ledger.ContractEventSendOperation; +import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.DataAccountKVSetOperation; +import com.jd.blockchain.ledger.DataAccountRegisterOperation; +import com.jd.blockchain.ledger.EndpointRequest; +import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerInitOperation; +import com.jd.blockchain.ledger.NodeRequest; +import com.jd.blockchain.ledger.Operation; +import com.jd.blockchain.ledger.TransactionContent; +import com.jd.blockchain.ledger.TransactionContentBody; +import com.jd.blockchain.ledger.TransactionRequest; +import com.jd.blockchain.ledger.TransactionResponse; +import com.jd.blockchain.ledger.UserRegisterOperation; import com.jd.blockchain.ledger.core.LedgerAdminAccount; import com.jd.blockchain.ledger.core.LedgerManage; import com.jd.blockchain.ledger.core.LedgerRepository; @@ -68,35 +79,17 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag public static final int MIN_GATEWAY_ID = 10000; - // @Autowired - // private PeerSettings peerSetting; - -// @Autowired -// private ConsensusTransactionService consensusService; - - // private ConsensusPeer consensusReplica; - @Autowired private LedgerManage ledgerManager; @Autowired private DbConnectionFactory connFactory; - // private Map ledgerConns = new - // ConcurrentHashMap<>(); - private Map ledgerTxConverters = new ConcurrentHashMap<>(); private Map ledgerPeers = new ConcurrentHashMap<>(); private Map ledgerCryptoSettings = new ConcurrentHashMap<>(); - // private Map nodeRealms = new - // ConcurrentHashMap<>(); - - // private Map ledgerRealms = new - // ConcurrentHashMap<>(); - // private Map ledgerRealmsNoConflict = new - // ConcurrentHashMap<>(); private LedgerBindingConfig config; @@ -106,9 +99,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag @Autowired private StateMachineReplicate consensusStateManager; - // private static int step = 0; - // private static int temp = 0; - static { DataContractRegistry.register(LedgerInitOperation.class); DataContractRegistry.register(LedgerBlock.class); @@ -134,24 +124,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag } - @PostConstruct - private void init() { - - } - - @PreDestroy - private void destroy() { -// DbConnection[] conns = ledgerConns.values().toArray(new DbConnection[ledgerConns.size()]); -// ledgerConns.clear(); -// for (DbConnection conn : conns) { -// try { -// conn.close(); -// } catch (Exception e) { -// // Ignore; -// } -// } - } - /** * 鎺ュ叆璁よ瘉锛 * @@ -234,42 +206,8 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag HashDigest[] ledgerHashs = config.getLedgerHashs(); for (HashDigest ledgerHash : ledgerHashs) { setConfig(config,ledgerHash); -// LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); -// DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), -// bindingConfig.getDbConnection().getPassword()); -// LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); -// -// // load provider; -// LedgerAdminAccount ledgerAdminAccount = ledgerRepository.getAdminAccount(); -// String consensusProvider = ledgerAdminAccount.getSetting().getConsensusProvider(); -// ConsensusProvider provider = ConsensusProviders.getProvider(consensusProvider); -// // find current node; -// Bytes csSettingBytes = ledgerAdminAccount.getSetting().getConsensusSetting(); -// ConsensusSettings csSettings = provider.getSettingsFactory().getConsensusSettingsEncoder() -// .decode(csSettingBytes.toBytes()); -// NodeSettings currentNode = null; -// for (NodeSettings nodeSettings : csSettings.getNodes()) { -// if (nodeSettings.getAddress().equals(bindingConfig.getParticipant().getAddress())) { -// currentNode = nodeSettings; -// } -// } -// if (currentNode == null) { -// throw new IllegalArgumentException( -// "Current node is not found from the consensus settings of ledger[" + ledgerHash.toBase58() -// + "]!"); -// } -// ServerSettings serverSettings = provider.getServerFactory().buildServerSettings(ledgerHash.toBase58(), csSettings, currentNode.getAddress()); -// -// NodeServer server = provider.getServerFactory().setupServer(serverSettings, consensusMessageHandler, -// consensusStateManager); -// ledgerPeers.put(ledgerHash, server); -// ledgerCryptoSettings.put(ledgerHash, ledgerAdminAccount.getSetting().getCryptoSetting()); - } - // remove duplicate consensus realm,and establish consensus peer and consensus - // realm corresponding relationship - // initBindingConfig(config); this.config = config; } catch (Exception e) { @@ -314,46 +252,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag return server; } - // private void initBindingConfig(LedgerBindingConfig config) { - // boolean intersection = false; - // // to remove intersection consensus realm - // for (HashDigest hashDigest : ledgerRealms.keySet()) { - // ConsensusRealm consensusRealm1i = ledgerRealms.get(hashDigest); - // for (ConsensusRealm consensusRealm1j : ledgerRealms.values()) { - // // avoid compare with myself - // if (consensusRealm1i.equals(consensusRealm1j)) { - // continue; - // } - // if (consensusRealm1i.hasIntersection(consensusRealm1j)) { - // intersection = true; - // break; - // } - // } - // // prompt consensus realm conflict info - // if (intersection == true) { - // ConsoleUtils.info("\r\nconsensus realm intersection with other consensus - // realm\r\n"); - // continue; - // } - // if (intersection == false) { - // // add consensus realm without conflict to ledgerRealmsNoConflict - // ledgerRealmsNoConflict.put(hashDigest, consensusRealm1i); - // - // // String consensusSystemFile = - // config.getLedger(hashDigest).getCsConfigFile(); - // int currentId = config.getLedger(hashDigest).getParticipant().getId(); - // // init consensusSystemConfig; - // ConsensusProperties csProps = - // ConsensusProperties.resolve(consensusRealm1i.getSetting()); - // ConsensusPeer consensusPeer = new ConsensusPeer(consensusRealm1i, currentId, - // consensusService, - // csProps.getProperties()); - // ledgerPeers.put(hashDigest, consensusPeer); - // } - // } // END OF FOR:get ledgerRealmsNoConflict and ledgerPeers - // - // } - @Override public ConsensusRealm[] getRealms() { throw new IllegalStateException("Not implemented!"); @@ -364,45 +262,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag for (NodeServer peer : ledgerPeers.values()) { runRealm(peer); } - // try { - // - // // for (ConsensusPeer peer : ledgerPeers.values()) { - // for (Map.Entry entry : ledgerPeers.entrySet()) { - // HashDigest ledgerHash = entry.getKey(); - // ConsensusPeer peer = entry.getValue(); - // // TODO: 澶氱嚎绋嬪惎鍔紱 - // ConsensusNode[] nodes = peer.getConsensusRealm().getNodes(); - // StringBuilder consensusInfo = new StringBuilder(); - // for (ConsensusNode node : nodes) { - // consensusInfo.append( - // String.format("[%s]-%s; ", node.getAddress(), - // node.getConsensusAddress().toString())); - // } - // LOGGER.debug(String.format("-------- start consensus peer[Id=%s] --Nodes=%s - // -------------", - // peer.getCurrentId(), consensusInfo.toString())); - // peer.start(); - // // 璁剧疆娑堟伅闃熷垪 - // MsgQueueMessageDispatcher messageDispatcher = ledgerTxConverters.get(ledgerHash); - // - // if (messageDispatcher == null) { - // LedgerBindingConfig.BindingConfig bindingConfig = - // this.config.getLedger(ledgerHash); - // MQConnectionConfig mqConnection = bindingConfig.getMqConnection(); - // if (mqConnection != null && mqConnection.getServer() != null) { - // MessageQueueConfig mqConfig = new - // MessageQueueConfig(mqConnection.getServer(), - // mqConnection.getTopic()); - // messageDispatcher = MessageDispatcherFactory.newInstance(mqConfig, peer); - // Executors.newSingleThreadExecutor().execute(messageDispatcher); // 鍚姩鐩戝惉 - // } - // } - // } - // } catch (Exception e) { - // LOGGER.error("Error occurred on starting all consensus realms! --" + - // e.getMessage(), e); - // throw new IllegalStateException(e.getMessage(), e); - // } } @Override diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/web/PeerTimeTasks.java b/source/peer/src/main/java/com/jd/blockchain/peer/web/PeerTimeTasks.java index 8e3d220f..698fb584 100644 --- a/source/peer/src/main/java/com/jd/blockchain/peer/web/PeerTimeTasks.java +++ b/source/peer/src/main/java/com/jd/blockchain/peer/web/PeerTimeTasks.java @@ -15,11 +15,11 @@ import com.jd.blockchain.peer.ConsensusManage; import com.jd.blockchain.peer.LedgerBindingConfigAware; import com.jd.blockchain.peer.PeerServerBooter; import com.jd.blockchain.tools.initializer.LedgerBindingConfig; -import com.jd.blockchain.utils.ArgumentSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.io.ClassPathResource; @@ -38,9 +38,11 @@ import java.util.*; * @since 1.0.0 */ @Component -//@EnableScheduling +@EnableScheduling public class PeerTimeTasks implements ApplicationContextAware { + private static Logger LOGGER = LoggerFactory.getLogger(PeerTimeTasks.class); + private ApplicationContext applicationContext; @Autowired @@ -51,7 +53,9 @@ public class PeerTimeTasks implements ApplicationContextAware { //姣1鍒嗛挓鎵ц涓娆 @Scheduled(cron = "0 */5 * * * * ") public void updateLedger(){ - System.out.println ("Update Ledger Tasks Start " + new Date()); + + LOGGER.debug("Time Task Update Ledger Tasks Start {}", new Date()); + try { LedgerBindingConfig ledgerBindingConfig = loadLedgerBindingConfig(); @@ -78,7 +82,8 @@ public class PeerTimeTasks implements ApplicationContextAware { Map bindingConfigAwares = applicationContext.getBeansOfType(LedgerBindingConfigAware.class); List nodeServers = new ArrayList<>(); for (HashDigest ledgerHash : newAddHashs) { - System.out.printf("newLedger[%s] \r\n", ledgerHash.toBase58()); + + LOGGER.info("New Ledger [{}] Need To Be Init !!!", ledgerHash.toBase58()); for (LedgerBindingConfigAware aware : bindingConfigAwares.values()) { nodeServers.add(aware.setConfig(ledgerBindingConfig, ledgerHash)); } @@ -89,10 +94,10 @@ public class PeerTimeTasks implements ApplicationContextAware { consensusManage.runRealm(nodeServer); } } else { - System.out.println("All Ledgers is newest!!!"); + LOGGER.debug("All Ledgers is newest!!!"); } } catch (Exception e) { - e.printStackTrace(); + LOGGER.error(e.getMessage()); } } @@ -104,7 +109,8 @@ public class PeerTimeTasks implements ApplicationContextAware { private LedgerBindingConfig loadLedgerBindingConfig() throws Exception { LedgerBindingConfig ledgerBindingConfig; ledgerBindConfigFile = PeerServerBooter.ledgerBindConfigFile; - System.out.printf("load ledgerBindConfigFile = %s \r\n", ledgerBindConfigFile); + LOGGER.debug("Load LedgerBindConfigFile path = {}", + ledgerBindConfigFile == null ? "Default" : ledgerBindConfigFile); if (ledgerBindConfigFile == null) { ClassPathResource configResource = new ClassPathResource("ledger-binding.conf"); InputStream in = configResource.getInputStream(); diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerInitSettings.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerInitSettings.java index fa3c2cd0..d4f287ab 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerInitSettings.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerInitSettings.java @@ -34,7 +34,7 @@ public class LedgerInitSettings { /** * 鍏辫瘑鍗忚 */ - private int consensusProtocol; + private String consensusProtocol; /** * 鍏辫瘑閰嶇疆 @@ -70,11 +70,11 @@ public class LedgerInitSettings { this.cryptoSetting = cryptoSetting; } - public int getConsensusProtocol() { + public String getConsensusProtocol() { return consensusProtocol; } - public void setConsensusProtocol(int consensusProtocol) { + public void setConsensusProtocol(String consensusProtocol) { this.consensusProtocol = consensusProtocol; } @@ -93,21 +93,4 @@ public class LedgerInitSettings { public void setParticipantNodes(ParticipantNode[] participantNodes) { this.participantNodes = participantNodes; } - - public enum CONSENSUS_PROTOCOL { - UNKNOWN(0), - BFTSMART(1), - MSGQUEUE(2), - ; - - private int code; - - CONSENSUS_PROTOCOL(int code) { - this.code = code; - } - - public int code() { - return code; - } - } } diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java index 4dbe7bc9..e18f1df7 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java @@ -147,6 +147,11 @@ public abstract class BlockchainServiceProxy implements BlockchainService { return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys); } + @Override + public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { + return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, kvInfoVO); + } + @Override public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, fromIndex, count); diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java index bfdc0baf..bd063a5d 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java @@ -496,7 +496,11 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService @PathParam(name="address") String address, @RequestParam(name="keys", array = true) String... keys); - @HttpAction(method = HttpMethod.POST, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") + @HttpAction(method=HttpMethod.POST, path="ledgers/{ledgerHash}/accounts/{address}/entries-version") + @Override + KVDataEntry[] getDataEntries(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, + @PathParam(name="address") String address, + @RequestBody KVInfoVO kvInfoVO); /** * 杩斿洖鏁版嵁璐︽埛涓寚瀹氬簭鍙风殑鏈鏂板硷紱 @@ -513,6 +517,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService * 濡傛灉鍙傛暟鍊间负 -1锛屽垯杩斿洖鍏ㄩ儴鐨勮褰曪紱
* @return */ + @HttpAction(method = HttpMethod.POST, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") @Override KVDataEntry[] getDataEntries(@PathParam(name = "ledgerHash") HashDigest ledgerHash, @PathParam(name = "address") String address, diff --git a/source/state-transfer/pom.xml b/source/state-transfer/pom.xml new file mode 100644 index 00000000..d17c8e03 --- /dev/null +++ b/source/state-transfer/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + + com.jd.blockchain + jdchain-root + 0.9.0-SNAPSHOT + + state-transfer + + + + com.jd.blockchain + stp-communication + ${project.version} + + + com.jd.blockchain + utils-common + ${project.version} + + + + com.jd.blockchain + utils-serialize + ${project.version} + + + + + + + diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java new file mode 100644 index 00000000..237a6d47 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java @@ -0,0 +1,75 @@ +package com.jd.blockchain.statetransfer; + +import java.net.InetSocketAddress; +import java.util.LinkedList; + +/** + * 娴嬭瘯杩囩▼寤虹珛鐨勪竴涓暟鎹簭鍒 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class DataSequence { + + private InetSocketAddress address; + private String id; + + // 姣忎釜鏁版嵁搴忓垪缁存姢浜嗕竴绯诲垪鐨勬暟鎹簭鍒楀厓绱 + private LinkedList dataSequenceElements = new LinkedList<>(); + + + public DataSequence(InetSocketAddress address, String id) { + this.address = address; + this.id = id; + } + + public String getId() { + return id; + } + + public InetSocketAddress getAddress() { + return address; + } + + + public void addElements(DataSequenceElement[] elements) { + for (DataSequenceElement element : elements) { + addElement(element); + } + } + + public void addElement(DataSequenceElement element) { + try { + if (dataSequenceElements.size() == 0) { + if (element.getHeight() != 0) { + throw new IllegalArgumentException("Data sequence add element height error!"); + } + dataSequenceElements.addLast(element); + } + else { + if (dataSequenceElements.getLast().getHeight() != element.getHeight() - 1) { + throw new IllegalArgumentException("Data sequence add element height error!"); + } + dataSequenceElements.addLast(element); + } + + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } + + public LinkedList getDataSequenceElements() { + return dataSequenceElements; + } + + public DataSequenceInfo getDSInfo() { + if (dataSequenceElements.size() == 0) { + return new DataSequenceInfo(id, -1); + } + else { + return new DataSequenceInfo(id, dataSequenceElements.getLast().getHeight()); + } + } + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceElement.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceElement.java new file mode 100644 index 00000000..aaf6e7f5 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceElement.java @@ -0,0 +1,53 @@ +package com.jd.blockchain.statetransfer; + +import java.io.Serializable; + +/** + * 鏁版嵁搴忓垪闇瑕佸鍒跺唴瀹圭殑鍏冪礌鎴栧崟浣 + * @author zhangshuang + * @create 2019/4/11 + * @since 1.0.0 + */ +public class DataSequenceElement implements Serializable { + + private static final long serialVersionUID = -719578198150380571L; + + //鏁版嵁搴忓垪鐨勫敮涓鏍囪瘑绗︼紱 + private String id; + + //鏁版嵁搴忓垪鐨勬煇涓珮搴︼紱 + private long height; + + //瀵瑰簲鏌愪釜楂樺害鐨勬暟鎹簭鍒楀唴瀹 + private byte[][] data; + + public DataSequenceElement(String id, long height, byte[][] data) { + this.id = id; + this.height = height; + this.data = data; + } + + public long getHeight() { + return height; + } + + public void setHeight(long height) { + this.height = height; + } + + public String getId() { + return id; + } + + public void setId(String id) { + id = id; + } + + public byte[][] getData() { + return data; + } + + public void setData(byte[][] data) { + this.data = data; + } +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceInfo.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceInfo.java new file mode 100644 index 00000000..6f0f2e10 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceInfo.java @@ -0,0 +1,37 @@ +package com.jd.blockchain.statetransfer; + +/** + * 鍏辫瘑缁撶偣涓婄殑鏌愪釜鏁版嵁搴忓垪鐨勫綋鍓嶇姸鎬佷俊鎭紝姣忎釜鍏辫瘑缁撶偣鍙互瀵瑰簲浠绘剰涓暟鎹簭鍒楋紱 + * @author zhangshuang + * @create 2019/4/11 + * @since 1.0.0 + */ +public class DataSequenceInfo { + + //鏁版嵁搴忓垪鐨勫敮涓鏍囪瘑 + private String id; + + //鏁版嵁搴忓垪鐨勫綋鍓嶉珮搴 + private long height; + + public DataSequenceInfo(String id, long height) { + this.id = id; + this.height = height; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public long getHeight() { + return height; + } + + public void setHeight(long height) { + this.height = height; + } +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReader.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReader.java new file mode 100644 index 00000000..e137b929 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReader.java @@ -0,0 +1,39 @@ +package com.jd.blockchain.statetransfer.callback; + +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; + +/** + * 鏁版嵁搴忓垪宸紓鎻愪緵鑰呴渶瑕佷娇鐢ㄧ殑鍥炶皟鎺ュ彛 + * @author zhangshuang + * @create 2019/4/11 + * @since 1.0.0 + */ +public interface DataSequenceReader { + + /** + * 宸紓鎻愪緵鑰呮牴鎹暟鎹簭鍒楁爣璇嗙鑾峰彇鏁版嵁搴忓垪褰撳墠鐘舵侊紱 + * @param id 鏁版嵁搴忓垪鏍囪瘑绗 + * @return 鏁版嵁搴忓垪褰撳墠鐘舵佷俊鎭 + */ + DataSequenceInfo getDSInfo(String id); + + + /** + * 宸紓鎻愪緵鑰呮牴鎹暟鎹簭鍒楁爣璇嗙浠ュ強璧峰锛岀粨鏉熼珮搴︽彁渚涙暟鎹簭鍒楄鑼冨洿鐨勫樊寮傚唴瀹癸紱 + * @param id 鏁版嵁搴忓垪鏍囪瘑绗 + * @param from 宸紓鐨勮捣濮嬮珮搴 + * @param to 宸紓鐨勭粨鏉熼珮搴 + * @return 宸紓鍏冪礌缁勬垚鐨勬暟缁 + */ + DataSequenceElement[] getDSDiffContent(String id, long from, long to); + + + /** + * 宸紓鎻愪緵鑰呮牴鎹暟鎹簭鍒楁爣璇嗙浠ュ強楂樺害鎻愪緵鏁版嵁搴忓垪鐨勫樊寮傚唴瀹癸紱 + * @param id 鏁版嵁搴忓垪鏍囪瘑绗 + * @param height 瑕佽幏寰楀摢涓珮搴︾殑宸紓鍏冪礌 + * @return 宸紓鍏冪礌 + */ + DataSequenceElement getDSDiffContent(String id, long height); +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java new file mode 100644 index 00000000..3d581b2d --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java @@ -0,0 +1,59 @@ +package com.jd.blockchain.statetransfer.callback; + +import com.jd.blockchain.statetransfer.DataSequence; +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; + +import java.util.LinkedList; + +/** + * 鏁版嵁搴忓垪宸紓鐨勬彁渚涜呴渶瑕佷娇鐢ㄧ殑鍥炶皟鎺ュ彛瀹炵幇绫 + * @author zhangshuang + * @create 2019/4/22 + * @since 1.0.0 + */ + +public class DataSequenceReaderImpl implements DataSequenceReader { + + DataSequence currDataSequence; + + public DataSequenceReaderImpl(DataSequence currDataSequence) { + this.currDataSequence = currDataSequence; + } + + @Override + public DataSequenceInfo getDSInfo(String id) { + return currDataSequence.getDSInfo(); + } + + @Override + public DataSequenceElement[] getDSDiffContent(String id, long from, long to) { + DataSequenceElement[] elements = new DataSequenceElement[(int)(to - from + 1)]; + + int i = 0; + LinkedList dataSequenceElements = currDataSequence.getDataSequenceElements(); + for (DataSequenceElement element : dataSequenceElements) { + if (element.getHeight() < from || element.getHeight() > to) { + continue; + } + else { + elements[i++] = element; + } + } + + return elements; + + } + + @Override + public DataSequenceElement getDSDiffContent(String id, long height) { + for(DataSequenceElement dataSequenceElement : currDataSequence.getDataSequenceElements()) { + if (dataSequenceElement.getHeight() == height) { + return dataSequenceElement; + + } + } + return null; + } +} + diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java new file mode 100644 index 00000000..b45eb3ac --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java @@ -0,0 +1,30 @@ +package com.jd.blockchain.statetransfer.callback; + +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; + +/** + * 鏁版嵁搴忓垪宸紓璇锋眰鑰呰幏寰楀樊寮傚唴瀹瑰悗闇瑕佸洖璋冭鎺ュ彛 + * @author zhangshuang + * @create 2019/4/11 + * @since 1.0.0 + */ +public interface DataSequenceWriter { + + /** + * 宸紓璇锋眰鑰呮洿鏂版湰鍦版暟鎹簭鍒楃殑鐘舵,涓娆″彲浠ユ洿鏂板涓樊寮傚厓绱 + * @param dsInfo 鏁版嵁搴忓垪褰撳墠鐘舵佷俊鎭 + * @param diffContents 闇瑕佹洿鏂扮殑宸紓鍏冪礌鏁扮粍 + * @return 鏇存柊缁撴灉缂栫爜 + */ + int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement[] diffContents); + + /** + * 宸紓璇锋眰鑰呮洿鏂版湰鍦版暟鎹簭鍒楃殑鐘舵侊紝涓娆″彧鏇存柊涓涓樊寮傚厓绱 + * @param dsInfo 鏁版嵁搴忓垪褰撳墠鐘舵佷俊鎭 + * @param diffContent 闇瑕佹洿鏂扮殑宸紓鍏冪礌 + * @return 鏇存柊缁撴灉缂栫爜 + */ +// int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContent); + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java new file mode 100644 index 00000000..c510e843 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java @@ -0,0 +1,142 @@ +package com.jd.blockchain.statetransfer.callback; + +import com.jd.blockchain.statetransfer.DataSequence; +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; + +import java.util.ArrayList; + +/** + * 鏁版嵁搴忓垪宸紓鐨勮姹傝呴渶瑕佷娇鐢ㄧ殑鍥炶皟鎺ュ彛瀹炵幇绫 + * @author zhangshuang + * @create 2019/4/22 + * @since 1.0.0 + */ +public class DataSequenceWriterImpl implements DataSequenceWriter { + + private long currHeight; + private DataSequence currDataSequence; + private ArrayList deceidedElements = new ArrayList(); + + public DataSequenceWriterImpl(DataSequence currDataSequence) { + this.currDataSequence = currDataSequence; + } + + /** + * 妫鏌ユ暟鎹簭鍒楀樊寮傚厓绱犱腑鐨勯珮搴︽槸鍚﹀悎鐞嗭紱 + * @param currHeight 褰撳墠缁撶偣鐨勮处鏈珮搴 + * @param dsUpdateElements 闇瑕佹洿鏂板埌鏈湴缁撶偣鐨勬暟鎹簭鍒楀厓绱燣ist + * @return + */ + private int checkElementsHeight(long currHeight, ArrayList dsUpdateElements) { + boolean lossMiddleElements = false; + + // lose first element + if (currHeight + 1 < dsUpdateElements.get(0).getHeight()){ + System.out.println("Diff response loss first element error!"); + return DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE; + } + else { + for (int i = 0; i < dsUpdateElements.size(); i++) { + if (dsUpdateElements.get(i).getHeight() == currHeight + 1 + i) { + deceidedElements.add(dsUpdateElements.get(i)); + } + // lose middle elements + else { + lossMiddleElements = true; + break; + } + } + + if (lossMiddleElements) { + System.out.println("Diff response loss middle elements error!"); + return DataSequenceErrorType.DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT.CODE; + } + + System.out.println("Diff response elements height normal!"); + return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; + } + + } + + @Override + public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement[] diffContents) { + + int result = 0; + + try { + ArrayList dsUpdateElements = new ArrayList(); + + if (diffContents == null) { + throw new IllegalArgumentException("Update diffContents is null!"); + } + + //remove unexpected elements + for (int i = 0 ; i < diffContents.length; i++) { + if (diffContents[i].getId().equals(dsInfo.getId())) { + dsUpdateElements.add(diffContents[i]); + } + } + + currHeight = dsInfo.getHeight(); + + // check element's height + result = checkElementsHeight(currHeight, dsUpdateElements); + + // cann't exe update + if (result == DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE) { + return result; + } + // exe elements update + else { + System.out.println("Old data sequence state: "); + System.out.println(" Current height = " + currDataSequence.getDataSequenceElements().getLast().getHeight()); + currDataSequence.addElements(deceidedElements.toArray(new DataSequenceElement[deceidedElements.size()])); + + System.out.println("Update diffContents is completed!"); + System.out.println("New data sequence state: "); + System.out.println(" Current height = " + currDataSequence.getDataSequenceElements().getLast().getHeight()); + + return result; + } + + + + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + + return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; + + } + +// @Override +// public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContent) { +// currDataSequence.addElement(diffContent); +// return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; +// } + + public enum DataSequenceErrorType { + DATA_SEQUENCE_LOSS_FIRST_ELEMENT((byte) 0x1), + DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT((byte) 0x2), + DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL((byte) 0x3), + ; + public final int CODE; + + private DataSequenceErrorType(byte code) { + this.CODE = code; + } + + public static DataSequenceErrorType valueOf(byte code) { + for (DataSequenceErrorType errorType : DataSequenceErrorType.values()) { + if (errorType.CODE == code) { + return errorType; + } + } + throw new IllegalArgumentException("Unsupported code[" + code + "] of errorType!"); + } + } + +} + diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/comparator/DataSequenceComparator.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/comparator/DataSequenceComparator.java new file mode 100644 index 00000000..9e0afbe5 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/comparator/DataSequenceComparator.java @@ -0,0 +1,32 @@ +package com.jd.blockchain.statetransfer.comparator; + +import com.jd.blockchain.statetransfer.DataSequenceElement; + +import java.util.Comparator; + +/** + * 鏁版嵁搴忓垪宸紓鍏冪礌鐨勯珮搴︽瘮杈冨櫒 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class DataSequenceComparator implements Comparator { + + // sort by data sequence height + /** + * 瀵瑰樊寮傚厓绱犳牴鎹珮搴﹀ぇ灏忔帓搴 + * @param o1 宸紓鍏冪礌1 + * @param o2 宸紓鍏冪礌2 + * @return >0 or <0 + */ + @Override + public int compare(DataSequenceElement o1, DataSequenceElement o2) { + long height1; + long height2; + + height1 = o1.getHeight(); + height2 = o2.getHeight(); + + return (int) (height1 - height2); + } +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/exception/DataSequenceException.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/exception/DataSequenceException.java new file mode 100644 index 00000000..5e6248c0 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/exception/DataSequenceException.java @@ -0,0 +1,21 @@ +package com.jd.blockchain.statetransfer.exception; + +/** + * 鏁版嵁搴忓垪寮傚父澶勭悊 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class DataSequenceException extends RuntimeException { + + private static final long serialVersionUID = -4090881296855827889L; + + + public DataSequenceException(String message) { + super(message); + } + public DataSequenceException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSDefaultMessageExecutor.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSDefaultMessageExecutor.java new file mode 100644 index 00000000..6c67e8c8 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSDefaultMessageExecutor.java @@ -0,0 +1,80 @@ +package com.jd.blockchain.statetransfer.message; + +import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; +import com.jd.blockchain.statetransfer.process.DSTransferProcess; +import com.jd.blockchain.statetransfer.result.DSDiffRequestResult; +import com.jd.blockchain.stp.communication.MessageExecutor; +import com.jd.blockchain.stp.communication.RemoteSession; + +/** + * 鏁版嵁搴忓垪宸紓鎻愪緵鑰呬娇鐢紝瑙f瀽鏀跺埌鐨勫樊寮傝姹傛秷鎭苟浜х敓鍝嶅簲 + * @author zhangshuang + * @create 2019/4/11 + * @since 1.0.0 + */ +public class DSDefaultMessageExecutor implements MessageExecutor { + + DataSequenceReader dsReader; + DataSequenceWriter dsWriter; + + public DSDefaultMessageExecutor(DataSequenceReader dsReader, DataSequenceWriter dsWriter) { + this.dsReader = dsReader; + this.dsWriter = dsWriter; + } + + /** + * 瀵圭姸鎬佹満澶嶅埗鐨勫樊寮傝姹傝繘琛屽搷搴 + * @param key 璇锋眰娑堟伅鐨凨ey + * @param data 闇瑕佽В鐮佺殑瀛楄妭鏁扮粍 + * @param session 鎸囧畾鍝嶅簲闇瑕佷娇鐢ㄧ殑鐩爣缁撶偣浼氳瘽 + * @return 閰嶇疆涓鸿嚜鍔ㄥ搷搴旀椂锛岃繑鍥炲间负鍝嶅簲鐨勫瓧鑺傛暟缁勶紝閰嶇疆涓烘墜鍔ㄥ搷搴旀椂锛屼笉闇瑕佸叧娉ㄨ繑鍥炲 + */ + + @Override + public byte[] receive(String key, byte[] data, RemoteSession session) { + + try { + Object object = DSMsgResolverFactory.getDecoder(dsWriter, dsReader).decode(data); + + // 瑙f瀽CMD_DSINFO_REQUEST 璇锋眰鐨勬儏鍐 + if (object instanceof String) { + String id = (String)object; + byte[] respLoadMsg = DSMsgResolverFactory.getEncoder(dsWriter, dsReader).encode(DSTransferProcess.DataSequenceMsgType.CMD_DSINFO_RESPONSE, id, 0, 0); + session.reply(key, new DataSequenceLoadMessage(respLoadMsg)); + } + // 瑙f瀽CMD_GETDSDIFF_REQUEST 璇锋眰鐨勬儏鍐 + else if (object instanceof DSDiffRequestResult) { + + DSDiffRequestResult requestResult = (DSDiffRequestResult)object; + String id = requestResult.getId(); + long fromHeight = requestResult.getFromHeight(); + long toHeight = requestResult.getToHeight(); + //姣忎釜楂樺害鐨勬暟鎹簭鍒楀樊寮傚厓绱犺繘琛屼竴娆″搷搴旂殑鎯呭喌 + for (long i = fromHeight; i < toHeight + 1; i++) { + byte[] respLoadMsg = DSMsgResolverFactory.getEncoder(dsWriter, dsReader).encode(DSTransferProcess.DataSequenceMsgType.CMD_GETDSDIFF_RESPONSE, id, i, i); + session.reply(key, new DataSequenceLoadMessage(respLoadMsg)); + } + //鎵鏈夊樊寮傝繘琛屼竴娆″搷搴旂殑鎯呭喌 + } + else { + throw new IllegalArgumentException("Receive data exception, unknown message type!"); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + /** + * 鍝嶅簲绫诲瀷璁剧疆 + * 鍒嗘墜鍔ㄥ搷搴旓紝鑷姩鍝嶅簲涓ょ绫诲瀷 + */ + @Override + public REPLY replyType() { + return REPLY.MANUAL; + } + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSMsgResolverFactory.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSMsgResolverFactory.java new file mode 100644 index 00000000..c0dfae8d --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSMsgResolverFactory.java @@ -0,0 +1,34 @@ +package com.jd.blockchain.statetransfer.message; + +import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; + +/** + * 鏁版嵁搴忓垪娑堟伅瑙f瀽鍣ㄥ伐鍘 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + * + */ +public class DSMsgResolverFactory { + + /** + * 鑾峰緱鏁版嵁搴忓垪娑堟伅缂栫爜鍣ㄥ疄渚 + * @param dsWriter 宸紓璇锋眰鑰呮墽琛屾暟鎹簭鍒楁洿鏂扮殑鎵ц鍣 + * @param dsReader 宸紓鍝嶅簲鑰呮墽琛屾暟鎹簭鍒楄鍙栫殑鎵ц鍣 + * @return 娑堟伅缂栫爜鍣ㄥ疄渚 + */ + public static DataSequenceMsgEncoder getEncoder(DataSequenceWriter dsWriter, DataSequenceReader dsReader) { + return new DataSequenceMsgEncoder(dsWriter, dsReader); + } + + /** + * 鑾峰緱鏁版嵁搴忓垪娑堟伅瑙g爜鍣ㄥ疄渚 + * @param dsWriter 宸紓璇锋眰鑰呮墽琛屾暟鎹簭鍒楁洿鏂扮殑鎵ц鍣 + * @param dsReader 宸紓鍝嶅簲鑰呮墽琛屾暟鎹簭鍒楄鍙栫殑鎵ц鍣 + * @return 娑堟伅瑙g爜鍣ㄥ疄渚 + */ + public static DataSequenceMsgDecoder getDecoder(DataSequenceWriter dsWriter, DataSequenceReader dsReader) { + return new DataSequenceMsgDecoder(dsWriter, dsReader); + } +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceLoadMessage.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceLoadMessage.java new file mode 100644 index 00000000..a4131e61 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceLoadMessage.java @@ -0,0 +1,28 @@ +package com.jd.blockchain.statetransfer.message; + +import com.jd.blockchain.stp.communication.message.LoadMessage; + +/** + * 鏁版嵁搴忓垪澶嶅埗鐨勮礋杞芥秷鎭 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + * + */ +public class DataSequenceLoadMessage implements LoadMessage { + + byte[] bytes; + + public DataSequenceLoadMessage(byte[] bytes) { + this.bytes = bytes; + } + + public void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + @Override + public byte[] toBytes() { + return bytes; + } +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgDecoder.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgDecoder.java new file mode 100644 index 00000000..6bfa4c97 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgDecoder.java @@ -0,0 +1,107 @@ +package com.jd.blockchain.statetransfer.message; + +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; +import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; +import com.jd.blockchain.statetransfer.process.DSTransferProcess; +import com.jd.blockchain.statetransfer.result.DSDiffRequestResult; +import com.jd.blockchain.utils.io.BytesUtils; +import com.jd.blockchain.utils.serialize.binary.BinarySerializeUtils; + +/** + * 鏁版嵁搴忓垪娑堟伅瑙g爜鍣 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class DataSequenceMsgDecoder { + + private int heightSize = 8; + private int msgTypeSize = 1; + + private long respHeight; + private long fromHeight; + private long toHeight; + private int idSize; + private byte[] idBytes; + private String id; + private int diffElemSize; + private byte[] diffElem; + DataSequenceElement dsElement; + + private DataSequenceWriter dsWriter; + private DataSequenceReader dsReader; + + public DataSequenceMsgDecoder(DataSequenceWriter dsWriter, DataSequenceReader dsReader) { + this.dsWriter = dsWriter; + this.dsReader = dsReader; + } + + + /** + * 瀵圭紪杩囩爜鐨勫瓧鑺傛暟缁勮В鐮侊紝杩樺師鎴愬璞″疄渚 + * @param loadMessage 瀛楄妭搴忓垪 + * @return 瑙g爜鍚庣殑瀵硅薄 + */ + public Object decode(byte[] loadMessage) { + + try { + if (loadMessage.length <= 5) { + System.out.println("LoadMessage size is less than 5!"); + throw new IllegalArgumentException(); + } + + int dataLength = BytesUtils.toInt(loadMessage, 0, 4); + byte msgCode = loadMessage[4]; + + // send by diff provider, diff requester decode + if (msgCode == DSTransferProcess.DataSequenceMsgType.CMD_DSINFO_RESPONSE.CODE) { + respHeight = BytesUtils.toLong(loadMessage, 4 + msgTypeSize); + idSize = BytesUtils.toInt(loadMessage, 4 + msgTypeSize + heightSize, 4); + idBytes = new byte[idSize]; + System.arraycopy(loadMessage, 4 + msgTypeSize + heightSize + 4, idBytes, 0, idSize); + id = new String(idBytes); + return new DataSequenceInfo(id, respHeight); + } + // send by diff provider, diff requester decode + else if (msgCode == DSTransferProcess.DataSequenceMsgType.CMD_GETDSDIFF_RESPONSE.CODE) { + diffElemSize = BytesUtils.toInt(loadMessage, 4 + msgTypeSize, 4); + diffElem = new byte[diffElemSize]; + System.arraycopy(loadMessage, 4 + msgTypeSize + 4, diffElem, 0, diffElemSize); + dsElement = BinarySerializeUtils.deserialize(diffElem); + return dsElement; + } + // send by diff requester, diff provider decode + else if (msgCode == DSTransferProcess.DataSequenceMsgType.CMD_DSINFO_REQUEST.CODE) { + idSize = BytesUtils.toInt(loadMessage, 4 + msgTypeSize, 4); + idBytes = new byte[idSize]; + System.arraycopy(loadMessage, 4 + msgTypeSize + 4, idBytes, 0, idSize); + id = new String(idBytes); + return id; + } + // send by diff requester, diff provider decode + else if (msgCode == DSTransferProcess.DataSequenceMsgType.CMD_GETDSDIFF_REQUEST.CODE) { + fromHeight = BytesUtils.toLong(loadMessage, 4 + msgTypeSize); + toHeight = BytesUtils.toLong(loadMessage, 4 + msgTypeSize + heightSize); + idSize = BytesUtils.toInt(loadMessage, 4 + msgTypeSize + heightSize + heightSize, 4); + idBytes = new byte[idSize]; + System.arraycopy(loadMessage, 4 + msgTypeSize + heightSize + heightSize + 4, idBytes, 0, idSize); + id = new String(idBytes); + return new DSDiffRequestResult(id, fromHeight, toHeight); + } + else { + System.out.println("Unknown message type!"); + throw new IllegalArgumentException(); + } + + } catch (Exception e) { + System.out.println("Error to decode message: " + e.getMessage() + "!"); + e.printStackTrace(); + + } + + return null; + } + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgEncoder.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgEncoder.java new file mode 100644 index 00000000..71b3ef4c --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgEncoder.java @@ -0,0 +1,133 @@ +package com.jd.blockchain.statetransfer.message; + +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; +import com.jd.blockchain.statetransfer.process.DSTransferProcess; +import com.jd.blockchain.utils.io.BytesUtils; +import com.jd.blockchain.utils.serialize.binary.BinarySerializeUtils; + +/** + * 鏁版嵁搴忓垪娑堟伅缂栫爜鍣 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class DataSequenceMsgEncoder { + + private int heightSize = 8; + private int msgTypeSize = 1; + + private DataSequenceWriter dsWriter; + private DataSequenceReader dsReader; + + public DataSequenceMsgEncoder(DataSequenceWriter dsWriter, DataSequenceReader dsReader) { + this.dsWriter = dsWriter; + this.dsReader = dsReader; + } + + /** + * 鐩墠鏆傛椂鑰冭檻fromHeight涓巘oHeight鐩稿悓鐨勬儏鍐碉紝鍗虫瘡娆″彧瀵逛竴涓珮搴︾殑宸紓鍐呭杩涜缂栫爜骞跺搷搴 + * 鎶婃秷鎭紪鐮佹垚瀛楄妭鏁扮粍锛屽啀浜ょ粰閫氫俊灞備紶杈 + * @param msgType 鏁版嵁搴忓垪鐘舵佸鍒舵秷鎭被鍨 + * @param id 鏁版嵁搴忓垪鍞竴鏍囪瘑绗 + * @param fromHeight 宸紓鍏冪礌璧峰楂樺害 + * @param toHeight 宸紓鍏冪礌缁撴潫楂樺害 + */ + public byte[] encode(DSTransferProcess.DataSequenceMsgType msgType, String id, long fromHeight, long toHeight) { + + try { + + int dataLength; + int idSize = id.getBytes().length; + byte[] loadMessage = null; + + // different encoding methods for different message types + // send by diff requester, diff requester encode + if (msgType == DSTransferProcess.DataSequenceMsgType.CMD_DSINFO_REQUEST) { + + // CMD_DSINFO_REQUEST Message parts : 4 bytes total message size, 1 byte message type coe, + // 4 bytes id length, id content size bytes + + dataLength = 4 + msgTypeSize + 4 + idSize; + + loadMessage = new byte[dataLength]; + + System.arraycopy(BytesUtils.toBytes(dataLength), 0, loadMessage, 0, 4); + loadMessage[4] = msgType.CODE; + System.arraycopy(BytesUtils.toBytes(idSize), 0, loadMessage, 4 + msgTypeSize, 4); + System.arraycopy(id.getBytes(), 0, loadMessage, 4 + msgTypeSize + 4, idSize); + } + // send by diff requester, diff requester encode + else if (msgType == DSTransferProcess.DataSequenceMsgType.CMD_GETDSDIFF_REQUEST) { + + // CMD_GETDSDIFF_REQUEST Message parts : 4 bytes total message size, 1 byte message type coe, 8 bytes from height, + // 8 bytes to height, 4 bytes id length, id content size bytes + + dataLength = 4 + msgTypeSize + heightSize + heightSize + 4 + idSize; + + loadMessage = new byte[dataLength]; + + System.arraycopy(BytesUtils.toBytes(dataLength), 0, loadMessage, 0, 4); + loadMessage[4] = msgType.CODE; + System.arraycopy(BytesUtils.toBytes(fromHeight), 0, loadMessage, 4 + msgTypeSize, heightSize); + System.arraycopy(BytesUtils.toBytes(toHeight), 0, loadMessage, 4 + msgTypeSize + heightSize, heightSize); + System.arraycopy(BytesUtils.toBytes(idSize), 0, loadMessage, 4 + msgTypeSize + heightSize + heightSize, 4); + System.arraycopy(id.getBytes(), 0, loadMessage, 4 + msgTypeSize + heightSize + heightSize + 4, idSize); + } + // send by diff provider, diff provider encode + else if (msgType == DSTransferProcess.DataSequenceMsgType.CMD_DSINFO_RESPONSE) { + + // CMD_DSINFO_RESPONSE Message parts : 4 bytes total message size, 1 byte message type coe, 8 bytes data sequence local height, + // 4 bytes id length, id content size bytes + + dataLength = 4 + msgTypeSize + heightSize + 4 + idSize; + + loadMessage = new byte[dataLength]; + + System.arraycopy(BytesUtils.toBytes(dataLength), 0, loadMessage, 0, 4); + loadMessage[4] = msgType.CODE; + System.arraycopy(BytesUtils.toBytes(dsReader.getDSInfo(id).getHeight()), 0, loadMessage, 4 + msgTypeSize, heightSize); + + System.arraycopy(BytesUtils.toBytes(idSize), 0, loadMessage, 4 + msgTypeSize + heightSize, 4); + System.arraycopy(id.getBytes(), 0, loadMessage, 4 + msgTypeSize + heightSize + 4, idSize); + + } + // send by diff provider, diff provider encode + else if (msgType == DSTransferProcess.DataSequenceMsgType.CMD_GETDSDIFF_RESPONSE) { + if (fromHeight != toHeight) { + throw new IllegalArgumentException("Height parameter error!"); + } + + // CMD_DSINFO_RESPONSE Message parts : 4 bytes total message size, 1 byte message type coe, + // 4 bytes diffElem size, diff content size; + + // 鍥炶皟reader,鑾峰緱杩欎釜楂樺害涓婄殑鎵鏈夊樊寮傜殑鏁版嵁搴忓垪鍐呭锛屽苟缁勭粐鎴怐ataSequenceElement缁撴瀯 + DataSequenceElement element = dsReader.getDSDiffContent(id, fromHeight); + + byte[] diffElem = BinarySerializeUtils.serialize(element); + + dataLength = 4 + msgTypeSize + 4 + diffElem.length; + loadMessage = new byte[dataLength]; + + System.arraycopy(BytesUtils.toBytes(dataLength), 0, loadMessage, 0, 4); //total size + loadMessage[4] = msgType.CODE; //msgType size + System.arraycopy(BytesUtils.toBytes(diffElem.length), 0, loadMessage, 4 + msgTypeSize, 4); // diffElem size + System.arraycopy(diffElem, 0, loadMessage, 4 + msgTypeSize + 4, diffElem.length); // diffElem bytes + } + else { + System.out.println("Unknown message type!"); + throw new IllegalArgumentException(); + } + + return loadMessage; + + } catch (Exception e) { + System.out.println("Error to encode message type : " + msgType + "!"); + e.printStackTrace(); + } + + return null; + } + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSProcessManager.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSProcessManager.java new file mode 100644 index 00000000..97b14602 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSProcessManager.java @@ -0,0 +1,186 @@ +package com.jd.blockchain.statetransfer.process; + +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; +import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; +import com.jd.blockchain.statetransfer.comparator.DataSequenceComparator; +import com.jd.blockchain.statetransfer.message.DSDefaultMessageExecutor; +import com.jd.blockchain.statetransfer.result.DSInfoResponseResult; +import com.jd.blockchain.stp.communication.RemoteSession; +import com.jd.blockchain.stp.communication.callback.CallBackBarrier; +import com.jd.blockchain.stp.communication.callback.CallBackDataListener; +import com.jd.blockchain.stp.communication.manager.RemoteSessionManager; +import com.jd.blockchain.stp.communication.node.LocalNode; +import com.jd.blockchain.stp.communication.node.RemoteNode; + +import java.net.InetSocketAddress; +import java.util.*; +import java.util.concurrent.*; + +/** + * 鏁版嵁搴忓垪鐘舵佸鍒惰繃绋嬬鐞嗗櫒 + * @author zhangshuang + * @create 2019/4/11 + * @since 1.0.0 + * + */ +public class DSProcessManager { + + private static Map dSProcessMap = new ConcurrentHashMap<>(); + private RemoteSession[] remoteSessions; + private long dsInfoResponseTimeout = 20000; + private ExecutorService writeExecutors = Executors.newFixedThreadPool(5); + private int returnCode = 0; + + /** + * 鍚姩涓涓寚瀹氭暟鎹簭鍒楃殑鐘舵佸鍒惰繃绋 + * @param dsInfo 鏁版嵁搴忓垪褰撳墠鐘舵佷俊鎭 + * @param listener 鏈湴鐩戝惉鑰 + * @param targets 鐩爣缁撶偣 + * @param dsWriter 宸紓璇锋眰鑰呮墽琛屾暟鎹簭鍒楁洿鏂扮殑鎵ц鍣 + * @param dsReader 宸紓鍝嶅簲鑰呮墽琛屾暟鎹簭鍒楄鍙栫殑鎵ц鍣 + * @return returnCode 鎵ц缁撴灉鐮 + */ + public int startDSProcess(DataSequenceInfo dsInfo, InetSocketAddress listener, InetSocketAddress[] targets, DataSequenceWriter dsWriter, DataSequenceReader dsReader) { + + // create remote sessions manager锛 add listener + LocalNode listenNode = new LocalNode(listener.getHostName(), listener.getPort(), new DSDefaultMessageExecutor(dsReader, dsWriter)); + + RemoteSessionManager remoteSessionManager = new RemoteSessionManager(listenNode); + + // data sequence transfer process life cycle start + DSTransferProcess dsTransferProcess = new DSTransferProcess(dsInfo, targets); + dsTransferProcess.setDSReader(dsReader); + dsTransferProcess.setDSWriter(dsWriter); + dsTransferProcess.setRemoteSessionManager(remoteSessionManager); + + dSProcessMap.put(dsInfo.getId(), dsTransferProcess); + + try { + + //wait all listener nodes start + Thread.sleep(2000); + + // start network connections with targets + dsTransferProcess.start(); + + //get all target sessions + remoteSessions = dsTransferProcess.getSessions(); + + // async message send process + CallBackBarrier callBackBarrier = CallBackBarrier.newCallBackBarrier(remoteSessions.length, dsInfoResponseTimeout); + + // response message manage map + LinkedList dsInfoResponses = new LinkedList<>(); + + System.out.println("Async send CMD_DSINFO_REQUEST msg to targets will start!"); + // step1: send get dsInfo request, then hold + for (RemoteSession remoteSession : remoteSessions) { + CallBackDataListener dsInfoResponse = dsTransferProcess.send(DSTransferProcess.DataSequenceMsgType.CMD_DSINFO_REQUEST, remoteSession, 0, 0, callBackBarrier); + dsInfoResponses.addLast(dsInfoResponse); + } + + System.out.println("Wait CMD_DSINFO_RESPONSE msg from targets!"); + // step2: collect get dsInfo response + LinkedList receiveResponses = new LinkedList<>(); + if (callBackBarrier.tryCall()) { + Iterator iterator = dsInfoResponses.iterator(); + while (iterator.hasNext()) { + CallBackDataListener receiveResponse = iterator.next(); + if (receiveResponse.isDone()) { + receiveResponses.addLast(receiveResponse); + } + } + } + + System.out.printf("%s:%d Compute diff info!\r\n", listener.getHostName(), listener.getPort()); + // step3: process received responses + DSInfoResponseResult diffResult = dsTransferProcess.computeDiffInfo(receiveResponses); + + System.out.printf("%s:%d Diff info result height = %x!\r\n", listener.getHostName(), listener.getPort(), diffResult.getMaxHeight()); + + // height diff + long diff = dsInfo.getHeight() - diffResult.getMaxHeight(); + + if (diff == 0 || diff > 0) { + System.out.printf("%s:%d No duplication is required!\r\n", listener.getHostName(), listener.getPort()); + // no duplication is required锛 life cycle ends +// dsTransferProcess.close(); + dSProcessMap.remove(dsInfo.getId()); + return returnCode; + + } + else { + System.out.printf("%s:%d Duplication is required!\r\n", listener.getHostName(), listener.getPort()); + // step4: async send get data sequence diff request + // single step get diff + // async message send process + CallBackBarrier callBackBarrierDiff = CallBackBarrier.newCallBackBarrier((int)(diffResult.getMaxHeight() - dsInfo.getHeight()), dsInfoResponseTimeout); + LinkedList dsDiffResponses = new LinkedList<>(); + + RemoteSession responseSession = findResponseSession(diffResult.getMaxHeightRemoteNode(), remoteSessions); + System.out.println("Async send CMD_GETDSDIFF_REQUEST msg to targets will start!"); + + // step5: collect get data sequence diff response + for (long height = dsInfo.getHeight() + 1; height < diffResult.getMaxHeight() + 1; height++) { + CallBackDataListener dsDiffResponse = dsTransferProcess.send(DSTransferProcess.DataSequenceMsgType.CMD_GETDSDIFF_REQUEST, responseSession, height, height, callBackBarrierDiff); + dsDiffResponses.addLast(dsDiffResponse); + } + // 涓婅堪鍙戦佷笉鍚堢悊锛岃冭檻涓娆℃у彂閫佽姹 + System.out.println("Wait CMD_GETDSDIFF_RESPONSE msg from targets!"); + LinkedList receiveDiffResponses = new LinkedList<>(); + if (callBackBarrierDiff.tryCall()) { + for (int i = 0; i < dsDiffResponses.size(); i++) { + CallBackDataListener asyncFutureDiff = dsDiffResponses.get(i); + if (asyncFutureDiff.isDone()) { + receiveDiffResponses.addLast(asyncFutureDiff.getCallBackData()); + } + } + } + + System.out.printf("%s:%d ReceiveDiffResponses size = %d !\r\n", listener.getHostName(), listener.getPort(), receiveDiffResponses.size()); + // step6: process data sequence diff response, update local data sequence state + System.out.println("Compute diff elements!"); + ArrayList dataSequenceElements = dsTransferProcess.computeDiffElement(receiveDiffResponses.toArray(new byte[receiveDiffResponses.size()][])); + System.out.println("Update local data sequence!"); + Collections.sort(dataSequenceElements, new DataSequenceComparator()); + returnCode = dsWriter.updateDSInfo(dsInfo, dataSequenceElements.toArray(new DataSequenceElement[dataSequenceElements.size()])); + + // data sequence transfer complete, close all sessions, end process life cycle + System.out.println("Close all sessions"); +// dsTransferProcess.close(); + dSProcessMap.remove(dsInfo.getId()); + } + + + } catch (Exception e) { + e.printStackTrace(); + } + return returnCode; + } + + /** + * 鏍规嵁杩滅缁撶偣鎵句笌杩滅缁撶偣寤虹珛鐨勪細璇 + * @param remoteNode 杩滅缁撶偣 + * @param remoteSessions 鏈湴缁存姢鐨勮繙绔粨鐐逛細璇濊〃 + * @return 涓庤繙绔粨鐐瑰搴旂殑浼氳瘽 + */ + RemoteSession findResponseSession(RemoteNode remoteNode, RemoteSession[] remoteSessions) { + for (RemoteSession remoteSession : remoteSessions) { + if (remoteSession.remoteNode().equals(remoteNode)) { + return remoteSession; + } + } + return null; + } + /** + * + * + */ +// void setDSReader(DataSequenceReader reader) { +// +// } + + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSTransferProcess.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSTransferProcess.java new file mode 100644 index 00000000..45fc89fb --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSTransferProcess.java @@ -0,0 +1,216 @@ +package com.jd.blockchain.statetransfer.process; + +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; +import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; +import com.jd.blockchain.statetransfer.message.DSMsgResolverFactory; +import com.jd.blockchain.statetransfer.message.DataSequenceLoadMessage; +import com.jd.blockchain.statetransfer.result.DSInfoResponseResult; +import com.jd.blockchain.stp.communication.RemoteSession; +import com.jd.blockchain.stp.communication.callback.CallBackBarrier; +import com.jd.blockchain.stp.communication.callback.CallBackDataListener; +import com.jd.blockchain.stp.communication.manager.RemoteSessionManager; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import com.jd.blockchain.utils.IllegalDataException; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Map; + +/** + * 鏁版嵁搴忓垪鐘舵佸鍒惰繃绋 + * @author zhangshuang + * @create 2019/4/11 + * @since 1.0.0 + */ +public class DSTransferProcess { + + private InetSocketAddress[] targets; + private DataSequenceWriter dsWriter; + private DataSequenceReader dsReader; + private DataSequenceInfo dsInfo; + private RemoteSessionManager remoteSessionManager; + private RemoteSession[] remoteSessions; + private String id; + + /** + * @param dsInfo 鏁版嵁搴忓垪褰撳墠鐘舵佷俊鎭 + * @param targets 鐩爣缁撶偣 + */ + public DSTransferProcess(DataSequenceInfo dsInfo, InetSocketAddress[] targets) { + this.dsInfo = dsInfo; + this.targets = targets; + this.id = dsInfo.getId(); + } + + /** + * @param dsWriter 宸紓璇锋眰鑰呮墽琛屾暟鎹簭鍒楁洿鏂扮殑鎵ц鍣 + * @return void + */ + public void setDSWriter(DataSequenceWriter dsWriter) { + this.dsWriter = dsWriter; + } + + /** + * @param dsReader 宸紓鍝嶅簲鑰呮墽琛屾暟鎹簭鍒楄鍙栫殑鎵ц鍣 + * @return void + */ + public void setDSReader(DataSequenceReader dsReader) { + this.dsReader = dsReader; + } + + /** + * @param remoteSessionManager 杩滅浼氳瘽绠$悊鍣 + * @return void + */ + public void setRemoteSessionManager(RemoteSessionManager remoteSessionManager) { + this.remoteSessionManager = remoteSessionManager; + } + + + /** + * + * @return 鏁版嵁搴忓垪鏍囪瘑绗 + */ + public String getId() { + return id; + } + + /** + * @param msgType 鏁版嵁搴忓垪宸紓璇锋眰娑堟伅绫诲瀷 + * @param remoteSession 鐩爣缁撶偣瀵瑰簲鐨勪細璇 + * @param fromHeight 宸紓璧峰楂樺害 + * @param toHeight 宸紓缁撴潫楂樺害 + * @param callBackBarrier 寮傛鍥炶皟 + * @return 寮傛鍥炶皟 + */ + CallBackDataListener send(DataSequenceMsgType msgType, RemoteSession remoteSession, long fromHeight, long toHeight, CallBackBarrier callBackBarrier) { + + byte[] loadMessage = DSMsgResolverFactory.getEncoder(dsWriter, dsReader).encode(msgType, id, fromHeight, toHeight); + + return remoteSession.asyncRequest(new DataSequenceLoadMessage(loadMessage), callBackBarrier); + } + + /** + * 璁$畻鏁版嵁搴忓垪宸紓鍏冪礌鏁扮粍 + * @param diffArray 宸紓鐨勫瓧鑺傛暟缁 + * @return 瀵瑰樊寮傚瓧鑺傛暟缁勭殑瑙g爜缁撴灉 + */ + public ArrayList computeDiffElement(byte[][] diffArray) { + + ArrayList dataSequenceElements = new ArrayList<>(); + + for (int i = 0 ; i < diffArray.length; i++) { + Object object = DSMsgResolverFactory.getDecoder(dsWriter, dsReader).decode(diffArray[i]); + if (object instanceof DataSequenceElement) { + dataSequenceElements.add((DataSequenceElement) object); + } + else { + throw new IllegalDataException("Unknown instance object!"); + } + } + + return dataSequenceElements; + } + + /** + * 鏍规嵁宸紓鎻愪緵鑰呭搷搴旂殑鏁版嵁搴忓垪鐘舵佷俊鎭壘鍒版嫢鏈夋渶澶ф暟鎹簭鍒楅珮搴︾殑杩滅缁撶偣 + * @param receiveResponses 鏁版嵁搴忓垪宸紓璇锋眰鑰呮敹鍒扮殑杩滅缁撶偣鐘舵佺殑鍝嶅簲淇℃伅 + * @return 寰楀埌杩滅鏁版嵁搴忓垪鐨勬渶澶ч珮搴︿互鍙婃嫢鏈夎呯粨鐐 + */ + public DSInfoResponseResult computeDiffInfo(LinkedList receiveResponses) { + long maxHeight = 0; + RemoteNode maxHeightRemoteNode = null; + + System.out.println("ComputeDiffInfo receiveResponses size = "+ receiveResponses.size()); + + try { + for (CallBackDataListener receiveResponse : receiveResponses) { + Object object = DSMsgResolverFactory.getDecoder(dsWriter, dsReader).decode(receiveResponse.getCallBackData()); + if (object instanceof DataSequenceInfo) { + DataSequenceInfo dsInfo = (DataSequenceInfo) object; + long height = dsInfo.getHeight(); + // sava max height and its remote node + if (maxHeight < height) { + maxHeight = height; + maxHeightRemoteNode = receiveResponse.remoteNode(); + } + } + else { + throw new IllegalDataException("Unknown instance object!"); + } + + } + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + + return new DSInfoResponseResult(maxHeight, maxHeightRemoteNode); + } + + /** + * 鑾峰彇鏈鍒惰繃绋嬬淮鎶ょ殑杩滅浼氳瘽琛 + * @param + * @return 杩滅浼氳瘽琛ㄦ暟缁 + */ + public RemoteSession[] getSessions() { + return remoteSessions; + } + + /** + * 鍏抽棴鏈鍒惰繃绋嬬淮鎶ょ殑鎵鏈夎繙绔細璇 + * @return void + */ + public void close() { + for (RemoteSession session : remoteSessions) { + session.closeAll(); + } + } + + /** + * 寤虹珛涓庤繙绔洰鏍囩粨鐐圭殑杩炴帴锛屼骇鐢熸湰鍦扮淮鎶ょ殑杩滅浼氳瘽琛 + * @return void + */ + public void start() { + + RemoteNode[] remoteNodes = new RemoteNode[targets.length]; + + for (int i = 0; i < remoteNodes.length; i++) { + remoteNodes[i] = new RemoteNode(targets[i].getHostName(), targets[i].getPort()); + } + + remoteSessions = remoteSessionManager.newSessions(remoteNodes); + } + + + /** + * 鏁版嵁搴忓垪鐘舵佷紶杈撲娇鐢ㄧ殑娑堟伅绫诲瀷 + * + */ + public enum DataSequenceMsgType { + CMD_DSINFO_REQUEST((byte) 0x1), + CMD_DSINFO_RESPONSE((byte) 0x2), + CMD_GETDSDIFF_REQUEST((byte) 0x3), + CMD_GETDSDIFF_RESPONSE((byte) 0x4), + ; + public final byte CODE; + + private DataSequenceMsgType(byte code) { + this.CODE = code; + } + + public static DataSequenceMsgType valueOf(byte code) { + for (DataSequenceMsgType msgType : DataSequenceMsgType.values()) { + if (msgType.CODE == code) { + return msgType; + } + } + throw new IllegalArgumentException("Unsupported code[" + code + "] of msgType!"); + } + } + + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSDiffRequestResult.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSDiffRequestResult.java new file mode 100644 index 00000000..af62bd6c --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSDiffRequestResult.java @@ -0,0 +1,45 @@ +package com.jd.blockchain.statetransfer.result; + +/** + * 鏁版嵁搴忓垪宸紓鎻愪緵鑰呰В鐮佽姹傝"CMD_GETDSDIFF_REQUEST"娑堟伅鏃跺緱鍒扮殑缁撴灉 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class DSDiffRequestResult { + + String id; + long fromHeight; + long toHeight; + + public DSDiffRequestResult(String id ,long fromHeight, long toHeight) { + this.id = id; + this.fromHeight = fromHeight; + this.toHeight = toHeight; + } + + public String getId() { + return id; + } + + public long getFromHeight() { + return fromHeight; + } + + public long getToHeight() { + return toHeight; + } + + public void setId(String id) { + this.id = id; + } + + public void setFromHeight(long fromHeight) { + this.fromHeight = fromHeight; + } + + public void setToHeight(long toHeight) { + this.toHeight = toHeight; + } + +} diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSInfoResponseResult.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSInfoResponseResult.java new file mode 100644 index 00000000..7f6d48cc --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSInfoResponseResult.java @@ -0,0 +1,37 @@ +package com.jd.blockchain.statetransfer.result; + +import com.jd.blockchain.stp.communication.node.RemoteNode; + +/** + * 鏁版嵁搴忓垪宸紓璇锋眰鑰呰В鐮佹彁渚涜"CMD_DSINFO_RESPONSE"娑堟伅鏃跺緱鍒扮殑缁撴灉 + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class DSInfoResponseResult { + + long maxHeight; + RemoteNode maxHeightRemoteNode; + + public DSInfoResponseResult(long maxHeight, RemoteNode maxHeightRemoteNode) { + this.maxHeight = maxHeight; + this.maxHeightRemoteNode = maxHeightRemoteNode; + } + + public long getMaxHeight() { + return maxHeight; + } + + public RemoteNode getMaxHeightRemoteNode() { + return maxHeightRemoteNode; + } + + public void setMaxHeight(long maxHeight) { + this.maxHeight = maxHeight; + } + + public void setMaxHeightRemoteNode(RemoteNode maxHeightRemoteNode) { + this.maxHeightRemoteNode = maxHeightRemoteNode; + } + +} diff --git a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java b/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java new file mode 100644 index 00000000..5741262e --- /dev/null +++ b/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java @@ -0,0 +1,155 @@ +package test.com.jd.blockchain.statetransfer; + +import com.jd.blockchain.statetransfer.DataSequence; +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; +import com.jd.blockchain.statetransfer.callback.DataSequenceReaderImpl; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriterImpl; +import com.jd.blockchain.statetransfer.process.DSProcessManager; +import com.jd.blockchain.utils.codec.Base58Utils; +import org.junit.Before; +import org.junit.Test; + +import java.net.InetSocketAddress; +import java.util.LinkedList; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * @author zhangshuang + * @create 2019/4/18 + * @since 1.0.0 + */ +public class StateTransferLayerTest { + + private final int[] listenPorts = new int[]{9000, 9010, 9020, 9030}; + + private String localIp = "127.0.0.1"; + + private int DataSequenceNum = 1; + + private int nodesNum = 4; + + private byte[] idBytes = new byte[20]; + + private Random rand = new Random(); + + private String[] dataSequenceIds = new String[DataSequenceNum]; + + private InetSocketAddress[] remoteNodeIps = new InetSocketAddress[nodesNum]; + + private final ExecutorService threadPool = Executors.newFixedThreadPool(8); + + private static LinkedList dataSequencesPerNode = new LinkedList<>(); + + // 鍋囧畾姣忎釜鏁版嵁搴忓垪鍏冪礌閲屾湁鍥涙潯璁板綍鏁版嵁 + private byte[][] dsElementDatas = new byte[4][]; + + + @Before + public void init() { + + // 浜х敓涓や釜鍞竴鐨勬暟鎹簭鍒桰d鏍囪瘑 + for (int i = 0; i < DataSequenceNum; i++) { + + dataSequenceIds[i] = new String(); + rand.nextBytes(idBytes); + dataSequenceIds[i] = Base58Utils.encode(idBytes); + } + + // 鍑嗗濂芥墍鏈夌殑杩滅缁撶偣锛屽寘鎷洃鍚 + for (int i = 0; i < nodesNum; i++) { + remoteNodeIps[i] = new InetSocketAddress(localIp, listenPorts[i]); + } + + // 涓烘暟鎹簭鍒楃殑姣忎釜楂樺害鍑嗗濂藉唴瀹癸紝涓轰簡鏂逛究娴嬭瘯锛屾瘡涓珮搴︾殑鍐呭璁剧疆涓轰竴鑷 + for (int i = 0; i < dsElementDatas.length; i++) { + rand.nextBytes(idBytes); + dsElementDatas[i] = idBytes; + } + + // 涓虹粨鐐瑰噯澶囨暟鎹簭鍒 + for (String id : dataSequenceIds) { + for (int i = 0; i < remoteNodeIps.length; i++) { + DataSequence dataSequence = new DataSequence(remoteNodeIps[i], id); + + // 涓烘暟鎹簭鍒楃殑0锛1锛2楂樺害娣诲姞鍐呭 + for (int j = 0; j < 3; j++) { + dataSequence.addElement(new DataSequenceElement(id, j, dsElementDatas)); + } + dataSequencesPerNode.addLast(dataSequence); + } + + // 鎶婂叾涓竴涓粨鐐圭殑鏁版嵁搴忓垪涓庡叾浠栫粨鐐瑰尯鍒紑鏉 + for (int i = 0; i < dataSequencesPerNode.size(); i++) { + DataSequence dataSequence = dataSequencesPerNode.get(i); + if (dataSequence.getAddress().getPort() != listenPorts[0]) { + // 涓烘暟鎹簭鍒楃殑3,4楂樺害娣诲姞鍐呭 + for (int j = 3; j < 5; j++) { + dataSequence.addElement(new DataSequenceElement(id, j, dsElementDatas)); + } + } + } + } + } + + InetSocketAddress[] getTargetNodesIp(InetSocketAddress listenIp, InetSocketAddress[] remoteNodeIps) { + + // 鑾峰緱闄ょ洃鍚粨鐐逛箣澶栫殑鍏朵粬杩滅缁撶偣 + InetSocketAddress[] targets = new InetSocketAddress[remoteNodeIps.length - 1]; + int j = 0; + + for (int i = 0; i < remoteNodeIps.length; i++) { + if ((remoteNodeIps[i].getHostName().equals(listenIp.getHostName())) && (remoteNodeIps[i].getPort() == listenIp.getPort())) { + continue; + } + targets[j++] = new InetSocketAddress(remoteNodeIps[i].getHostName(), remoteNodeIps[i].getPort()); + } + + return targets; + + } + + + DataSequence findDataSequence(String id, InetSocketAddress listenNodeAddr) { + for (DataSequence dataSequence : dataSequencesPerNode) { + if ((dataSequence.getAddress().getPort() == listenNodeAddr.getPort() && (dataSequence.getAddress().getHostName().equals(listenNodeAddr.getHostName())) + && (dataSequence.getId().equals(id)))) { + return dataSequence; + } + } + return null; + } + + + @Test + public void test() { + + CountDownLatch countDownLatch = new CountDownLatch(nodesNum); + + for (String id : dataSequenceIds) { + for (int i = 0; i < nodesNum; i++) { + InetSocketAddress listenNode = remoteNodeIps[i]; + threadPool.execute(() -> { + // 鍒涘缓鏁版嵁搴忓垪澶勭悊绠$悊鑰呭疄渚 + DSProcessManager dsProcessManager = new DSProcessManager(); + DataSequence currDataSequence = findDataSequence(id, listenNode); + DataSequenceInfo dsInfo = currDataSequence.getDSInfo(); + InetSocketAddress[] targets = getTargetNodesIp(listenNode, remoteNodeIps); + dsProcessManager.startDSProcess(dsInfo, listenNode, targets, new DataSequenceWriterImpl(currDataSequence), new DataSequenceReaderImpl(currDataSequence)); + countDownLatch.countDown(); + }); + } + } + + // 绛夊緟鏁版嵁搴忓垪鏇存柊瀹屾垚 + try { + Thread.sleep(60000); + countDownLatch.await(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/source/stp/pom.xml b/source/stp/pom.xml new file mode 100644 index 00000000..fd7fc35e --- /dev/null +++ b/source/stp/pom.xml @@ -0,0 +1,21 @@ + + + + + jdchain-root + com.jd.blockchain + 0.9.0-SNAPSHOT + + 4.0.0 + + stp + pom + + stp-communication + + + + UTF-8 + + diff --git a/source/stp/stp-communication/pom.xml b/source/stp/stp-communication/pom.xml new file mode 100644 index 00000000..96798377 --- /dev/null +++ b/source/stp/stp-communication/pom.xml @@ -0,0 +1,50 @@ + + + + + stp + com.jd.blockchain + 0.9.0-SNAPSHOT + + 4.0.0 + + stp-communication + + stp-communication + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + test + + + + commons-codec + commons-codec + + + + com.alibaba + fastjson + + + + io.netty + netty-all + 4.1.29.Final + + + + com.google.guava + guava + + + diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/MessageExecutor.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/MessageExecutor.java new file mode 100644 index 00000000..dba7e0d0 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/MessageExecutor.java @@ -0,0 +1,56 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.MessageExecutor + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓婂崍10:59 + * Description: + */ +package com.jd.blockchain.stp.communication; + +/** + * 娑堟伅鎵ц鍣 + * 璇ユ墽琛屽櫒鐢卞叾浠栧簲鐢ㄥ疄鐜 + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + * @date 2019-04-18 15:29 + */ + +public interface MessageExecutor { + + /** + * 鎺ユ敹鍒皉eceive娑堟伅濡備綍澶勭悊 + * + * @param key + * 璇锋眰娑堟伅鐨凨ey锛岃皟鐢ㄨ呴渶瑕佸湪搴旂瓟鏃堕氳繃璇ey搴旂瓟杩滅 + * @param data + * 璇锋眰娑堟伅鐨勫唴瀹 + * @param session + * 杩滅Session锛屾弿杩拌娑堟伅鏄粠鍝彂閫佹潵鐨 + * @return + * 搴旂瓟缁撴灉 + */ + byte[] receive(String key, byte[] data, RemoteSession session); + + /** + * 搴旂瓟鏂瑰紡 + * + * @return + * 鍙傝冿細{@link REPLY} + */ + REPLY replyType(); + + // 搴旂瓟鏂瑰紡 + enum REPLY { + // 鎵嬪姩搴旂瓟锛歊eceiver涓嶄細鑷姩鍙戦佸簲绛旇姹傦紝闇瑕佽皟鐢 + // session.reply(String key, LoadMessage loadMessage) 鎴 + // asyncReply(String key, LoadMessage loadMessage) + MANUAL, + + // 鑷姩搴旂瓟锛歊eceiver浼氭牴鎹畆eceive鏂规硶鐨勫簲绛旂粨鏋滆嚜鍔ㄨ皟鐢ㄥ簲绛 + // 浣跨敤鑰呬笉鑳介噸鏂拌皟鐢 + AUTO, + ; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/RemoteSession.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/RemoteSession.java new file mode 100644 index 00000000..0ce9fceb --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/RemoteSession.java @@ -0,0 +1,206 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.RemoteSession + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓婂崍11:15 + * Description: + */ +package com.jd.blockchain.stp.communication; + +import com.jd.blockchain.stp.communication.callback.CallBackBarrier; +import com.jd.blockchain.stp.communication.callback.CallBackDataListener; +import com.jd.blockchain.stp.communication.connection.Connection; +import com.jd.blockchain.stp.communication.message.LoadMessage; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import org.apache.commons.codec.binary.Hex; + +import java.util.concurrent.TimeUnit; + + +/** + * 杩滅Session + * + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + */ + +public class RemoteSession { + + /** + * 鏈湴鑺傜偣ID + */ + private String localId; + + /** + * 杩滅鑺傜偣 + */ + private RemoteNode remoteNode; + + /** + * 杩滅杩炴帴 + */ + private Connection connection; + + /** + * 瀵瑰簲杩滅鑺傜偣娑堟伅鐨勫鐞嗗櫒 + * 璇ュ鐞嗗櫒鑻ヤ负NULL锛屽垯浣跨敤褰撳墠鑺傜偣榛樿澶勭悊鍣 + */ + private MessageExecutor messageExecutor; + + /** + * 鏋勯犲櫒 + * @param localId + * 鏈湴鑺傜偣ID + * @param connection + * 瀵瑰簲杩炴帴 + */ + public RemoteSession(String localId, Connection connection) { + this(localId, connection, null); + } + + /** + * 鏋勯犲櫒 + * @param localId + * 鏈湴鑺傜偣ID + * @param connection + * 瀵瑰簲杩炴帴 + * @param messageExecutor + * 瀵瑰簲杩滅娑堟伅澶勭悊鍣 + */ + public RemoteSession(String localId, Connection connection, MessageExecutor messageExecutor) { + this.localId = localId; + this.connection = connection; + this.messageExecutor = messageExecutor; + this.remoteNode = connection.remoteNode(); + } + + public void init() { + connection.initSession(this); + } + + public void initExecutor(MessageExecutor messageExecutor) { + this.messageExecutor = messageExecutor; + } + + /** + * 鍚屾璇锋眰 + * 璇ヨ姹備細闃诲鍘熺嚎绋 + * + * @param loadMessage + * 瑕佽姹傜殑璐熻浇娑堟伅 + * @return + * 搴旂瓟锛岀洿鍒版湁娑堟伅搴旂瓟鎴栧嚭鐜板紓甯 + * @throws Exception + */ + public byte[] request(LoadMessage loadMessage) throws Exception { + return this.connection.request(this.localId, loadMessage, null).getCallBackData(); + } + + /** + * 鍚屾璇锋眰 + * 璇ヨ姹備細闃诲鍘熺嚎绋 + * + * @param loadMessage + * 瑕佽姹傜殑璐熻浇娑堟伅 + * @param time + * 璇锋眰鐨勬渶闀跨瓑寰呮椂闂 + * @param timeUnit + * 璇锋眰鐨勬渶闀跨瓑寰呭崟浣 + * @return + * 搴旂瓟锛岀洿鍒版湁娑堟伅鎴栨椂闂存埅姝㈡垨鍑虹幇寮傚父 + * @throws Exception + */ + public byte[] request(LoadMessage loadMessage, long time, TimeUnit timeUnit) throws Exception { + return this.connection.request(this.localId, loadMessage, null).getCallBackData(time, timeUnit); + } + + /** + * 寮傛璇锋眰 + * 涓嶄細闃诲璋冪敤绾跨▼ + * + * @param loadMessage + * 瑕佸彂閫佺殑璐熻浇娑堟伅 + * @return + * 搴旂瓟锛岄渶瑕佽皟鐢ㄨ呬粠Listener涓幏鍙栫粨鏋 + */ + public CallBackDataListener asyncRequest(LoadMessage loadMessage) { + return asyncRequest(loadMessage, null); + } + + /** + * 寮傛璇锋眰 + * 涓嶄細闃诲璋冪敤绾跨▼ + * + * @param loadMessage + * 瑕佽姹傜殑璐熻浇娑堟伅 + * @param callBackBarrier + * 鍥炶皟鏍呮爮锛堢敤浜庡涓姹傛椂杩涜缁熶竴闃绘嫤锛 + * @return + * 搴旂瓟锛岄渶瑕佽皟鐢ㄨ呬粠Listener涓幏鍙栫粨鏋 + */ + public CallBackDataListener asyncRequest(LoadMessage loadMessage, CallBackBarrier callBackBarrier) { + return this.connection.request(this.localId, loadMessage, callBackBarrier); + } + + /** + * 搴旂瓟 + * + * @param key + * 璇锋眰娑堟伅鐨凨ey + * @param loadMessage + * 闇瑕佸簲绛旂殑璐熻浇娑堟伅 + */ + public void reply(String key, LoadMessage loadMessage) { + this.connection.reply(this.localId, key, loadMessage); + } + + public void closeAll() { + this.connection.closeAll(); + } + + public void closeReceiver() { + this.connection.closeReceiver(); + } + + public void closeSender() { + this.connection.closeSender(); + } + + /** + * 杩斿洖鏈湴鑺傜偣ID + * + * @return + */ + public String localId() { + return localId; + } + + /** + * 杩斿洖杩滅瀵瑰簲鐨凷essionID + * + * @return + */ + public String remoteSessionId() { + return Hex.encodeHexString(remoteNode.toString().getBytes()); + } + + /** + * 杩斿洖杩滅瀵瑰簲鎵ц鍣 + * + * @return + */ + public MessageExecutor messageExecutor() { + return this.messageExecutor; + } + + /** + * 杩斿洖瀵瑰簲杩滅鑺傜偣 + * + * @return + */ + public RemoteNode remoteNode() { + return remoteNode; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackBarrier.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackBarrier.java new file mode 100644 index 00000000..41da6b66 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackBarrier.java @@ -0,0 +1,74 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.CallBackBarrier + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/12 涓婂崍10:22 + * Description: + */ +package com.jd.blockchain.stp.communication.callback; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * 鍥炶皟鏍呮爮 + * 鐢ㄤ簬瀵规壒閲忚姹傜殑搴旂瓟鍥炶皟澶勭悊 + * @author shaozhuguang + * @create 2019/4/12 + * @since 1.0.0 + */ + +public class CallBackBarrier { + + private CountDownLatch countDownLatch; + + /** + * 榛樿鏈澶у皾璇曡皟鐢ㄦ椂闂达紙鍗曚綅锛氭绉掞級 + */ + private long maxTryCallMillSeconds = 2000; + + + /** + * 闈欐佹瀯閫犲櫒 + * @param barrierLength + * 璇锋眰鐨勮繙绔暟閲 + * @return + */ + public static final CallBackBarrier newCallBackBarrier(int barrierLength) { + return new CallBackBarrier(barrierLength); + } + + /** + * 闈欐佹瀯閫犲櫒 + * @param barrierLength + * 璇锋眰鐨勮繙绔暟閲 + * @param maxTryCallMillSeconds + * 鏈澶у皾璇曠殑鏃堕棿锛屽崟浣嶏細姣 + * @return + */ + public static final CallBackBarrier newCallBackBarrier(int barrierLength, long maxTryCallMillSeconds) { + return new CallBackBarrier(barrierLength, maxTryCallMillSeconds); + } + + private CallBackBarrier(int barrierLength) { + this.countDownLatch = new CountDownLatch(barrierLength); + } + + private CallBackBarrier(int barrierLength, long maxTryCallMillSeconds) { + this.countDownLatch = new CountDownLatch(barrierLength); + this.maxTryCallMillSeconds = maxTryCallMillSeconds; + } + + public void release() { + countDownLatch.countDown(); + } + + public boolean tryCall() throws InterruptedException { + return countDownLatch.await(maxTryCallMillSeconds, TimeUnit.MILLISECONDS); + } + + public boolean tryCall(long timeout, TimeUnit unit) throws InterruptedException { + return countDownLatch.await(timeout, unit); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackDataListener.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackDataListener.java new file mode 100644 index 00000000..9de7aa32 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackDataListener.java @@ -0,0 +1,113 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.callback.CallBackDataListener + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/15 涓嬪崍4:40 + * Description: + */ +package com.jd.blockchain.stp.communication.callback; + +import com.jd.blockchain.stp.communication.node.RemoteNode; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 鏁版嵁鍥炶皟鐩戝惉鍣 + * @author shaozhuguang + * @create 2019/4/15 + * @since 1.0.0 + */ + +public class CallBackDataListener { + + /** + * Future + */ + private CompletableFuture future = new CompletableFuture<>(); + + /** + * 杩滅鑺傜偣 + */ + private RemoteNode remoteNode; + + private boolean isFill = false; + + private Lock lock = new ReentrantLock(); + + + /** + * 鏋勯犲櫒 + * @param remoteNode + * 杩滅鑺傜偣淇℃伅 + */ + public CallBackDataListener(RemoteNode remoteNode) { + this.remoteNode = remoteNode; + } + + /** + * 鑾峰彇杩斿洖鐨勬暟鎹 + * 璋冪敤璇ユ柟娉曚細闃诲褰撳墠绾跨▼锛岀洿鍒版湁鏁版嵁杩斿洖鎴栧嚭鐜板紓甯 + * @return + * 搴旂瓟缁撴灉 + * @throws InterruptedException + * @throws ExecutionException + */ + public byte[] getCallBackData() throws InterruptedException, ExecutionException { + return future.get(); + } + + /** + * 鎸囧畾鏃堕棿鍐呰幏鍙栬繑鍥炵殑鏁版嵁 + * 璋冪敤璇ユ柟娉曚細闃诲褰撳墠绾跨▼锛岀洿鍒版椂闂村埌杈炬垨鏈夋暟鎹繑鍥炴垨鍑虹幇寮傚父 + * @param time + * 瓒呮椂鏃堕棿 + * @param timeUnit + * 瓒呮椂鍗曚綅 + * @return + * 搴旂瓟缁撴灉锛岃嫢鎸囧畾鏃堕棿鍐呮病鏈夋暟鎹紝鍒欒繑鍥瀗ull + * @throws InterruptedException + * @throws ExecutionException + * @throws TimeoutException + */ + public byte[] getCallBackData(long time, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException { + return future.get(time, timeUnit); + } + + /** + * 璁剧疆杩斿洖鐨勬暟鎹 + * @param data + */ + public void setCallBackData(byte[] data) { + // 闃叉鏁版嵁澶氭璁剧疆 + if (!isFill) { + try { + lock.lock(); + // Double Check + if (!isFill) { + future.complete(data); + isFill = true; + } + } finally { + lock.unlock(); + } + } + } + + public RemoteNode remoteNode() { + return this.remoteNode; + } + + /** + * 鍒ゆ柇鏄惁寮傛鎿嶄綔瀹屾垚 + * @return + */ + public boolean isDone() { + return future.isDone(); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackLauncher.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackLauncher.java new file mode 100644 index 00000000..e1f9473a --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackLauncher.java @@ -0,0 +1,80 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.callback.CallBackLauncher + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/17 涓嬪崍6:27 + * Description: + */ +package com.jd.blockchain.stp.communication.callback; + +import java.util.concurrent.Semaphore; + +/** + * 鍚姩鍣ㄥ洖璋 + * @author shaozhuguang + * @create 2019/4/17 + * @since 1.0.0 + * @date 2019-04-19 09:53 + */ + +public class CallBackLauncher { + + /** + * 鏄惁鍚姩鎴愬姛 + */ + private boolean isBootSuccess = false; + + /** + * 淇″彿閲 + */ + private Semaphore isBooted = new Semaphore(0, true); + + /** + * 寮傚父 + */ + private Exception exception; + + /** + * 鏍囪瘑褰撳墠鍚姩鎴愬姛 + */ + public void bootSuccess() { + isBootSuccess = true; + release(); + } + + /** + * 鏍囪瘑褰撳墠鍚姩澶辫触 + * @param e + * 瀵艰嚧澶辫触鐨勫紓甯镐俊鎭 + */ + public void bootFail(Exception e) { + this.exception = e; + isBootSuccess = false; + release(); + } + + /** + * 绛夊緟鍚姩瀹屾垚 + * 璋冪敤璇ユ柟娉曚細闃诲褰撳墠绾跨▼锛岀煡閬撳惎鍔ㄥ畬鎴愭垨鍙戠敓寮傚父 + * @return + * 褰撳墠瀵硅薄 + * @throws InterruptedException + */ + public CallBackLauncher waitingBooted() throws InterruptedException { + this.isBooted.acquire(); + return this; + } + + public boolean isBootSuccess() { + return isBootSuccess; + } + + public Exception exception() { + return exception; + } + + private void release() { + this.isBooted.release(); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AbstractAsyncExecutor.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AbstractAsyncExecutor.java new file mode 100644 index 00000000..fc99cb05 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AbstractAsyncExecutor.java @@ -0,0 +1,71 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.AbstractAsyncExecutor + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/17 涓婂崍11:16 + * Description: + */ +package com.jd.blockchain.stp.communication.connection; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.jd.blockchain.stp.communication.callback.CallBackLauncher; + +import java.util.concurrent.*; + +/** + * 鎶借薄寮傛鎵ц鍣 + * @author shaozhuguang + * @create 2019/4/17 + * @since 1.0.0 + */ + +public abstract class AbstractAsyncExecutor implements AsyncExecutor{ + + /** + * 绾跨▼姹犲彲澶勭悊闃熷垪鐨勫閲 + */ + private static final int QUEUE_CAPACITY = 1024; + + /** + * 鍥炶皟鎵ц鍣 + */ + protected final CallBackLauncher callBackLauncher = new CallBackLauncher(); + + /** + * 榛樿鎻愪緵鐨勫垵濮嬪寲娲昏穬绾跨▼璋冨害鍣 + * @return + */ + @Override + public ThreadPoolExecutor initRunThread() { + ThreadFactory timerFactory = new ThreadFactoryBuilder() + .setNameFormat(threadNameFormat()).build(); + + ThreadPoolExecutor runThread = new ThreadPoolExecutor(1, 1, + 60, TimeUnit.SECONDS, + new LinkedBlockingQueue<>(QUEUE_CAPACITY), + timerFactory, + new ThreadPoolExecutor.AbortPolicy()); + + return runThread; + } + + /** + * 鍚姩瀹屾垚鍚庡洖璋 + * 璇ヨ皟鐢ㄤ細闃诲褰撳墠绾跨▼锛岀洿鍒板惎鍔ㄥ畬鎴愶紝鏃犺鏄垚鍔熸垨澶辫触 + * @return + * 鍥炶皟鎵ц鍣 + * 鎴愬姛鎴栧け璐ヤ細鍦ㄥ洖璋冩墽琛屽櫒涓湁鎵浣撶幇 + * @throws InterruptedException + */ + @Override + public CallBackLauncher waitBooted() throws InterruptedException { + return callBackLauncher.waitingBooted(); + } + + /** + * 绾跨▼姹犱腑鐨勭嚎绋嬪懡鍚嶆牸寮 + * @return + */ + public abstract String threadNameFormat(); +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AsyncExecutor.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AsyncExecutor.java new file mode 100644 index 00000000..5bfdd682 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AsyncExecutor.java @@ -0,0 +1,36 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.AsyncExecutor + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/17 涓婂崍11:14 + * Description: + */ +package com.jd.blockchain.stp.communication.connection; + +import com.jd.blockchain.stp.communication.callback.CallBackLauncher; + +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 寮傛鎵ц鍣ㄦ帴鍙 + * @author shaozhuguang + * @create 2019/4/17 + * @since 1.0.0 + */ + +public interface AsyncExecutor { + + /** + * 鍒濆鍖栬繍琛岀嚎绋 + * @return + */ + ThreadPoolExecutor initRunThread(); + + /** + * 鍚姩瀹屾垚鍚庤繑鍥炶皟搴︽墽琛屽櫒 + * @return + * @throws InterruptedException + */ + CallBackLauncher waitBooted() throws InterruptedException; +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Connection.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Connection.java new file mode 100644 index 00000000..5d534686 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Connection.java @@ -0,0 +1,220 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.Connection + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓嬪崍5:39 + * Description: + */ +package com.jd.blockchain.stp.communication.connection; + +import com.jd.blockchain.stp.communication.RemoteSession; +import com.jd.blockchain.stp.communication.callback.CallBackBarrier; +import com.jd.blockchain.stp.communication.callback.CallBackDataListener; +import com.jd.blockchain.stp.communication.callback.CallBackLauncher; +import com.jd.blockchain.stp.communication.connection.listener.ReplyListener; +import com.jd.blockchain.stp.communication.message.LoadMessage; +import com.jd.blockchain.stp.communication.message.SessionMessage; +import com.jd.blockchain.stp.communication.message.TransferMessage; +import com.jd.blockchain.stp.communication.node.LocalNode; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; + +import java.util.Random; + +/** + * 缁熶竴杩炴帴瀵硅薄 + * 璇ュ璞′腑鏈変袱涓璞eceiver鍜孲ender + * Receiver涓哄鐢ㄥ璞★紙姣忎釜绔彛鐩戝惉浜х敓鐨凴eceiver鍙湁涓涓級 + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + * @date 2019-04-18 14:49 + */ +public class Connection { + + /** + * 杩滅鑺傜偣 + */ + private RemoteNode remoteNode; + + /** + * 鎺ユ敹鍣 + */ + private Receiver receiver; + + /** + * 鍙戦佸櫒 + */ + private Sender sender; + + /** + * 鏋勯犲櫒 + * + * @param receiver + */ + public Connection(Receiver receiver) { + this.receiver = receiver; + } + + /** + * 鍒濆鍖朢emoteSession + * + * @param remoteSession + */ + public void initSession(RemoteSession remoteSession) { + this.receiver.initRemoteSession(remoteSession.remoteSessionId(), remoteSession); + } + + /** + * 杩炴帴杩滅 + * + * @param remoteNode + * 杩滅鑺傜偣 + * @param messageExecutorClass + * 甯屾湜杩滅鑺傜偣澶勭悊鏈湴鑺傜偣娑堟伅鏃剁殑娑堟伅澶勭悊鍣 + * @return + * 鍥炶皟鎵ц鍣 + * @throws InterruptedException + */ + public CallBackLauncher connect(RemoteNode remoteNode, String messageExecutorClass) throws InterruptedException { + this.remoteNode = remoteNode; + this.sender = new Sender(this.receiver.localNode(), this.remoteNode, sessionMessage(messageExecutorClass)); + this.sender.connect(); + return this.sender.waitBooted(); + } + + /** + * 鍙戦佽姹 + * + * 澶勭悊杩囩▼绠杩板涓嬶細 + * 1銆佺敓鎴愬簳灞傛秷鎭紙TransferMessage锛夛紝鍏朵腑娑堟伅绫诲瀷涓鸿姹傦紝鐢ㄤ簬鎻忚堪鏈鍙戦佺殑娑堟伅鏄敤浜庤姹傚簲绛旓紱 + * 2銆佹牴鎹秷鎭殑鍞竴Key锛岀敓鎴恖istenKey锛屽苟鐢熸垚搴旂瓟鐩戝惉鍣 + * 3銆佸皢搴旂瓟鐩戝惉鍣ㄦ坊鍔犲埌Receiver涓紙Receiver涓槸浠ap瀛樺偍锛 + * 4銆佽皟鐢⊿ender鍙戦佹秷鎭嚦瀵圭鑺傜偣 + * 5銆佽繑鍥炲簲绛旂洃鍚櫒鐨勫洖璋冩暟鎹洃鍚璞 + * + * @param sessionId + * 褰撳墠SessionId + * @param loadMessage + * 杞戒綋娑堟伅 + * @param callBackBarrier + * 鍥炶皟鏍呮爮 + * @return + */ + public CallBackDataListener request(String sessionId, LoadMessage loadMessage, CallBackBarrier callBackBarrier) { + + TransferMessage transferMessage = transferMessage(sessionId, null, loadMessage, TransferMessage.MESSAGE_TYPE.TYPE_REQUEST); + + // 鐩戝惉鍣ㄧ殑Key + String listenKey = transferMessage.toListenKey(); + + // 鍒涘缓鐩戝惉鍣 + ReplyListener replyListener = new ReplyListener(listenKey, this.remoteNode, callBackBarrier); + + // 娣诲姞鐩戝惉鍣ㄨ嚦Receiver + this.receiver.addListener(replyListener); + + // 鍙戦佽姹 + this.sender.send(transferMessage); + + return replyListener.callBackDataListener(); + } + + /** + * 鍙戦佸簲绛 + * + * @param sessionId + * 褰撳墠SessionID + * @param key + * 璇锋眰娑堟伅鐨凨ey锛岀敤浜庢弿杩板搴旂殑璇锋眰 + * @param loadMessage + * 搴旂瓟鐨勮浇浣撴秷鎭 + */ + public void reply(String sessionId, String key, LoadMessage loadMessage) { + TransferMessage transferMessage = transferMessage(sessionId, key, loadMessage, TransferMessage.MESSAGE_TYPE.TYPE_RESPONSE); + + // 閫氳繃Sender鍙戦佹暟鎹 + this.sender.send(transferMessage); + } + + /** + * 鐢熸垚杞戒綋娑堟伅鐨凨ey + * + * @param loadMessage + * @return + */ + private String loadKey(LoadMessage loadMessage) { + // key姣忔涓嶈兘涓鑷达紝鍥犳澧炲姞闅忔満鏁 + byte[] randomBytes = new byte[8]; + new Random().nextBytes(randomBytes); + byte[] loadBytes = loadMessage.toBytes(); + byte[] keyBytes = new byte[loadBytes.length + randomBytes.length]; + System.arraycopy(randomBytes, 0, keyBytes, 0, randomBytes.length); + System.arraycopy(loadBytes, 0, keyBytes, randomBytes.length, loadBytes.length); + // 浣跨敤Sha256姹侶ash + byte[] sha256Bytes = DigestUtils.sha256(keyBytes); + // 浣跨敤base64浣滀负Key + return Base64.encodeBase64String(sha256Bytes); + } + + /** + * 鐢熸垚TransferMessage + * + * @param sessionId + * 鑺傜偣ID + * @param key + * 娑堟伅Key + * @param loadMessage + * 杞戒綋娑堟伅 + * @param messageType + * 娑堟伅绫诲瀷 + * @return + */ + private TransferMessage transferMessage(String sessionId, String key, LoadMessage loadMessage, TransferMessage.MESSAGE_TYPE messageType) { + + if (key == null || key.length() == 0) { + key = loadKey(loadMessage); + } + + TransferMessage transferMessage = new TransferMessage( + sessionId, messageType.code(), key, loadMessage.toBytes()); + + return transferMessage; + } + + /** + * 鐢熸垚SessionMessage + * + * @param messageExecutorClass + * + * @return + */ + private SessionMessage sessionMessage(String messageExecutorClass) { + + LocalNode localNode = this.receiver.localNode(); + + SessionMessage sessionMessage = new SessionMessage( + localNode.getHostName(), localNode.getPort(), messageExecutorClass); + + return sessionMessage; + } + + public void closeAll() { + closeReceiver(); + closeSender(); + } + + public RemoteNode remoteNode() { + return remoteNode; + } + + public void closeReceiver() { + this.receiver.close(); + } + + public void closeSender() { + this.sender.close(); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Receiver.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Receiver.java new file mode 100644 index 00000000..fdbb0df6 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Receiver.java @@ -0,0 +1,161 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.inner.Receiver + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓婂崍10:59 + * Description: + */ +package com.jd.blockchain.stp.communication.connection; + +import com.jd.blockchain.stp.communication.RemoteSession; +import com.jd.blockchain.stp.communication.connection.handler.HeartBeatReceiverHandler; +import com.jd.blockchain.stp.communication.connection.handler.HeartBeatReceiverTrigger; +import com.jd.blockchain.stp.communication.connection.handler.ReceiverHandler; +import com.jd.blockchain.stp.communication.connection.listener.ReplyListener; +import com.jd.blockchain.stp.communication.manager.ConnectionManager; +import com.jd.blockchain.stp.communication.node.LocalNode; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.timeout.IdleStateHandler; + +import java.io.Closeable; +import java.net.InetSocketAddress; +import java.util.concurrent.*; + +/** + * 鎺ユ敹鍣 + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + */ + +public class Receiver extends AbstractAsyncExecutor implements Closeable { + + /** + * Netty涓殑BOSS绾跨▼ + */ + private final EventLoopGroup bossGroup = new NioEventLoopGroup(); + + /** + * Netty涓殑Worker绾跨▼ + */ + private final EventLoopGroup workerGroup = new NioEventLoopGroup(); + + /** + * 鏈湴鑺傜偣 + */ + private LocalNode localNode; + + /** + * 娑堟伅鎺ユ敹Handler + */ + private ReceiverHandler receiverHandler; + + public Receiver(LocalNode localNode) { + this.localNode = localNode; + } + + /** + * 鍚姩鐩戝惉 + */ + public void startListen() { + ServerBootstrap bootstrap = new ServerBootstrap(); + + bootstrap.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG, 1024) + .childOption(ChannelOption.SO_KEEPALIVE, true) + .localAddress(new InetSocketAddress(this.localNode.getPort())) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + socketChannel.pipeline() +// .addLast(new LoggingHandler(LogLevel.ERROR)) + .addLast(new IdleStateHandler(8, 0, 0, TimeUnit.SECONDS)) + .addLast(new LineBasedFrameDecoder(1024)) + .addLast(new StringDecoder()) + .addLast(new HeartBeatReceiverTrigger()) + .addLast(new HeartBeatReceiverHandler()) + .addLast(receiverHandler); + } + }); + + // 鐢卞崟鐙殑绾跨▼鍚姩锛岄槻姝㈠閮ㄨ皟鐢ㄧ嚎绋嬮樆濉 + ThreadPoolExecutor runThread = initRunThread(); + runThread.execute(() -> { + try { + ChannelFuture f = bootstrap.bind().sync(); + boolean isStartSuccess = f.isSuccess(); + if (isStartSuccess) { + super.callBackLauncher.bootSuccess(); + // 鍚姩鎴愬姛 + f.channel().closeFuture().sync(); + } else { + // 鍚姩澶辫触 + throw new Exception("Receiver start fail :" + f.cause().getMessage() + " !!!"); + } + } catch (Exception e) { + super.callBackLauncher.bootFail(e); + } finally { + close(); + } + }); + } + + @Override + public String threadNameFormat() { + return "receiver-pool-%d"; + } + + /** + * 鍒濆鍖朢eceiverHandler + * + * @param connectionManager + * 杩炴帴绠$悊鍣 + * @param messageExecutorClass + * 褰撳墠鑺傜偣鐨勬秷鎭鐞咰lass + */ + public void initReceiverHandler(ConnectionManager connectionManager, String messageExecutorClass) { + receiverHandler = new ReceiverHandler(connectionManager, messageExecutorClass, this.localNode); + } + + /** + * 鍒濆鍖栬繙绔疭ession + * + * @param sessionId + * + * @param remoteSession + */ + public void initRemoteSession(String sessionId, RemoteSession remoteSession) { + receiverHandler.putRemoteSession(sessionId, remoteSession); + } + + /** + * 娣诲姞鐩戝惉鍣 + * + * @param replyListener + */ + public void addListener(ReplyListener replyListener) { + receiverHandler.addListener(replyListener); + } + + @Override + public void close() { + receiverHandler.close(); + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + + public LocalNode localNode() { + return this.localNode; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Sender.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Sender.java new file mode 100644 index 00000000..7c17f18f --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Sender.java @@ -0,0 +1,207 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.inner.Sender + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓婂崍10:58 + * Description: + */ +package com.jd.blockchain.stp.communication.connection; + +import com.jd.blockchain.stp.communication.connection.handler.*; +import com.jd.blockchain.stp.communication.message.IMessage; +import com.jd.blockchain.stp.communication.message.SessionMessage; +import com.jd.blockchain.stp.communication.node.LocalNode; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.timeout.IdleStateHandler; + +import java.io.Closeable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; + +/** + * 鍙戦佸櫒 + * + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + * @date 2019-04-18 15:08 + */ +public class Sender extends AbstractAsyncExecutor implements Closeable { + + private final EventLoopGroup loopGroup = new NioEventLoopGroup(); + + private Bootstrap bootstrap; + + private ChannelFuture channelFuture; + + /** + * 褰撳墠鑺傜偣鐨凷essionMessage + */ + private SessionMessage sessionMessage; + + private LocalNode localNode; + + private RemoteNode remoteNode; + +// /** +// * 杩滅HOST +// */ +// private String remoteHost; +// +// /** +// * 杩滅绔彛 +// */ +// private int remotePort; + + /** + * 鐩戝惉Handler锛堥噸杩濰andler锛 + */ + private WatchDogHandler watchDogHandler; + + public Sender(LocalNode localNode, RemoteNode remoteNode, SessionMessage sessionMessage) { + init(localNode, remoteNode, sessionMessage); + } + +// public Sender(String remoteHost, int remotePort, SessionMessage sessionMessage) { +// init(remoteHost, remotePort, sessionMessage); +// } + + /** + * 杩炴帴 + */ + public void connect() { + watchDogHandler = new WatchDogHandler(this.remoteNode.getHostName(), this.remoteNode.getPort(), bootstrap); + + ChannelHandlers frontChannelHandlers = new ChannelHandlers() + .addHandler(watchDogHandler); + + ChannelHandlers afterChannelHandlers = new ChannelHandlers() + .addHandler(new StringDecoder()) + .addHandler(new HeartBeatSenderTrigger()) + .addHandler(new HeartBeatSenderHandler()) + .addHandler(new SenderHandler(this.localNode, this.remoteNode, this.sessionMessage)); + + // 鍒濆鍖杦atchDogHandler + watchDogHandler.init(frontChannelHandlers.toArray(), afterChannelHandlers.toArray()); + + bootstrap.handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ch.pipeline() + .addLast(frontChannelHandlers.toArray()) + .addLast(new IdleStateHandler(10, 4, 0, TimeUnit.SECONDS)) + .addLast(new LineBasedFrameDecoder(1024)) + .addLast(afterChannelHandlers.toArray()); + } + }); + + ThreadPoolExecutor runThread = initRunThread(); + + // 鍗曠嫭绾跨▼杩涜杩炴帴锛岄槻姝㈠綋鍓嶈皟鐢ㄧ嚎绋嬮樆濉 + runThread.execute(() -> { + try { + // 鍙戣捣杩炴帴璇锋眰 + channelFuture = bootstrap.connect(this.remoteNode.getHostName(), this.remoteNode.getPort()).sync(); + boolean isStartSuccess = channelFuture.isSuccess(); + if (isStartSuccess) { + // 鍚姩鎴愬姛 + // 璁剧疆ChannelFuture瀵硅薄锛屼互渚夸簬鍙戦佺殑杩炴帴鐘舵佸鐞 + watchDogHandler.initChannelFuture(channelFuture); + // 閲婃斁绛夊緟 + super.callBackLauncher.bootSuccess(); + // 绛夊緟瀹㈡埛绔叧闂繛鎺 + channelFuture.channel().closeFuture().sync(); + } else { + // 鍚姩澶辫触 + throw new Exception("Sender start fail :" + channelFuture.cause().getMessage() + " !!!"); + } + } catch (Exception e) { + super.callBackLauncher.bootFail(e); + } finally { + close(); + } + }); + } + + /** + * 鍒濆鍖栫浉鍏抽厤缃 + * + * @param localNode + * 鏈湴鑺傜偣 + * @param remoteNode + * 杩滅鑺傜偣 + * @param sessionMessage + * 鏈湴鑺傜偣杩炴帴鍒拌繙绔妭鐐瑰悗鍙戦佺殑SessionMessage + */ + private void init(LocalNode localNode, RemoteNode remoteNode, SessionMessage sessionMessage) { + this.localNode = localNode; + this.remoteNode = remoteNode; + + this.sessionMessage = sessionMessage; + + this.bootstrap = new Bootstrap().group(loopGroup) + .channel(NioSocketChannel.class) + .option(ChannelOption.SO_KEEPALIVE, true) + .option(ChannelOption.TCP_NODELAY, true); + } + + @Override + public String threadNameFormat() { + return "sender-pool-%d"; + } + + /** + * 鍙戦佹秷鎭 + * + * @param message + * 娑堟伅缁熶竴鎺ュ彛 + */ + public void send(IMessage message) { + watchDogHandler.channelFuture().channel().writeAndFlush(message.toTransferByteBuf()); + } + + @Override + public void close() { + // 鍥犱负瑕侀噸杩烇紝闇瑕佷粛鐒堕渶瑕佷娇鐢ㄨLoopGroup锛屽洜姝や笉鑳藉叧闂 +// loopGroup.shutdownGracefully(); + } + + /** + * ChannelHandler闆嗗悎绠$悊绫 + */ + public static class ChannelHandlers { + + private List channelHandlers = new ArrayList<>(); + + /** + * 娣诲姞鎸囧畾鐨凜hannelHandler + * + * @param channelHandler + * 闇瑕佸姞鍏ョ殑ChannelHandler + * @return + */ + public ChannelHandlers addHandler(ChannelHandler channelHandler) { + channelHandlers.add(channelHandler); + return this; + } + + /** + * List闆嗗悎杞崲涓烘暟缁 + * + * @return + */ + public ChannelHandler[] toArray() { + ChannelHandler[] channelHandlerArray = new ChannelHandler[channelHandlers.size()]; + return channelHandlers.toArray(channelHandlerArray); + } + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverHandler.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverHandler.java new file mode 100644 index 00000000..ab3595e9 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverHandler.java @@ -0,0 +1,43 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.handler.HeartBeatSenderHandler + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/15 涓婂崍10:10 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.handler; + +import com.jd.blockchain.stp.communication.message.HeartBeatMessage; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +/** + * 蹇冭烦鎺ユ敹Handler + * @author shaozhuguang + * @create 2019/4/15 + * @since 1.0.0 + */ +@ChannelHandler.Sharable +public class HeartBeatReceiverHandler extends ChannelInboundHandlerAdapter { + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + // 鍒ゆ柇褰撳墠鏀跺埌鐨勪俊鎭槸鍚︿负蹇冭烦淇℃伅 + if (HeartBeatMessage.isHeartBeat(msg)) { + // 鏀跺埌鐨勬秷鎭槸蹇冭烦娑堟伅锛屾鏃堕渶瑕佸洖澶嶄竴涓績璺虫秷鎭 + HeartBeatMessage.write(ctx); + System.out.println("Receive HeartBeat Request Message -> " + msg.toString()); + } else { + // 闈炲績璺充俊鎭殑鎯呭喌涓嬩氦鐢卞叾浠朒andler缁х画澶勭悊 + super.channelRead(ctx, msg); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // 鍑虹幇寮傚父鐩存帴鍏抽棴杩炴帴 + ctx.close(); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverTrigger.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverTrigger.java new file mode 100644 index 00000000..48288dc6 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverTrigger.java @@ -0,0 +1,42 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.handler.HeartBeatSenderTrigger + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/15 涓婂崍10:11 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.handler; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; + +/** + * 蹇冭烦鎺ユ敹瑙﹀彂鍣 + * @author shaozhuguang + * @create 2019/4/15 + * @since 1.0.0 + */ +@ChannelHandler.Sharable +public class HeartBeatReceiverTrigger extends ChannelInboundHandlerAdapter { + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + // 鏈嶅姟绔彧浼氭帴鏀跺績璺虫暟鎹悗搴旂瓟锛岃屼笉浼氫富鍔ㄥ簲绛 + if (evt instanceof IdleStateEvent) { + IdleState idleState = ((IdleStateEvent) evt).state(); + // 璇昏姹傝秴鏃惰〃绀哄緢涔呮病鏈夋敹鍒板鎴风璇锋眰 + if (idleState.equals(IdleState.READER_IDLE)) { + // 闀挎椂闂存湭鏀跺埌瀹㈡埛绔姹傦紝鍒欏叧闂繛鎺 + System.out.println("Long Time UnReceive HeartBeat Request, Close Connection !!!"); + ctx.close(); + } + } else { + // 闈炵┖闂茬姸鎬佷簨浠讹紝鐢卞叾浠朒andler澶勭悊 + super.userEventTriggered(ctx, evt); + } + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderHandler.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderHandler.java new file mode 100644 index 00000000..be1c187b --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderHandler.java @@ -0,0 +1,42 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.handler.HeartBeatSenderHandler + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/15 涓婂崍10:10 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.handler; + +import com.jd.blockchain.stp.communication.message.HeartBeatMessage; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +/** + * 蹇冭烦鍙戦丠andler + * @author shaozhuguang + * @create 2019/4/15 + * @since 1.0.0 + */ +@ChannelHandler.Sharable +public class HeartBeatSenderHandler extends ChannelInboundHandlerAdapter { + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + // 鍒ゆ柇鏀跺埌鐨勬秷鎭 + if (HeartBeatMessage.isHeartBeat(msg)) { + // 鍋囪鏀跺埌鐨勬秷鎭槸瀛楃涓诧紝骞朵笖鏄績璺虫秷鎭紝璇存槑鐢辨湇鍔$鍙戦佷簡蹇冭烦淇℃伅 + // TODO 姝ゅ涓嶉渶瑕佽繘琛屾秷鎭弽棣堬紝鍙渶瑕佹墦鍗版棩蹇楀嵆鍙 + System.out.println("Receive HeartBeat Response Message -> " + msg.toString()); + } else { + super.channelRead(ctx, msg); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // 鍑虹幇寮傚父鐩存帴鍏抽棴杩炴帴 + ctx.close(); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderTrigger.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderTrigger.java new file mode 100644 index 00000000..9a61f31a --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderTrigger.java @@ -0,0 +1,48 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.handler.HeartBeatSenderTrigger + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/15 涓婂崍10:11 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.handler; + +import com.jd.blockchain.stp.communication.message.HeartBeatMessage; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; + +/** + * 蹇冭烦鍙戦佽Е鍙戝櫒 + * @author shaozhuguang + * @create 2019/4/15 + * @since 1.0.0 + */ +@ChannelHandler.Sharable +public class HeartBeatSenderTrigger extends ChannelInboundHandlerAdapter { + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + + // 蹇冭烦浜嬩欢锛堢姸鎬佺┖闂蹭簨浠讹級 + if (evt instanceof IdleStateEvent) { + IdleState idleState = ((IdleStateEvent) evt).state(); + if (idleState.equals(IdleState.READER_IDLE)) { + // Sender璇昏秴鏃讹紝琛ㄧず鍦ㄦ寚瀹氭椂闂村唴鏈敹鍒癛eceiver鐨勫簲绛 + // 姝ゆ椂鍏抽棴杩炴帴锛岃嚜鍔ㄨ皟鐢ㄩ噸杩炴満鍒讹紝杩涜閲嶈繛鎿嶄綔 + System.out.println("Long Time UnReceive HeartBeat Response, Close Connection !!!"); + ctx.close(); + } else if (idleState == IdleState.WRITER_IDLE) { + // Sender鍐欒秴鏃讹紝琛ㄧず寰堥暱鏃堕棿娌℃湁鍙戦佹秷鎭簡锛岄渶瑕佸彂閫佹秷鎭嚦Receiver + System.out.println("Read TimeOut Trigger, Send HeartBeat Request !!!"); + HeartBeatMessage.write(ctx); + } + // TODO 杩樻湁涓绉嶆儏鍐垫槸璇诲啓瓒呮椂锛岃鎯呭喌鏆備笉澶勭悊 + } else { + super.userEventTriggered(ctx, evt); + } + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/ReceiverHandler.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/ReceiverHandler.java new file mode 100644 index 00000000..0dcf6753 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/ReceiverHandler.java @@ -0,0 +1,345 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.handler.ReceiverHandler + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/12 涓婂崍11:14 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.handler; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.jd.blockchain.stp.communication.MessageExecutor; +import com.jd.blockchain.stp.communication.RemoteSession; +import com.jd.blockchain.stp.communication.connection.Connection; +import com.jd.blockchain.stp.communication.connection.listener.ReplyListener; +import com.jd.blockchain.stp.communication.manager.ConnectionManager; +import com.jd.blockchain.stp.communication.message.SessionMessage; +import com.jd.blockchain.stp.communication.message.TransferMessage; +import com.jd.blockchain.stp.communication.node.LocalNode; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import org.apache.commons.codec.binary.Hex; + +import java.io.Closeable; +import java.util.Map; +import java.util.concurrent.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 鎺ユ敹鑰呮秷鎭鐞咹andler + * @author shaozhuguang + * @create 2019/4/12 + * @since 1.0.0 + */ +@ChannelHandler.Sharable +public class ReceiverHandler extends ChannelInboundHandlerAdapter implements Closeable { + + /** + * 闃熷垪鐨勬渶澶у閲忚缃紝榛樿涓256K锛堥槻姝㈤槦鍒楁孩鍑猴級 + */ + private static final int QUEUE_CAPACITY = 256 * 1024; + + /** + * 杩滅RemoteSession淇℃伅闆嗗悎 + * Key涓篠essionId + * Sender鍙戦佺殑娑堟伅涓細鎼哄甫SessionId + * ReceiverHandler浼氭牴鎹笉鍚岀殑SessionId閲囩敤涓嶅悓鐨凪essageExecutor澶勭悊绛栫暐 + */ + private final Map remoteSessions = new ConcurrentHashMap<>(); + + /** + * 鐩戝惉鍣ㄩ泦鍚 + * 瀵瑰簲Sender鍦ㄥ彂閫佽姹備箣鍓嶄細璁剧疆ReplyListener + * Key涓烘瘡涓姹傛秷鎭殑Hash锛岀敤浜庢弿杩版秷鎭殑鍞竴鎬 + * 搴旂瓟涓鏂逛細鍦ㄥ簲绛斾腑鍔犲叆瀵瑰簲鐨刱ey锛岀敤浜庢秷鎭殑鏄犲皠 + */ + private final Map allReplyListeners = new ConcurrentHashMap<>(); + + /** + * session鎺у埗閿 + * 鐢ㄤ簬闃叉瀵圭粺涓RemoteSession瀵硅薄杩涜閲嶅璁剧疆 + */ + private final Lock sessionLock = new ReentrantLock(); + + /** + * 褰撳墠鑺傜偣锛堟湰鍦拌妭鐐癸級鐨勬秷鎭鐞嗗櫒瀵瑰簲Class + * 璇ヤ俊鎭敤浜庡彂閫佽嚦鍏朵粬鑺傜偣锛屽悜鍏朵粬鑺傜偣閫氱煡閬囧埌鏈妭鐐硅姹傛椂璇ュ浣曞鐞 + */ + private String localMsgExecutorClass; + + /** + * 杩炴帴鎺у埗鍣紝鐢ㄤ簬涓庤繙绔妭鐐硅繛鎺 + */ + private ConnectionManager connectionManager; + + /** + * 娑堟伅澶勭悊鎵ц绾跨▼姹 + * 闃叉鎵ц鍐呭杩囬暱锛屽鑷撮樆濉 + */ + private ExecutorService msgExecutorPool; + + /** + * 榛樿娑堟伅澶勭悊鍣 + * 褰撳搴攕ession鑾峰彇鍒扮殑RemoteSession涓病鏈夎幏鍙栧埌鎸囧畾MessageExecutor鏃讹紝鐭椂闂村唴鐢卞叾杩涜澶勭悊 + */ + private MessageExecutor defaultMessageExecutor; + + /** + * 鏈湴鑺傜偣 + */ + private LocalNode localNode; + + public ReceiverHandler(ConnectionManager connectionManager, String localMsgExecutorClass, + LocalNode localNode) { + this.connectionManager = connectionManager; + this.localMsgExecutorClass = localMsgExecutorClass; + this.defaultMessageExecutor = localNode.defaultMessageExecutor(); + this.localNode = localNode; + initMsgExecutorPool(); + } + + public void putRemoteSession(String sessionId, RemoteSession remoteSession) { + remoteSessions.put(sessionId, remoteSession); + } + + public void addListener(ReplyListener replyListener) { + allReplyListeners.put(replyListener.listenKey(), replyListener); + } + + public void removeListener(String key) { + this.allReplyListeners.remove(key); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + + System.out.printf("%s Receive Biz Message -> %s \r\n", this.localNode.toString(), msg.toString()); + // 鏈夋暟鎹帴鍏 + // 棣栧厛鍒ゆ柇鏁版嵁鏄惁TransferMessage锛屽綋鍓岺andler涓嶅鐞嗛潪TransferMessage + TransferMessage tm = TransferMessage.toTransferMessage(msg); + if (tm == null) { + // 鍒ゆ柇鏄惁鏄疭essionMessage + SessionMessage sm = SessionMessage.toSessionMessage(msg); + if (sm != null) { + executeSessionMessage(sm); + } else { + super.channelRead(ctx, msg); + } + } else { + TransferMessage.MESSAGE_TYPE messageType = TransferMessage.MESSAGE_TYPE.valueOf(tm.getType()); + // 瀵逛簬璇锋眰鍜屽簲绛斿鐞嗘柟寮忎笉鍚 + if (messageType.equals(TransferMessage.MESSAGE_TYPE.TYPE_REQUEST)) { + // 鍋囪鏄姹傛秷鎭 + executeRequest(tm); + } else if (messageType.equals(TransferMessage.MESSAGE_TYPE.TYPE_RESPONSE)) { + // 鍋囪鏄簲绛旀秷鎭 + executeResponse(tm); + } else { + // todo 鍏朵粬娑堟伅鍙渶瑕佹墦鍗版棩蹇楀嵆鍙 + + + } + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + ctx.close(); + } + + /** + * 澶勭悊璇锋眰娑堟伅 + * + * @param transferMessage + * 鎺ユ敹鍒扮殑璇锋眰娑堟伅 + */ + private void executeRequest(final TransferMessage transferMessage) { + msgExecutorPool.execute(() -> { + RemoteSession remoteSession = remoteSessions.get(transferMessage.getSessionId()); + if (remoteSession != null) { + MessageExecutor messageExecutor = remoteSession.messageExecutor(); + if (messageExecutor == null) { + // 閲囩敤榛樿澶勭悊鍣ㄨ繘琛屽鐞 + messageExecutor = defaultMessageExecutor; + } + MessageExecutor.REPLY replyType = messageExecutor.replyType(); + if (replyType != null) { + switch (replyType) { + case MANUAL: + messageExecutor.receive(transferMessage.loadKey(), transferMessage.load(), remoteSession); + break; + case AUTO: + String requestKey = transferMessage.loadKey(); + byte[] replyMsg = messageExecutor.receive(requestKey, transferMessage.load(), remoteSession); + // 搴旂瓟 + remoteSession.reply(requestKey, () -> replyMsg); + break; + default: + break; + } + } + } + }); + } + + /** + * 澶勭悊搴旂瓟娑堟伅 + * @param transferMessage + * 鎺ユ敹鍒扮殑搴旂瓟娑堟伅 + */ + private void executeResponse(final TransferMessage transferMessage) { + msgExecutorPool.execute(() -> { + // listenKey鍜宮sgKey鏄笉涓鑷寸殑 + // msgKey鏄娑堟伅鏈韩璁剧疆key锛宭istenKey鏄鏁翠釜娑堟伅锛堝寘鎷瑂ession淇℃伅锛 + String listenKey = transferMessage.toListenKey(); + + ReplyListener replyListener = allReplyListeners.get(listenKey); + + if (replyListener != null) { + // 濉厖瀵瑰簲鐨勭粨鏋 + replyListener.replyData(transferMessage.load()); + + ReplyListener.MANAGE_TYPE manageType = replyListener.manageType(); + + if (manageType != null) { + switch (manageType) { + case REMOVE: + // 灏嗗璞′粠Map涓Щ闄 + removeListener(listenKey); + break; + case HOLD: + default: + // todo 鎵撳嵃鏃ュ織 + + break; + } + } + } + }); + } + + /** + * 澶勭悊SessionMessage + * @param sessionMessage + * 鎻忚堪Session鐨勬秷鎭璞 + */ + private void executeSessionMessage(SessionMessage sessionMessage) { + // 澶勭悊SessionMessage + String sessionId = sessionMessage.sessionId(); + if (sessionId != null) { + // 瀵逛簬鍚湁鐨凴emoteSession鐨凪ap锛岄渶瑕佸垽鏂叾MessageExecutor鏄惁涓篘ULL + RemoteSession remoteSession = remoteSessions.get(sessionId); + if (remoteSession == null) { + try { + sessionLock.lock(); + // 鐢熸垚瀵瑰簲鐨凪essageExecute瀵硅薄 + String meClass = sessionMessage.getMessageExecutor(); + MessageExecutor messageExecutor = initMessageExecutor(meClass); + + // 璇存槑灏氭湭鍜岃姹傛潵鐨勫鎴风寤虹珛杩炴帴锛岄渶瑕佸缓绔嬭繛鎺 + Connection remoteConnection = this.connectionManager.connect(new RemoteNode( + sessionMessage.getLocalHost(), sessionMessage.getListenPort()), + this.localMsgExecutorClass); + // 鍋囪杩炴帴澶辫触鐨勮瘽锛岃繑鍥炵殑Connection瀵硅薄涓簄ull锛屾鏃朵笉鏀惧叆Map锛岀瓑鍚庣画鍐嶅鐞 + if (remoteConnection != null) { + + remoteSession = new RemoteSession(this.localId(), remoteConnection, messageExecutor); + + // Double check 锛侊紒锛 + if (!remoteSessions.containsKey(sessionId)) { + this.putRemoteSession(sessionId, remoteSession); + } + } + } finally { + sessionLock.unlock(); + } + } else { + // 闇瑕佸垽鏂璏essageExecutor + MessageExecutor me = remoteSession.messageExecutor(); + if (me == null) { + try { + sessionLock.lock(); + // Double Check !!! + if (remoteSession.messageExecutor() == null) { + // 琛ㄦ槑涓婃瀛樺偍鐨凪essageExecutor鏈垱寤烘垚鍔燂紝鏈杩涜鏇存柊 + String meClass = sessionMessage.getMessageExecutor(); + MessageExecutor messageExecutor = initMessageExecutor(meClass); + + // 闃叉NULL灏嗗叾浠栫殑杩涜瑕嗙洊 + if (messageExecutor != null) { + remoteSession.initExecutor(messageExecutor); + } + } + } finally { + sessionLock.unlock(); + } + } + } + } + } + + /** + * 鍒濆鍖栨秷鎭墽琛屽櫒 + * 鏍规嵁娑堟伅鎵ц鍣ㄧ殑Class瀛楃涓茬敓鎴愬搴旂殑娑堟伅澶勭悊瀵硅薄 + * @param messageExecutorClass + * 娑堟伅鎵ц鍣ㄧ殑Class瀛楃涓 + * @return + * 瀵瑰簲鐨勬秷鎭鐞嗗璞★紝浜х敓浠讳綍寮傚父閮借繑鍥濶ULL + */ + private MessageExecutor initMessageExecutor(String messageExecutorClass) { + // 鐢熸垚瀵瑰簲鐨凪essageExecute瀵硅薄 + MessageExecutor messageExecutor = null; + if (messageExecutorClass != null && messageExecutorClass.length() > 0) { + try { + Class clazz = Class.forName(messageExecutorClass); + messageExecutor = (MessageExecutor) clazz.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + return messageExecutor; + } + + /** + * 鍒濆鍖栨秷鎭鐞嗙嚎绋嬫睜 + */ + private void initMsgExecutorPool() { + + ThreadFactory msgExecuteThreadFactory = new ThreadFactoryBuilder() + .setNameFormat("msg-executor-pool-%d").build(); + + //Common Thread Pool + msgExecutorPool = new ThreadPoolExecutor(5, 10, + 60, TimeUnit.SECONDS, + new LinkedBlockingQueue<>(QUEUE_CAPACITY), + msgExecuteThreadFactory, new ThreadPoolExecutor.AbortPolicy()); + } + + /** + * 杩斿洖鏈湴鑺傜偣 + * + * @return + */ + public LocalNode localNode() { + return localNode; + } + + /** + * 杩斿洖鏈湴鑺傜偣ID + * + * @return + */ + private String localId() { + return Hex.encodeHexString(localNode.toString().getBytes()); + } + + @Override + public void close() { + msgExecutorPool.shutdown(); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/SenderHandler.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/SenderHandler.java new file mode 100644 index 00000000..ed763434 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/SenderHandler.java @@ -0,0 +1,67 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.handler.SenderHandler + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/16 涓嬪崍2:00 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.handler; + +import com.jd.blockchain.stp.communication.message.SessionMessage; +import com.jd.blockchain.stp.communication.node.LocalNode; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + + +/** + * Sender瀵瑰簲Handler + * @author shaozhuguang + * @create 2019/4/16 + * @since 1.0.0 + */ +@ChannelHandler.Sharable +public class SenderHandler extends ChannelInboundHandlerAdapter { + + /** + * 鏈湴session淇℃伅 + */ + private SessionMessage sessionMessage; + + /** + * 鏈湴鑺傜偣 + */ + private LocalNode localNode; + + /** + * 杩滅鑺傜偣 + */ + private RemoteNode remoteNode; + + public SenderHandler(LocalNode localNode, RemoteNode remoteNode, SessionMessage sessionMessage) { + this.localNode = localNode; + this.remoteNode = remoteNode; + this.sessionMessage = sessionMessage; + } + + /** + * 杩炴帴杩滅鑺傜偣鎴愬姛鏃惰Е鍙 + * + * @param ctx + * @throws Exception + */ + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + + // 鍙戦佹湰鏈轰俊鎭紙鍖呮嫭IP銆佺鍙g瓑锛夎嚦瀵圭 + System.out.printf("%s Connect %s Success, Send Local Node Information !!! \r\n", this.localNode, this.remoteNode); + ctx.writeAndFlush(sessionMessage.toTransferByteBuf()); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + ctx.close(); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/WatchDogHandler.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/WatchDogHandler.java new file mode 100644 index 00000000..bdcb82de --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/WatchDogHandler.java @@ -0,0 +1,267 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.SenderWatchDog + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/12 涓嬪崍4:56 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.handler; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.jd.blockchain.stp.communication.message.HeartBeatMessage; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.timeout.IdleStateHandler; + +import java.io.Closeable; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 杩炴帴鐩戝惉鍣 + * @author shaozhuguang + * @create 2019/4/12 + * @since 1.0.0 + * @date 2019-04-19 09:21 + */ +@ChannelHandler.Sharable +public class WatchDogHandler extends ChannelInboundHandlerAdapter implements Runnable, Closeable { + + /** + * 褰撳墠杩炴帴娲昏穬鐘舵 + */ + private final AtomicBoolean currentActive = new AtomicBoolean(false); + + /** + * 閲嶈繛鐨勬帶鍒堕攣 + * 闃叉閲嶈繛杩囩▼涓噸澶嶅娆¤皟鐢 + */ + private final Lock reconnectLock = new ReentrantLock(); + + /** + * 榛樿鐨勬渶澶氶噸杩炴鏁 + */ + private final int maxReconnectSize = 16; + + /** + * 榛樿閲嶈繛鐨勬椂闂达紝涓嬫閲嶈繛鏃堕棿浼氬彉闀 + */ + private final int defaultReconnectSeconds = 2; + + /** + * 鏍囪瘑鏄惁姝e父宸ヤ綔涓紝鍋囪涓嶅啀宸ヤ綔鍒欎笉鍐嶉噸杩 + */ + private boolean isWorking = true; + + /** + * 閲嶈繛璋冨害鍣 + */ + private ScheduledExecutorService reconnectTimer; + + /** + * 杩滅鐨処P锛堝煙鍚嶏級淇℃伅 + */ + private String hostName; + + /** + * 杩滅鐨勭鍙 + */ + private int port; + + private Bootstrap bootstrap; + + /** + * 绗竴缁凥andler鏁扮粍 + */ + private ChannelHandler[] frontHandlers; + + /** + * 鍚庝竴缁凥andler鏁扮粍 + */ + private ChannelHandler[] afterHandlers; + + /** + * 鐢ㄤ簬閲嶈繛鏃跺璞¢噸缃 + */ + private ChannelFuture channelFuture; + + /** + * 鏋勯犲櫒 + * @param hostName + * 杩滅Host + * @param port + * 杩滅绔彛 + * @param bootstrap + * Netty宸ヤ綔鍚姩鍣 + */ + public WatchDogHandler(String hostName, int port, Bootstrap bootstrap) { + this.hostName = hostName; + this.port = port; + this.bootstrap = bootstrap; + } + + /** + * 鏋勯犲櫒 + * @param remoteNode + * 杩滅鑺傜偣 + * @param bootstrap + * Netty宸ヤ綔鍚姩鍣 + */ + public WatchDogHandler(RemoteNode remoteNode, Bootstrap bootstrap) { + this(remoteNode.getHostName(), remoteNode.getPort(), bootstrap); + } + + /** + * 閰嶇疆閲嶈繛闇瑕佺殑Handler + * 涓昏鏄负浜嗗璞$殑澶嶇敤锛屽悓鏃舵湁浜汬andler鏃犳硶澶嶇敤锛屽浜庢瘡娆¤繛鎺ヨ姹傚繀椤昏new鏂扮殑瀵硅薄 + * @param frontHandlers + * @param afterHandlers + */ + public void init(ChannelHandler[] frontHandlers, ChannelHandler[] afterHandlers) { + this.frontHandlers = frontHandlers; + this.afterHandlers = afterHandlers; + initTimer(); + } + + /** + * 鍒濆鍖朇hannelFuture + * + * @param channelFuture + */ + public void initChannelFuture(ChannelFuture channelFuture) { + this.channelFuture = channelFuture; + } + + /** + * 杩斿洖ChannelFuture + * + * @return + * 璇ヨ繑鍥炲璞$洰鍓嶆湭澶勭悊鏄惁杩炴帴鎴愬姛鐨勬儏鍐 + * 璋冪敤鑰呭彲鐩存帴浣跨敤锛屼絾鍋囪鍙戦佷笉鎴愬姛鐨勮瘽浼氬瓨鍦ㄥ紓甯告姏鍑 + * 璋冪敤鑰呭彲鎵嬪姩澶勭悊寮傚父 + */ + public ChannelFuture channelFuture() { + try { + // 浣跨敤閿侀槻姝㈠湪閲嶈繛杩涜杩囩▼涓簰鐩哥珵浜 + // 涓瀹氭槸绛夊緟鏈閲嶈繛瀹屾垚鎵嶈繑鍥 + reconnectLock.lock(); + return this.channelFuture; + } finally { + reconnectLock.unlock(); + } + } + + /** + * 杩炴帴鎴愬姛璋冪敤 + * 璇ヨ繛鎺ユ垚鍔熻〃绀哄畬鍏ㄨ繛鎺ユ垚鍔燂紝瀵逛簬TCP鑰岃█灏辨槸涓夋鎻℃墜鎴愬姛 + * @param ctx + * @throws Exception + */ + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + // 璋冪敤璇ユ柟娉曡〃绀鸿繛鎺ユ垚鍔 + connectSuccess(); + + // 杩炴帴鎴愬姛鍚庡彂閫佸績璺虫秷鎭嚦鏈嶅姟绔 + HeartBeatMessage.write(ctx); + + ctx.fireChannelActive(); + } + + /** + * 杩炴帴澶辫触鏃惰皟鐢 + * 姝ゅ鏄Е鍙戦噸杩炵殑鍏ュ彛 + * @param ctx + * @throws Exception + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + + System.err.println("Connection Exception, Close And Reconnect !!!"); + // 璋冪敤璇ユ柟娉曟椂琛ㄧず杩炴帴鍏抽棴浜嗭紙鏃犺鏄粈涔堝師鍥狅級 + // 杩炴帴鍏抽棴鐨勬儏鍐典笅闇瑕侀噸鏂拌繛鎺 + + connectFail(); + + ctx.close(); + + for (int i = 0; i < maxReconnectSize; i++) { + reconnectTimer.schedule(this, defaultReconnectSeconds << i, TimeUnit.SECONDS); + } + + ctx.fireChannelInactive(); + } + + @Override + public void run() { + if (isNeedReconnect()) { + // 閲嶈繛 + try { + reconnectLock.lock(); + if (isNeedReconnect()) { + + bootstrap.handler(new ChannelInitializer() { + @Override + protected void initChannel(Channel ch) throws Exception { + ch.pipeline() + .addLast(frontHandlers) + .addLast(new IdleStateHandler(10, 4, 0, TimeUnit.SECONDS)) + .addLast(new LineBasedFrameDecoder(1024)) + .addLast(afterHandlers) + ; + } + }); + + channelFuture = bootstrap.connect(hostName, port); + + // 澧炲姞鐩戝惉鍣ㄧ敤浜庡垽鏂湰娆¢噸杩炴槸鍚︽垚鍔 + channelFuture.addListener((ChannelFutureListener) future -> { + boolean isReconnectSuccess = future.isSuccess(); + if (isReconnectSuccess) { + // 杩炴帴鎴愬姛 + connectSuccess(); + } else { + connectFail(); + } + }); + + } + } finally { + reconnectLock.unlock(); + } + } + } + + private boolean isNeedReconnect() { + return isWorking && !currentActive.get(); + } + + private void connectSuccess() { + this.currentActive.set(true); + } + + private void connectFail() { + this.currentActive.set(false); + } + + @Override + public void close() { + this.isWorking = false; + this.reconnectTimer.shutdown(); + } + + /** + * 璁剧疆璋冨害鍣 + */ + private void initTimer() { + ThreadFactory timerFactory = new ThreadFactoryBuilder() + .setNameFormat("reconnect-pool-%d").build(); + + reconnectTimer = new ScheduledThreadPoolExecutor(1, timerFactory, new ThreadPoolExecutor.AbortPolicy()); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/listener/ReplyListener.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/listener/ReplyListener.java new file mode 100644 index 00000000..ac9221d0 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/listener/ReplyListener.java @@ -0,0 +1,87 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.connection.listener.ReplyListener + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/12 涓婂崍10:36 + * Description: + */ +package com.jd.blockchain.stp.communication.connection.listener; + +import com.jd.blockchain.stp.communication.callback.CallBackBarrier; +import com.jd.blockchain.stp.communication.callback.CallBackDataListener; +import com.jd.blockchain.stp.communication.node.RemoteNode; + + +/** + * 搴旂瓟鐩戝惉鍣 + * @author shaozhuguang + * @create 2019/4/12 + * @since 1.0.0 + */ + +public class ReplyListener { + + /** + * 鐩戝惉鐨凨ey锛岄氬父鐢ㄤ簬鎻忚堪鍞竴鐨勮姹 + */ + private String listenKey; + + /** + * 娑堟伅澶勭悊绫诲瀷 + * REMOVE锛氳〃绀哄鐞嗗畬璇ュ璞′箣鍚庝粠缂撳瓨涓竻闄 + * HOLD锛氳〃绀哄鐞嗗畬璇ュ璞′箣鍚庝粛鍦ㄧ紦瀛樹腑淇濆瓨 + */ + private MANAGE_TYPE manageType = MANAGE_TYPE.REMOVE; + + /** + * 鏁版嵁鍥炶皟鐩戝惉鍣 + */ + private CallBackDataListener callBackDataListener; + + /** + * 鍥炶皟鏍呮爮 + */ + private CallBackBarrier callBackBarrier; + + public ReplyListener(String listenKey, RemoteNode remoteNode) { + this(listenKey, remoteNode, null); + } + + public ReplyListener(String listenKey, RemoteNode remoteNode, CallBackBarrier callBackBarrier) { + this.listenKey = listenKey; + this.callBackDataListener = new CallBackDataListener(remoteNode); + this.callBackBarrier = callBackBarrier; + } + + public void setManageType(MANAGE_TYPE manageType) { + this.manageType = manageType; + } + + public String listenKey() { + return listenKey; + } + + public CallBackDataListener callBackDataListener() { + return this.callBackDataListener; + } + + public void replyData(byte[] reply) { + // 璁剧疆鏁版嵁 + this.callBackDataListener.setCallBackData(reply); + if (this.callBackBarrier != null) { + // 鍚屾閲婃斁瀵瑰簲鐨勬爡鏍 + this.callBackBarrier.release(); + } + } + + public MANAGE_TYPE manageType() { + return this.manageType; + } + + public enum MANAGE_TYPE { + HOLD, + REMOVE, + ; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/ConnectionManager.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/ConnectionManager.java new file mode 100644 index 00000000..c8336284 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/ConnectionManager.java @@ -0,0 +1,175 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.ConnectionManager + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓嬪崍6:11 + * Description: + */ +package com.jd.blockchain.stp.communication.manager; + +import com.jd.blockchain.stp.communication.callback.CallBackLauncher; +import com.jd.blockchain.stp.communication.connection.Receiver; +import com.jd.blockchain.stp.communication.connection.Connection; +import com.jd.blockchain.stp.communication.node.LocalNode; +import com.jd.blockchain.stp.communication.node.RemoteNode; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 杩炴帴绠$悊鍣 + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + * @date 2019-04-18 15:11 + */ + +public class ConnectionManager { + + /** + * Connection瀵瑰簲Map + * RemoteNode鍞竴鎬э細IP锛圚OST锛+PORT + */ + private final Map connectionMap = new ConcurrentHashMap<>(); + + /** + * 杩炴帴绠$悊鍣ㄥ搴擬AP + * 浠ョ洃鍚鍙o紙int锛変綔涓篕ey锛岃繘琛屽敮涓鎬х害鏉 + */ + private static final Map connectionManagerMap = new ConcurrentHashMap<>(); + + /** + * connectionManagerMap鎺у埗閿 + */ + private static final Lock managerLock = new ReentrantLock(); + + /** + * connectionMap鎺у埗閿 + */ + private static final Lock connectionLock = new ReentrantLock(); + + /** + * 褰撳墠ConnectionManager瀵瑰簲鐨凴eceiver + */ + private Receiver receiver; + + /** + * 闈欐丆onnectionManager鏋勯犲櫒 + * + * @param localNode + * 鏈湴鑺傜偣 + * @return + * 浼樺厛杩斿洖Map涓殑瀵硅薄 + */ + public static final ConnectionManager newConnectionManager(LocalNode localNode) { + int listenPort = localNode.getPort(); + if (!connectionManagerMap.containsKey(listenPort)) { + try { + managerLock.lock(); + if (!connectionManagerMap.containsKey(listenPort)) { + ConnectionManager connectionManager = newInstance(localNode); + connectionManagerMap.put(listenPort, connectionManager); + return connectionManager; + } + } finally { + managerLock.unlock(); + } + } + return connectionManagerMap.get(listenPort); + } + + /** + * 鍐呴儴璋冪敤鐨勯潤鎬佹瀯閫犲櫒 + * + * @param localNode + * 鏈湴鑺傜偣 + * @return + */ + private static final ConnectionManager newInstance(LocalNode localNode) { + return new ConnectionManager(new Receiver(localNode)); + } + + /** + * 鍚姩 + * 璇ュ惎鍔ㄦ槸鍚姩Receiver锛岃繑鍥炲惎鍔ㄧ殑鐘舵 + * + * @param messageExecutorClass + * 褰撳墠鑺傜偣甯屾湜鍏朵粬鑺傜偣鏀跺埌璇ヨ妭鐐逛俊鎭椂鐨勫鐞咹andler + * @return + * 鍥炶皟鎵ц鍣 + * @throws InterruptedException + */ + public final CallBackLauncher start(String messageExecutorClass) throws InterruptedException { + receiver.initReceiverHandler(this, messageExecutorClass); + receiver.startListen(); + // 鍒ゆ柇鏄惁鍚姩瀹屾垚锛屽惎鍔ㄥ畬鎴愬悗鍐嶈繑鍥 + return receiver.waitBooted(); + } + + private ConnectionManager(Receiver receiver) { + this.receiver = receiver; + } + + /** + * 杩炴帴杩滅鑺傜偣 + * + * @param remoteNode + * 杩滅鑺傜偣淇℃伅 + * @param messageExecutorClass + * 甯屾湜杩滅鑺傜偣鎺ユ敹鍒版湰鑺傜偣娑堟伅鏃剁殑澶勭悊Handler + * @return + */ + public Connection connect(RemoteNode remoteNode, String messageExecutorClass) { + if (!connectionMap.containsKey(remoteNode)) { + try { + connectionLock.lock(); + if (!connectionMap.containsKey(remoteNode)) { + Connection connection = init(remoteNode, messageExecutorClass); + if (connection != null) { + // 淇濊瘉閮芥槸杩炴帴鎴愬姛鐨 + connectionMap.put(remoteNode, connection); + return connection; + } else { + // 杩炴帴澶辫触杩斿洖null + return null; + } + } + } finally { + connectionLock.unlock(); + } + } + return connectionMap.get(remoteNode); + } + + /** + * 鍏抽棴Receiver + * + */ + public void closeReceiver() { + this.receiver.close(); + } + + private Connection init(RemoteNode remoteNode, String messageExecutorClass) { + + // 鍒濆鍖朇onnection + Connection remoteConnection = new Connection(this.receiver); + + try { + // 杩炴帴杩滅锛岄渶瑕佸彂閫佸綋鍓嶈妭鐐瑰鐞嗙殑MessageExecuteClass + CallBackLauncher callBackLauncher = remoteConnection.connect(remoteNode, messageExecutorClass); + if (!callBackLauncher.isBootSuccess()) { + // TODO 鎵撳嵃閿欒鏃ュ織 + callBackLauncher.exception().printStackTrace(); + return null; + } + return remoteConnection; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (RuntimeException e) { + throw e; + } + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/RemoteSessionManager.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/RemoteSessionManager.java new file mode 100644 index 00000000..1086fb33 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/RemoteSessionManager.java @@ -0,0 +1,180 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.RemoteSessionManager + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓婂崍11:22 + * Description: + */ +package com.jd.blockchain.stp.communication.manager; + + +import com.jd.blockchain.stp.communication.MessageExecutor; +import com.jd.blockchain.stp.communication.RemoteSession; +import com.jd.blockchain.stp.communication.callback.CallBackLauncher; +import com.jd.blockchain.stp.communication.connection.Connection; +import com.jd.blockchain.stp.communication.node.LocalNode; +import com.jd.blockchain.stp.communication.node.RemoteNode; +import org.apache.commons.codec.binary.Hex; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + + +/** + * 杩滅Session绠$悊鍣 + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + */ + +public class RemoteSessionManager { + + /** + * 鍙洃鍚殑鏈澶х鍙 + */ + private static final int MAX_PORT = 65535; + + /** + * 鑺傜偣Session鐨勯泦鍚堜俊鎭 + */ + private Map nodeRemoteSessionMap = new ConcurrentHashMap<>(); + + /** + * nodeRemoteSessionMap鐨勬帶鍒堕攣 + */ + private Lock lock = new ReentrantLock(); + + /** + * 杩炴帴绠$悊鍣 + * 鐢ㄤ簬绠$悊搴曞眰鐨勯氫俊杩炴帴 + */ + private ConnectionManager connectionManager; + + /** + * 鏈湴鑺傜偣淇℃伅 + */ + private LocalNode localNode; + + /** + * 鏈湴鑺傜偣ID + */ + private String localId; + + /** + * 鏋勯犲櫒 + * @param localNode + * 鏈湴鑺傜偣淇℃伅 + */ + public RemoteSessionManager(LocalNode localNode) { + this.localNode = localNode; + this.localId = localId(); + // 鏍¢獙鏈湴鑺傜偣鐨勯厤缃紝闃叉寮傚父 + check(); + this.connectionManager = ConnectionManager.newConnectionManager(this.localNode); + try { + CallBackLauncher callBackLauncher = start(); + if (!callBackLauncher.isBootSuccess()) { + // 鍚姩褰撳墠绔彛杩炴帴蹇呴』瑕佹垚鍔燂紝鍚﹀垯鍒欓鍑猴紝浜ょ敱搴旂敤绋嬪簭澶勭悊 + throw new RuntimeException(callBackLauncher.exception()); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (RuntimeException e) { + throw e; + } + } + + /** + * RemoteSession瀵硅薄鐢熸垚鍣 + * @param remoteNode + * 杩滅鑺傜偣淇℃伅 + * @return + */ + public RemoteSession newSession(RemoteNode remoteNode) { + + RemoteSession remoteSession = nodeRemoteSessionMap.get(remoteNode); + + if (remoteSession != null) { + return remoteSession; + } else { + try { + lock.lock(); + + // Double Check !!! + if (!nodeRemoteSessionMap.containsKey(remoteNode)) { + Connection remoteConnection = this.connectionManager.connect(remoteNode, localNode.messageExecutorClass()); + + if (remoteConnection == null) { + return null; + } + + remoteSession = new RemoteSession(localId, remoteConnection); + + remoteSession.init(); + + nodeRemoteSessionMap.put(remoteNode, remoteSession); + + return remoteSession; + } + } finally { + lock.unlock(); + } + } + return null; + } + + public RemoteSession[] newSessions(RemoteNode[] remoteNodes) { + List remoteSessionList = new ArrayList<>(); + + for (int i = 0; i < remoteNodes.length; i++) { + RemoteSession remoteSession = newSession(remoteNodes[i]); + if (remoteSession != null) { + remoteSessionList.add(remoteSession); + } + } + + if (remoteSessionList.isEmpty()) { + return null; + } + + RemoteSession[] remoteSessions = new RemoteSession[remoteSessionList.size()]; + + return remoteSessionList.toArray(remoteSessions); + } + + /** + * 杩斿洖搴曞眰閫氫俊绠$悊鍣 + * + * @return + */ + public ConnectionManager connectionManager() { + return this.connectionManager; + } + + private void check() { + // 瑕佹眰绔彛鑼冨洿锛1~65535锛宮essageExecuteClass涓嶈兘涓簄ull + int listenPort = this.localNode.getPort(); + if (listenPort <= 0 || listenPort > MAX_PORT) { + throw new IllegalArgumentException("Illegal Local Listen Port, Please Check !!!"); + } + + // 榛樿澶勭悊鍣ㄥ繀椤诲寘鍚紝鍙笉鍖呭惈鏈満闇瑕佸绔煡鏅撶殑澶勭悊鍣 + MessageExecutor defaultMessageExecutor = this.localNode.defaultMessageExecutor(); + if (defaultMessageExecutor == null) { + throw new IllegalArgumentException("Illegal Default MessageExecutor, Please Check !!!"); + } + } + + private CallBackLauncher start() throws InterruptedException { + return this.connectionManager.start(this.localNode.messageExecutorClass()); + } + + private String localId() { + return Hex.encodeHexString(localNode.toString().getBytes()); + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/AbstractMessage.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/AbstractMessage.java new file mode 100644 index 00000000..a20ef623 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/AbstractMessage.java @@ -0,0 +1,30 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.message.AbstractMessage + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/17 涓嬪崍4:00 + * Description: + */ +package com.jd.blockchain.stp.communication.message; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +/** + * 鎶借薄娑堟伅 + * @author shaozhuguang + * @create 2019/4/17 + * @since 1.0.0 + */ + +public abstract class AbstractMessage implements IMessage { + + @Override + public ByteBuf toTransferByteBuf() { + byte[] message = (toTransfer() + "\r\n").getBytes(); + ByteBuf byteBuf = Unpooled.buffer(message.length); + byteBuf.writeBytes(message); + return byteBuf; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/HeartBeatMessage.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/HeartBeatMessage.java new file mode 100644 index 00000000..eba5e4b6 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/HeartBeatMessage.java @@ -0,0 +1,76 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.message.HeartBeatMessage + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/12 涓嬪崍4:55 + * Description: + */ +package com.jd.blockchain.stp.communication.message; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.CharsetUtil; + +/** + * 蹇冭烦娑堟伅 + * @author shaozhuguang + * @create 2019/4/12 + * @since 1.0.0 + */ + +public class HeartBeatMessage implements IMessage { + + /** + * 缁熶竴鐨勫績璺充俊鎭瓧绗︿覆 + */ + private static final String HEARTBEAT_STRING = "JDChainHeartBeat"; + + /** + * 缁熶竴鐨勫績璺虫秷鎭瓧绗︿覆瀵逛竴涓殑ByteBuf + */ + private static final ByteBuf HEARTBEAT_MESSAGE = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer(HEARTBEAT_STRING + "\r\n", + CharsetUtil.UTF_8)); + + /** + * 灏嗗績璺虫秷鎭啓鍏tx + * @param ctx + */ + public static final void write(ChannelHandlerContext ctx) { + ctx.writeAndFlush(HEARTBEAT_MESSAGE.duplicate()); + } + + /** + * 鍒ゆ柇鎺ユ敹鐨勬秷鎭槸鍚︿负蹇冭烦娑堟伅 + * + * @param msg + * @return + */ + public static final boolean isHeartBeat(Object msg) { + return isHeartBeat(msg.toString()); + } + + /** + * 鍒ゆ柇鎺ユ敹鐨勬秷鎭槸鍚︿负蹇冭烦娑堟伅 + * + * @param msg + * @return + */ + public static final boolean isHeartBeat(String msg) { + if (HEARTBEAT_STRING.equals(msg)) { + return true; + } + return false; + } + + @Override + public String toTransfer() { + return HEARTBEAT_STRING; + } + + @Override + public ByteBuf toTransferByteBuf() { + return HEARTBEAT_MESSAGE; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/IMessage.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/IMessage.java new file mode 100644 index 00000000..c43e8d84 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/IMessage.java @@ -0,0 +1,33 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.message.IMessage + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/16 涓嬪崍1:58 + * Description: + */ +package com.jd.blockchain.stp.communication.message; + +import io.netty.buffer.ByteBuf; + +/** + * 娑堟伅鎺ュ彛 + * @author shaozhuguang + * @create 2019/4/16 + * @since 1.0.0 + */ + +public interface IMessage { + + /** + * 娑堟伅杞崲涓哄瓧绗︿覆 + * @return + */ + String toTransfer(); + + /** + * 娑堟伅杞崲涓築yteBuf + * @return + */ + ByteBuf toTransferByteBuf(); +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/LoadMessage.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/LoadMessage.java new file mode 100644 index 00000000..b8971293 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/LoadMessage.java @@ -0,0 +1,26 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.message.LoadMessage + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓婂崍10:59 + * Description: + */ +package com.jd.blockchain.stp.communication.message; + +/** + * 璐熻浇娑堟伅 + * 璇ユ帴鍙g敤浜庡簲鐢ㄥ疄鐜 + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + */ + +public interface LoadMessage { + + /** + * 灏嗚礋杞芥秷鎭浆鎹负瀛楄妭鏁扮粍 + * @return + */ + byte[] toBytes(); +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/SessionMessage.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/SessionMessage.java new file mode 100644 index 00000000..b3ce460b --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/SessionMessage.java @@ -0,0 +1,112 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.message.SessionMessage + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/16 涓婂崍10:40 + * Description: + */ +package com.jd.blockchain.stp.communication.message; + +import org.apache.commons.codec.binary.Hex; + +/** + * Session娑堟伅 + * 璇ユ秷鎭敤浜庡彂閫佽嚦杩滅鑺傜偣锛屽憡璇夎繙绔妭鐐规湰鍦扮殑淇℃伅 + * @author shaozhuguang + * @create 2019/4/16 + * @since 1.0.0 + */ + +public class SessionMessage extends AbstractMessage implements IMessage { + + /** + * 鏈湴鑺傜偣HOST + */ + private String localHost; + + /** + * 鏈湴鑺傜偣鐩戝惉绔彛 + */ + private int listenPort; + + /** + * 杩滅鎺ユ敹鍒版湰鍦拌妭鐐逛俊鎭椂澶勭悊鐨凜lass + */ + private String messageExecutor; + + public SessionMessage() { + } + + public SessionMessage(String localHost, int listenPort, String messageExecutor) { + this.localHost = localHost; + this.listenPort = listenPort; + this.messageExecutor = messageExecutor; + } + + public String getLocalHost() { + return localHost; + } + + public void setLocalHost(String localHost) { + this.localHost = localHost; + } + + public void setListenPort(int listenPort) { + this.listenPort = listenPort; + } + + + public int getListenPort() { + return listenPort; + } + + public String getMessageExecutor() { + return messageExecutor; + } + + public void setMessageExecutor(String messageExecutor) { + this.messageExecutor = messageExecutor; + } + + public String sessionId() { + return Hex.encodeHexString((this.localHost + ":" + this.listenPort).getBytes()); + } + + /** + * 灏嗗璞★紙鎴栬呰鎺ユ敹鍒扮殑娑堟伅锛夎浆鎹负SessionMessage + * @param msg + * 鎺ユ敹鍒扮殑娑堟伅瀵硅薄 + * @return + * 鍙纭В鏋愬垯杩斿洖锛屽惁鍒欒繑鍥濶ULL + */ + public static SessionMessage toSessionMessage(Object msg) { + String msgString = msg.toString(); + try { + String[] msgArray = msgString.split("\\|"); + if (msgArray.length == 2 || msgArray.length == 3) { + String host = msgArray[0]; + int port = Integer.parseInt(msgArray[1]); + String msgExecutorClass = null; + if (msgArray.length == 3) { + msgExecutorClass = msgArray[2]; + } + return new SessionMessage(host, port, msgExecutorClass); + } + return null; + } catch (Exception e) { + return null; + } + } + + @Override + public String toTransfer() { + // 涓哄尯鍒簬TransferMessage鐨凧SON鏍煎紡锛岃澶勪娇鐢ㄥ瓧绗︿覆杩炴帴澶勭悊 + // 鏍煎紡锛歭ocalHost|port|class + if (this.messageExecutor == null) { + return this.localHost + "|" + this.listenPort; + } else { + return this.localHost + "|" + this.listenPort + "|" + this.messageExecutor; + } + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/TransferMessage.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/TransferMessage.java new file mode 100644 index 00000000..fb918295 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/TransferMessage.java @@ -0,0 +1,182 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.message.TransferMessage + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓婂崍11:00 + * Description: + */ +package com.jd.blockchain.stp.communication.message; + +import com.alibaba.fastjson.JSON; +import org.apache.commons.codec.binary.Base64; + +/** + * 搴曞眰浼犺緭鍗忚 + * + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + */ + +public class TransferMessage extends AbstractMessage implements IMessage{ + + /** + * sessionId锛堟弿杩拌妭鐐逛俊鎭級 + */ + private String sessionId; + + /** + * 鏈娑堟伅鐨勭被鍨 + * 0锛氳姹傦紱 + * 1锛氬簲绛旓紱 + */ + private int type; + + /** + * 娑堟伅鐨凨ey + */ + private String key; + + /** + * 娑堟伅杞戒綋鐨勫唴瀹 + * 鏈唴瀹逛笉鍙搴忓垪鍖 + */ + private transient byte[] load; + + /** + * 娑堟伅杞戒綋鐨勫唴瀹->Base64杞崲 + */ + private String loadBase64; + + public TransferMessage() { + } + + public TransferMessage(String sessionId, int type, String key, byte[] load) { + this.sessionId = sessionId; + this.type = type; + this.key = key; + this.load = load; + } + + /** + * 杞崲涓篢ransferMessage瀵硅薄 + * + * @param msg + * @return + */ + public static TransferMessage toTransferMessage(Object msg) { + if (msg == null) { + return null; + } + TransferMessage tm; + try { + tm = JSON.parseObject(msg.toString(), TransferMessage.class); + tm.initLoad(); + } catch (Exception e) { + return null; + } + return tm; + } + + public byte[] load() { + return load; + } + + public void initLoad() { + if (loadBase64 != null && loadBase64.length() > 0) { + load = Base64.decodeBase64(loadBase64); + } + } + + public void initLoadBase64() { + if (load != null && load.length > 0) { + loadBase64 = Base64.encodeBase64String(load); + } + } + + @Override + public String toTransfer() { + // 浣跨敤JSON鐨勬柟寮忓彂閫 + // 鍒濆鍖杔oad鐨刡ase64杞崲 + initLoadBase64(); + + // 灏嗗瓧绗︿覆杞崲涓篔SON + return JSON.toJSONString(this); + } + + /** + * 杞崲涓虹洃鍚殑Key + * 璇ey鍙弿杩颁负浠庤繙绔彂閫佹潵娑堟伅鍙婂叾鍐呭鐨勫敮涓鎬 + * + * @return + */ + public String toListenKey() { + return key; + } + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String loadKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + public String getLoadBase64() { + return loadBase64; + } + + public void setLoadBase64(String loadBase64) { + this.loadBase64 = loadBase64; + } + + public enum MESSAGE_TYPE { + + TYPE_REQUEST(0), + + TYPE_RESPONSE(1); + + private int code; + + MESSAGE_TYPE(int code) { + this.code = code; + } + + public int code() { + return code; + } + + public static MESSAGE_TYPE valueOf(int code) { + switch (code) { + case 0: + return TYPE_REQUEST; + case 1: + return TYPE_RESPONSE; + + } + return null; + } + + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/LocalNode.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/LocalNode.java new file mode 100644 index 00000000..60b9b11b --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/LocalNode.java @@ -0,0 +1,88 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.node.LocalNode + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/16 涓嬪崍3:12 + * Description: + */ +package com.jd.blockchain.stp.communication.node; + +import com.jd.blockchain.stp.communication.MessageExecutor; + +/** + * 鏈湴鑺傜偣 + * @author shaozhuguang + * @create 2019/4/16 + * @since 1.0.0 + * @date 2019-04-19 09:28 + */ + +public class LocalNode extends RemoteNode { + + /** + * 褰撳墠鑺傜偣娑堟伅澶勭悊鍣 + * 璇ユ秷鎭鐞嗗櫒鐢ㄤ簬鎻忚堪杩滅鑺傜偣鏀跺埌褰撳墠鑺傜偣鐨勬秷鎭濡備綍澶勭悊 + * 閫氬父璇ユ秷鎭鐞嗗櫒浼氫互瀛楃涓茬殑褰㈠紡鍙戦佽嚦杩滅鑺傜偣 + */ + private Class messageExecutorClass; + + /** + * 褰撳墠鑺傜偣鎺ユ敹娑堟伅榛樿澶勭悊鍣 + * 涓巑essageExecutor涓嶅悓锛岃瀛楁鎻忚堪鐨勬槸褰撳墠鑺傜偣鎺ユ敹鍒板叾浠栬妭鐐逛俊鎭椂鐨勯粯璁ゅ鐞嗗櫒 + * 璇ュ弬鏁扮‖鎬ц姹傚繀椤讳笉鑳戒负绌 + */ + private MessageExecutor defaultMessageExecutor; + + /** + * 鏋勯犲櫒 + * @param hostName + * 褰撳墠鑺傜偣Host锛岃Host蹇呴』鏄竴绉嶈繙绔妭鐐瑰彲璁块棶鐨勫舰寮 + * @param port + * 褰撳墠鑺傜偣鐩戝惉绔彛 + * @param defaultMessageExecutor + * 褰撳墠鑺傜偣鎺ユ敹鍒拌繙绔秷鎭棤娉曞鐞嗘椂鐨勬秷鎭鐞嗗櫒 + * + */ + public LocalNode(String hostName, int port, MessageExecutor defaultMessageExecutor) { + this(hostName, port, null, defaultMessageExecutor); + } + + /** + * 鏋勯犲櫒 + * @param hostName + * 褰撳墠鑺傜偣Host锛岃Host蹇呴』鏄竴绉嶈繙绔妭鐐瑰彲璁块棶鐨勫舰寮 + * @param port + * 褰撳墠鑺傜偣鐩戝惉绔彛 + * @param messageExecutorClass + * 褰撳墠鑺傜偣鏈熸湜杩滅鑺傜偣鎺ユ敹鍒版秷鎭悗鐨勫鐞嗗櫒 + * @param defaultMessageExecutor + * 褰撳墠鑺傜偣鎺ユ敹鍒拌繙绔秷鎭棤娉曞鐞嗘椂鐨勬秷鎭鐞嗗櫒 + * + */ + public LocalNode(String hostName, int port, Class messageExecutorClass, MessageExecutor defaultMessageExecutor) { + super(hostName, port); + this.messageExecutorClass = messageExecutorClass; + this.defaultMessageExecutor = defaultMessageExecutor; + } + + /** + * 杩斿洖娑堟伅鎵ц鍣ㄧ殑绫诲搴旂殑瀛楃涓 + * 璇ヨ繑鍥炲奸氬父鐢ㄤ簬娑堟伅浼犻 + * @return + */ + public String messageExecutorClass() { + if (this.messageExecutorClass == null) { + return null; + } + return this.messageExecutorClass.getName(); + } + + /** + * 杩斿洖榛樿鐨勬秷鎭鐞嗗櫒 + * @return + */ + public MessageExecutor defaultMessageExecutor() { + return this.defaultMessageExecutor; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/RemoteNode.java b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/RemoteNode.java new file mode 100644 index 00000000..89287380 --- /dev/null +++ b/source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/RemoteNode.java @@ -0,0 +1,79 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.stp.communication.RemoteNode + * Author: shaozhuguang + * Department: Jingdong Digits Technology + * Date: 2019/4/11 涓嬪崍3:40 + * Description: + */ +package com.jd.blockchain.stp.communication.node; + +/** + * 鑺傜偣淇℃伅 + * @author shaozhuguang + * @create 2019/4/11 + * @since 1.0.0 + * @date 2019-04-19 09:28 + */ + +public class RemoteNode { + + /** + * 鐩戝惉绔彛 + */ + private int port; + + /** + * 褰撳墠鑺傜偣鍩熷悕 + */ + private String hostName; + + public RemoteNode(String hostName, int port) { + this.port = port; + this.hostName = hostName; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + /** + * 閫氳繃hostName+port褰㈠紡浣滀负鍒ゆ柇鑺傜偣鐨勫敮涓鏍囪瘑 + * @return + */ + @Override + public int hashCode() { + return (hostName + ":" + port).hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj instanceof RemoteNode) { + RemoteNode other = (RemoteNode) obj; + if (this.hashCode() == other.hashCode()) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return this.hostName + ":" + this.port; + } +} \ No newline at end of file diff --git a/source/stp/stp-communication/src/test/java/com/jd/blockchain/SessionMessageTest.java b/source/stp/stp-communication/src/test/java/com/jd/blockchain/SessionMessageTest.java new file mode 100644 index 00000000..b3cee4ab --- /dev/null +++ b/source/stp/stp-communication/src/test/java/com/jd/blockchain/SessionMessageTest.java @@ -0,0 +1,37 @@ +/** + * Copyright: Copyright 2016-2020 JD.COM All Right Reserved + * FileName: com.jd.blockchain.SessionMessageTest + * Author: shaozhuguang + * Department: Y浜嬩笟閮 + * Date: 2019/4/17 涓嬪崍3:24 + * Description: + */ +package com.jd.blockchain; + +import com.jd.blockchain.stp.communication.message.SessionMessage; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * + * @author shaozhuguang + * @create 2019/4/17 + * @since 1.0.0 + */ + +public class SessionMessageTest { + + + @Test + public void test() { + SessionMessage message = new SessionMessage("127.0.0.1", 9001, "com.jd.blockchain.StpTest.StpMessageExecute"); + + String transMsg = message.toTransfer(); + System.out.println(transMsg); + + SessionMessage sm = SessionMessage.toSessionMessage(transMsg); + + assertEquals(transMsg, sm.toTransfer()); + } +} \ No newline at end of file diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/PresetAnswerPrompter.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/PresetAnswerPrompter.java index 152ee356..d6ccbc6a 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/PresetAnswerPrompter.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/PresetAnswerPrompter.java @@ -7,13 +7,13 @@ import com.jd.blockchain.tools.initializer.ConsolePrompter; public class PresetAnswerPrompter extends ConsolePrompter { private Properties answers = new Properties(); - + private String defaultAnswer; - + public PresetAnswerPrompter(String defaultAnswer) { this.defaultAnswer = defaultAnswer; } - + public void setAnswer(String tag, String answer) { answers.setProperty(tag, answer); } @@ -21,7 +21,7 @@ public class PresetAnswerPrompter extends ConsolePrompter { public void setDefaultAnswer(String defaultAnswer) { this.defaultAnswer = defaultAnswer; } - + @Override public String confirm(String tag, String format, Object... args) { System.out.print(String.format(format, args)); @@ -29,7 +29,5 @@ public class PresetAnswerPrompter extends ConsolePrompter { System.out.println(String.format("\r\n [Mocked answer:%s]", answer)); return answer; } - - } diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/consensus/ConsensusTest.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/consensus/ConsensusTest.java index bfb0a392..d7f66545 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/consensus/ConsensusTest.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/consensus/ConsensusTest.java @@ -215,26 +215,26 @@ public class ConsensusTest { DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri("memory://local/0"); LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); - AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps,csProvider, - testDb0, consolePrompter, bindingConfig0, quitLatch); + AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, + csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri("memory://local/1"); LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); - AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps,csProvider, - testDb1, consolePrompter, bindingConfig1, quitLatch); + AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps, + csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri("memory://local/2"); LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); - AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps,csProvider, - testDb2, consolePrompter, bindingConfig2, quitLatch); + AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps, + csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); DBConnectionConfig testDb3 = new DBConnectionConfig(); testDb3.setConnectionUri("memory://local/3"); LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); - AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps,csProvider, - testDb3, consolePrompter, bindingConfig3, quitLatch); + AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps, + csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); @@ -354,8 +354,8 @@ public class ConsensusTest { } public AsyncCallback startInit(PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, Prompter prompter, - CountDownLatch quitLatch) { + ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, + Prompter prompter, CountDownLatch quitLatch) { ThreadInvoker invoker = new ThreadInvoker() { @Override @@ -364,7 +364,7 @@ public class ConsensusTest { // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); NodeInitContext.this.dbConnConfig = dbConnConfig; - HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, csProps, csProvider, + HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, dbConnConfig, prompter); quitLatch.countDown(); @@ -386,8 +386,7 @@ public class ConsensusTest { @Override protected HashDigest invoke() throws Exception { LedgerInitCommand initCmd = new LedgerInitCommand(); - HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, - csProvider, dbConnConfig, prompter, conf, db); + HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, prompter, conf, db); NodeInitContext.this.ledgerManager = initCmd.getLedgerManager(); quitLatch.countDown(); return ledgerHash; diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/GlobalPerformanceTest.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/GlobalPerformanceTest.java index ee1ecf4e..a35584c0 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/GlobalPerformanceTest.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/GlobalPerformanceTest.java @@ -187,7 +187,7 @@ public class GlobalPerformanceTest { Properties props = Utils.loadConsensusSetting(); ConsensusProvider csProvider = getConsensusProvider(); ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); - + // 鍚姩鏈嶅姟鍣紱 NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); NodeInitContext nodeCtx0 = new NodeInitContext(0, initAddr0); @@ -365,8 +365,8 @@ public class GlobalPerformanceTest { // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); NodeInitContext.this.dbConnConfig = dbConnConfig; - HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, csProps, - csProvider, dbConnConfig, prompter); + HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, + dbConnConfig, prompter); quitLatch.countDown(); return ledgerHash; @@ -387,8 +387,8 @@ public class GlobalPerformanceTest { @Override protected HashDigest invoke() throws Exception { LedgerInitCommand initCmd = new LedgerInitCommand(); - HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, - csProvider, dbConnConfig, prompter, conf, db); + HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, + prompter, conf, db); NodeInitContext.this.ledgerManager = initCmd.getLedgerManager(); quitLatch.countDown(); return ledgerHash; diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeTest.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeTest.java index 9a5cbd36..dbd8b21b 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeTest.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeTest.java @@ -68,9 +68,6 @@ public class LedgerInitializeTest { public void testInitWith4Nodes() { Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); LedgerInitProperties initSetting = loadInitSetting(); - Properties props = loadConsensusSetting(); - ConsensusProvider csProvider = getConsensusProvider(); - ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), serviceRegisterMap); @@ -81,31 +78,28 @@ public class LedgerInitializeTest { NodeContext node3 = new NodeContext(initSetting.getConsensusParticipant(3).getInitializerAddress(), serviceRegisterMap); - String[] memoryConnString = new String[]{"memory://local/0", "memory://local/1", "memory://local/2", "memory://local/3"}; + String[] memoryConnString = new String[] { "memory://local/0", "memory://local/1", "memory://local/2", + "memory://local/3" }; PrivKey privkey0 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri(memoryConnString[0]); - AsyncCallback callback0 = node0.startInit(0, privkey0, initSetting, csProps, csProvider, testDb0, - consolePrompter); + AsyncCallback callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter); PrivKey privkey1 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri(memoryConnString[1]); - AsyncCallback callback1 = node1.startInit(1, privkey1, initSetting, csProps, csProvider, testDb1, - consolePrompter); + AsyncCallback callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter); PrivKey privkey2 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri(memoryConnString[2]); - AsyncCallback callback2 = node2.startInit(2, privkey2, initSetting, csProps, csProvider, testDb2, - consolePrompter); + AsyncCallback callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter); PrivKey privkey3 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); DBConnectionConfig testDb03 = new DBConnectionConfig(); testDb03.setConnectionUri(memoryConnString[3]); - AsyncCallback callback3 = node3.startInit(3, privkey3, initSetting, csProps, csProvider, testDb03, - consolePrompter); + AsyncCallback callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); @@ -188,23 +182,21 @@ public class LedgerInitializeTest { public NodeContext(NetworkAddress address, Map serviceRegisterMap) { this.initCsServiceFactory = new MultiThreadInterInvokerFactory(serviceRegisterMap); - LedgerInitializeWebController initController = new LedgerInitializeWebController(ledgerManager, memoryDBConnFactory, - initCsServiceFactory); + LedgerInitializeWebController initController = new LedgerInitializeWebController(ledgerManager, + memoryDBConnFactory, initCsServiceFactory); serviceRegisterMap.put(address, initController); this.initProcess = initController; } public AsyncCallback startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter) { + DBConnectionConfig dbConnConfig, Prompter prompter) { partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); ThreadInvoker invoker = new ThreadInvoker() { @Override protected HashDigest invoke() throws Exception { - return initProcess.initialize(currentId, privKey, setting, csProps, csProvider, dbConnConfig, - prompter); + return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); } }; @@ -212,8 +204,7 @@ public class LedgerInitializeTest { } public AsyncCallback startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter, boolean autoVerifyHash) { + DBConnectionConfig dbConnConfig, Prompter prompter, boolean autoVerifyHash) { CryptoConfig cryptoSetting = new CryptoConfig(); cryptoSetting.setAutoVerifyHash(autoVerifyHash); @@ -224,8 +215,7 @@ public class LedgerInitializeTest { ThreadInvoker invoker = new ThreadInvoker() { @Override protected HashDigest invoke() throws Exception { - return initProcess.initialize(currentId, privKey, setting, csProps, csProvider, dbConnConfig, - prompter, cryptoSetting); + return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); } }; diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeWebTest.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeWebTest.java index 2a72c515..fe0d8bbc 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeWebTest.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerInitializeWebTest.java @@ -264,23 +264,23 @@ public class LedgerInitializeWebTest { DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri("memory://local/0"); - AsyncCallback callback0 = node0.startInit(privkey0, initSetting, csProps, csProvider, testDb0, - consolePrompter, quitLatch); + AsyncCallback callback0 = node0.startInit(privkey0, initSetting, testDb0, consolePrompter, + quitLatch); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri("memory://local/1"); - AsyncCallback callback1 = node1.startInit(privkey1, initSetting, csProps, csProvider, testDb1, - consolePrompter, quitLatch); + AsyncCallback callback1 = node1.startInit(privkey1, initSetting, testDb1, consolePrompter, + quitLatch); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri("memory://local/2"); - AsyncCallback callback2 = node2.startInit(privkey2, initSetting, csProps, csProvider, testDb2, - consolePrompter, quitLatch); + AsyncCallback callback2 = node2.startInit(privkey2, initSetting, testDb2, consolePrompter, + quitLatch); DBConnectionConfig testDb03 = new DBConnectionConfig(); testDb03.setConnectionUri("memory://local/3"); - AsyncCallback callback3 = node3.startInit(privkey3, initSetting, csProps, csProvider, testDb03, - consolePrompter, quitLatch); + AsyncCallback callback3 = node3.startInit(privkey3, initSetting, testDb03, consolePrompter, + quitLatch); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); @@ -402,8 +402,7 @@ public class LedgerInitializeWebTest { } public AsyncCallback startInit(PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter, CountDownLatch quitLatch) { + DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { ThreadInvoker invoker = new ThreadInvoker() { @Override @@ -412,8 +411,8 @@ public class LedgerInitializeWebTest { // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); NodeWebContext.this.dbConnConfig = dbConnConfig; - HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, csProps, - csProvider, dbConnConfig, prompter); + HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, + dbConnConfig, prompter); quitLatch.countDown(); return ledgerHash; @@ -443,8 +442,8 @@ public class LedgerInitializeWebTest { @Override protected HashDigest invoke() throws Exception { LedgerInitCommand initCmd = new LedgerInitCommand(); - HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, - csProvider, dbConnConfig, prompter, conf, db); + HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, + prompter, conf, db); NodeWebContext.this.ledgerManager = initCmd.getLedgerManager(); quitLatch.countDown(); return ledgerHash; diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java index 7bd15006..33d494a3 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java @@ -106,16 +106,14 @@ public class Utils { } public AsyncCallback startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, - Prompter prompter) { + DBConnectionConfig dbConnConfig, Prompter prompter) { partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); ThreadInvoker invoker = new ThreadInvoker() { @Override protected HashDigest invoke() throws Exception { - return initProcess.initialize(currentId, privKey, setting, csProps, consensusProvider, dbConnConfig, - prompter); + return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); } }; @@ -150,8 +148,7 @@ public class Utils { ThreadInvoker invoker = new ThreadInvoker() { @Override protected HashDigest invoke() throws Exception { - return initProcess.initialize(currentId, privKey, setting, csProps, consensusProvider, dbConnConfig, - prompter, cryptoSetting); + return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); } }; diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBaseTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBaseTest.java index da0e82b8..0703ef98 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBaseTest.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBaseTest.java @@ -1,7 +1,16 @@ package test.com.jd.blockchain.intgr; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; + +import org.springframework.core.io.ClassPathResource; + import com.jd.blockchain.consensus.ConsensusProvider; -import com.jd.blockchain.consensus.ConsensusProviders; import com.jd.blockchain.consensus.ConsensusSettings; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.HashDigest; @@ -9,27 +18,21 @@ import com.jd.blockchain.crypto.PrivKey; import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.core.LedgerRepository; -import com.jd.blockchain.tools.initializer.*; +import com.jd.blockchain.tools.initializer.DBConnectionConfig; +import com.jd.blockchain.tools.initializer.LedgerBindingConfig; +import com.jd.blockchain.tools.initializer.LedgerInitProperties; +import com.jd.blockchain.tools.initializer.Prompter; import com.jd.blockchain.tools.keygen.KeyGenCommand; import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; import com.jd.blockchain.utils.net.NetworkAddress; -import org.springframework.core.io.ClassPathResource; import test.com.jd.blockchain.intgr.IntegratedContext.Node; import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; -import java.util.concurrent.CountDownLatch; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - public class IntegrationBaseTest { - LedgerInitConsensusConfig.ConsensusConfig bftsmartConfig = LedgerInitConsensusConfig.bftsmartConfig; + LedgerInitConsensusConfig.ConsensusConfig bftsmartConfig = LedgerInitConsensusConfig.bftsmartConfig; public IntegratedContext context = initLedgers(bftsmartConfig.getConfigPath(), bftsmartConfig.getProvider()); public GatewayTestRunner gateway0; @@ -150,26 +153,26 @@ public class IntegrationBaseTest { DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[0]); LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); - AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, - csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); + AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, testDb0, + consolePrompter, bindingConfig0, quitLatch); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[1]); LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); - AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps, - csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); + AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, testDb1, + consolePrompter, bindingConfig1, quitLatch); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[2]); LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); - AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps, - csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); + AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, testDb2, + consolePrompter, bindingConfig2, quitLatch); DBConnectionConfig testDb3 = new DBConnectionConfig(); testDb3.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[3]); LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); - AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps, - csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); + AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, + consolePrompter, bindingConfig3, quitLatch); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java index ec968e54..a6f2f30a 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java @@ -41,7 +41,6 @@ import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; import com.jd.blockchain.utils.net.NetworkAddress; import test.com.jd.blockchain.intgr.IntegratedContext.Node; -import test.com.jd.blockchain.intgr.contract.AssetContract; import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; @@ -51,14 +50,14 @@ import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsT public class IntegrationTest2 { // 鍚堢害娴嬭瘯浣跨敤鐨勫垵濮嬪寲鏁版嵁; BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate(); - private String contractZipName = "contract.jar"; + private String contractZipName = "AssetContract3.contract"; private String eventName = "issue-asset"; @Test public void test() { // init ledgers of all nodes ; IntegratedContext context = initLedgers(LedgerInitConsensusConfig.mqConfig, - LedgerInitConsensusConfig.memConnectionStrings); + LedgerInitConsensusConfig.memConnectionStrings); Node node0 = context.getNode(0); Node node1 = context.getNode(1); Node node2 = context.getNode(2); @@ -71,10 +70,10 @@ public class IntegrationTest2 { PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB()); NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 13220); - PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2,node2.getBindingConfig(), node2.getStorageDB()); + PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB()); NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 13230); - PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3,node3.getBindingConfig(), node3.getStorageDB()); + PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB()); AsyncCallback peerStarting0 = peer0.start(); AsyncCallback peerStarting1 = peer1.start(); @@ -193,26 +192,26 @@ public class IntegrationTest2 { DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri(dbConns[0]); LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); - AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, csProvider, - testDb0, consolePrompter, bindingConfig0, quitLatch); + AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, testDb0, + consolePrompter, bindingConfig0, quitLatch); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri(dbConns[1]); LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); - AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps,csProvider, - testDb1, consolePrompter, bindingConfig1, quitLatch); + AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, testDb1, + consolePrompter, bindingConfig1, quitLatch); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri(dbConns[2]); LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); - AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps,csProvider, - testDb2, consolePrompter, bindingConfig2, quitLatch); + AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, testDb2, + consolePrompter, bindingConfig2, quitLatch); DBConnectionConfig testDb3 = new DBConnectionConfig(); testDb3.setConnectionUri(dbConns[3]); LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); - AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps,csProvider, - testDb3, consolePrompter, bindingConfig3, quitLatch); + AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, + consolePrompter, bindingConfig3, quitLatch); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); @@ -287,7 +286,7 @@ public class IntegrationTest2 { } private void testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, - BlockchainService blockchainService, IntegratedContext context) { + BlockchainService blockchainService, IntegratedContext context) { BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); // 瀹氫箟浜ゆ槗锛 @@ -305,18 +304,18 @@ public class IntegrationTest2 { assertTrue(txResp.isSuccess()); // execute the contract; - testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); + testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); } private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, - BlockchainService blockchainService, IntegratedContext context) { + BlockchainService blockchainService, IntegratedContext context) { LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); - LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight()-1); + LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); // 瀹氫箟浜ゆ槗锛 TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - txTpl.contract(contractDeployKey.getAddress(), AssetContract.class).issue(10,"abc"); + txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, ("888##999##abc").getBytes()); // 绛惧悕锛 PreparedTransaction ptx = txTpl.prepare(); @@ -327,7 +326,6 @@ public class IntegrationTest2 { assertTrue(txResp.isSuccess()); } - /** * 鏍规嵁鍚堢害鏋勫缓瀛楄妭鏁扮粍; * diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java index bc16860c..5b1b5457 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java @@ -8,13 +8,11 @@ import java.io.InputStream; import java.util.Properties; import java.util.concurrent.CountDownLatch; -import com.jd.blockchain.storage.service.DbConnection; import org.junit.Test; import org.springframework.core.io.ClassPathResource; import com.alibaba.fastjson.JSON; import com.jd.blockchain.consensus.ConsensusProvider; -import com.jd.blockchain.consensus.ConsensusProviders; import com.jd.blockchain.consensus.ConsensusSettings; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.HashDigest; @@ -34,6 +32,7 @@ import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.ledger.core.impl.LedgerManager; import com.jd.blockchain.sdk.BlockchainService; import com.jd.blockchain.sdk.client.GatewayServiceFactory; +import com.jd.blockchain.storage.service.DbConnection; import com.jd.blockchain.tools.initializer.DBConnectionConfig; import com.jd.blockchain.tools.initializer.LedgerBindingConfig; import com.jd.blockchain.tools.initializer.LedgerInitProperties; @@ -50,7 +49,7 @@ import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsT public class IntegrationTestDataAccount { - LedgerInitConsensusConfig.ConsensusConfig config = LedgerInitConsensusConfig.mqConfig; + LedgerInitConsensusConfig.ConsensusConfig config = LedgerInitConsensusConfig.mqConfig; public IntegratedContext context = initLedgers(config, LedgerInitConsensusConfig.memConnectionStrings); public GatewayTestRunner gateway0; @@ -173,8 +172,8 @@ public class IntegrationTestDataAccount { } // 閫氳繃璋冪敤SDK->GATEWAY,娴嬭瘯涓涓尯鍧楀寘鍚涓氦鏄撴椂鐨勫啓鍏ユ儏鍐碉紝骞堕獙璇佸啓鍏ョ粨鏋滐紱 - private void testAddKvOpToDataAccount(GatewayTestRunner gateway, AsymmetricKeypair adminKey, IntegratedContext context, - Bytes dataAddr) { + private void testAddKvOpToDataAccount(GatewayTestRunner gateway, AsymmetricKeypair adminKey, + IntegratedContext context, Bytes dataAddr) { GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); BlockchainService blockchainService = gwsrvFact.getBlockchainService(); @@ -182,7 +181,8 @@ public class IntegrationTestDataAccount { LedgerManager ledgerManager = context.getNode(0).getLedgerManager(); - DbConnection memoryBasedDb = context.getNode(0).getStorageDB().connect(LedgerInitConsensusConfig.memConnectionStrings[0]); + DbConnection memoryBasedDb = context.getNode(0).getStorageDB() + .connect(LedgerInitConsensusConfig.memConnectionStrings[0]); LedgerRepository ledgerRepository = ledgerManager.register(ledgerHashs[0], memoryBasedDb.getStorageService()); @@ -288,26 +288,26 @@ public class IntegrationTestDataAccount { DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri(dbConns[0]); LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); - AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, - csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); + AsyncCallback callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, testDb0, + consolePrompter, bindingConfig0, quitLatch); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri(dbConns[1]); LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); - AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps, - csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); + AsyncCallback callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, testDb1, + consolePrompter, bindingConfig1, quitLatch); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri(dbConns[2]); LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); - AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps, - csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); + AsyncCallback callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, testDb2, + consolePrompter, bindingConfig2, quitLatch); DBConnectionConfig testDb3 = new DBConnectionConfig(); testDb3.setConnectionUri(dbConns[3]); LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); - AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps, - csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); + AsyncCallback callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, + consolePrompter, bindingConfig3, quitLatch); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitSettingTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitPropertiesTest.java similarity index 67% rename from source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitSettingTest.java rename to source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitPropertiesTest.java index f0100d9f..3f926073 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitSettingTest.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitPropertiesTest.java @@ -16,39 +16,44 @@ import com.jd.blockchain.tools.keygen.KeyGenCommand; import com.jd.blockchain.utils.codec.HexUtils; import test.com.jd.blockchain.intgr.IntegrationBase; -public class LedgerInitSettingTest { +public class LedgerInitPropertiesTest { @Test public void test() throws IOException { ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger.init"); InputStream in = ledgerInitSettingResource.getInputStream(); try { - LedgerInitProperties setting = LedgerInitProperties.resolve(in); - assertEquals(4, setting.getConsensusParticipantCount()); - String expectedLedgerSeed = "932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe".replace("-", ""); - String actualLedgerSeed = HexUtils.encode(setting.getLedgerSeed()); + LedgerInitProperties initProps = LedgerInitProperties.resolve(in); + assertEquals(4, initProps.getConsensusParticipantCount()); + String expectedLedgerSeed = "932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe" + .replace("-", ""); + String actualLedgerSeed = HexUtils.encode(initProps.getLedgerSeed()); assertEquals(expectedLedgerSeed, actualLedgerSeed); - - ConsensusParticipantConfig part0 = setting.getConsensusParticipant(0); + + assertEquals("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", + initProps.getConsensusProvider()); + + String[] cryptoProviders = initProps.getCryptoProviders(); + assertEquals(2, cryptoProviders.length); + assertEquals("com.jd.blockchain.crypto.service.classic.ClassicCryptoService", cryptoProviders[0]); + assertEquals("com.jd.blockchain.crypto.service.sm.SMCryptoService", cryptoProviders[1]); + + ConsensusParticipantConfig part0 = initProps.getConsensusParticipant(0); assertEquals("jd.com", part0.getName()); - assertEquals("keys/jd-com.pub", part0.getPubKeyPath()); PubKey pubKey0 = KeyGenCommand.decodePubKey("3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9"); assertEquals(pubKey0, part0.getPubKey()); -// assertEquals("127.0.0.1", part0.getConsensusAddress().getHost()); -// assertEquals(8900, part0.getConsensusAddress().getPort()); -// assertEquals(true, part0.getConsensusAddress().isSecure()); assertEquals("127.0.0.1", part0.getInitializerAddress().getHost()); assertEquals(8800, part0.getInitializerAddress().getPort()); assertEquals(true, part0.getInitializerAddress().isSecure()); - - ConsensusParticipantConfig part1 = setting.getConsensusParticipant(1); + + ConsensusParticipantConfig part1 = initProps.getConsensusParticipant(1); assertEquals(false, part1.getInitializerAddress().isSecure()); PubKey pubKey1 = KeyGenCommand.decodePubKey("3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX"); assertEquals(pubKey1, part1.getPubKey()); - - ConsensusParticipantConfig part2 = setting.getConsensusParticipant(2); - assertEquals(null, part2.getPubKey()); - + + ConsensusParticipantConfig part2 = initProps.getConsensusParticipant(2); + assertEquals("7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe", part2.getPubKey().toBase58()); + } finally { in.close(); } diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeTest.java index e96d3c18..09ddf134 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeTest.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeTest.java @@ -9,22 +9,22 @@ import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; -import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; import org.junit.Test; import org.springframework.core.io.ClassPathResource; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.consensus.ConsensusProvider; -import com.jd.blockchain.consensus.ConsensusProviders; import com.jd.blockchain.consensus.ConsensusSettings; import com.jd.blockchain.crypto.AddressEncoding; -import com.jd.blockchain.crypto.CryptoAlgorithm; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PrivKey; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.crypto.SignatureDigest; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInitOperation; import com.jd.blockchain.ledger.UserRegisterOperation; @@ -35,6 +35,7 @@ import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.ledger.core.UserAccount; import com.jd.blockchain.ledger.core.UserAccountSet; import com.jd.blockchain.ledger.core.impl.LedgerManager; +import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; import com.jd.blockchain.tools.initializer.DBConnectionConfig; import com.jd.blockchain.tools.initializer.LedgerInitProcess; import com.jd.blockchain.tools.initializer.LedgerInitProperties; @@ -60,6 +61,9 @@ public class LedgerInitializeTest { DataContractRegistry.register(UserRegisterOperation.class); } + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + public static final String PASSWORD = IntegrationBase.PASSWORD; public static final String[] PUB_KEYS = IntegrationBase.PUB_KEYS; @@ -85,8 +89,8 @@ public class LedgerInitializeTest { Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); LedgerInitProperties initSetting = loadInitSetting(); Properties props = loadConsensusSetting(config.getConfigPath()); - ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); - ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); +// ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); +// ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), serviceRegisterMap); @@ -100,26 +104,22 @@ public class LedgerInitializeTest { PrivKey privkey0 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri(dbConnections[0]); - AsyncCallback callback0 = node0.startInit(0, privkey0, initSetting, csProps, csProvider, testDb0, - consolePrompter); + AsyncCallback callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter); PrivKey privkey1 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri(dbConnections[1]); - AsyncCallback callback1 = node1.startInit(1, privkey1, initSetting, csProps, csProvider, testDb1, - consolePrompter); + AsyncCallback callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter); PrivKey privkey2 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri(dbConnections[2]); - AsyncCallback callback2 = node2.startInit(2, privkey2, initSetting, csProps, csProvider, testDb2, - consolePrompter); + AsyncCallback callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter); PrivKey privkey3 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); DBConnectionConfig testDb03 = new DBConnectionConfig(); testDb03.setConnectionUri(dbConnections[3]); - AsyncCallback callback3 = node3.startInit(3, privkey3, initSetting, csProps, csProvider, testDb03, - consolePrompter); + AsyncCallback callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); @@ -234,16 +234,14 @@ public class LedgerInitializeTest { } public AsyncCallback startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter) { + DBConnectionConfig dbConnConfig, Prompter prompter) { partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); ThreadInvoker invoker = new ThreadInvoker() { @Override protected HashDigest invoke() throws Exception { - return initProcess.initialize(currentId, privKey, setting, csProps, csProvider, dbConnConfig, - prompter); + return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); } }; @@ -251,10 +249,14 @@ public class LedgerInitializeTest { } public AsyncCallback startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter, boolean autoVerifyHash) { + DBConnectionConfig dbConnConfig, Prompter prompter, boolean autoVerifyHash) { + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } CryptoConfig cryptoSetting = new CryptoConfig(); + cryptoSetting.setSupportedProviders(supportedProviders); cryptoSetting.setAutoVerifyHash(autoVerifyHash); cryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); @@ -263,8 +265,7 @@ public class LedgerInitializeTest { ThreadInvoker invoker = new ThreadInvoker() { @Override protected HashDigest invoke() throws Exception { - return initProcess.initialize(currentId, privKey, setting, csProps, csProvider, dbConnConfig, - prompter, cryptoSetting); + return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); } }; diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4Nodes.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4Nodes.java index ec80dd18..ef18078f 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4Nodes.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4Nodes.java @@ -94,23 +94,23 @@ public class LedgerInitializeWeb4Nodes { DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri(dbConns[0]); - AsyncCallback callback0 = node0.startInit(privkey0, initSetting, csProps, csProvider, testDb0, - consolePrompter, quitLatch); + AsyncCallback callback0 = node0.startInit(privkey0, initSetting, testDb0, consolePrompter, + quitLatch); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri(dbConns[1]); - AsyncCallback callback1 = node1.startInit(privkey1, initSetting, csProps, csProvider, testDb1, - consolePrompter, quitLatch); + AsyncCallback callback1 = node1.startInit(privkey1, initSetting, testDb1, consolePrompter, + quitLatch); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri(dbConns[2]); - AsyncCallback callback2 = node2.startInit(privkey2, initSetting, csProps, csProvider, testDb2, - consolePrompter, quitLatch); + AsyncCallback callback2 = node2.startInit(privkey2, initSetting, testDb2, consolePrompter, + quitLatch); DBConnectionConfig testDb03 = new DBConnectionConfig(); testDb03.setConnectionUri(dbConns[3]); - AsyncCallback callback3 = node3.startInit(privkey3, initSetting, csProps, csProvider, testDb03, - consolePrompter, quitLatch); + AsyncCallback callback3 = node3.startInit(privkey3, initSetting, testDb03, consolePrompter, + quitLatch); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); @@ -230,8 +230,7 @@ public class LedgerInitializeWeb4Nodes { } public AsyncCallback startInit(PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter, CountDownLatch quitLatch) { + DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { ThreadInvoker invoker = new ThreadInvoker() { @Override @@ -239,8 +238,8 @@ public class LedgerInitializeWeb4Nodes { doStartServer(); NodeWebContext.this.dbConnConfig = dbConnConfig; - HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, csProps, - csProvider, dbConnConfig, prompter); + HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, + dbConnConfig, prompter); System.out.printf("ledgerHash = %s \r\n", ledgerHash.toBase58()); @@ -252,7 +251,6 @@ public class LedgerInitializeWeb4Nodes { return invoker.start(); } - public void doStartServer() { String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4SingleStepsTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4SingleStepsTest.java index bdc80ae4..3426b296 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4SingleStepsTest.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeWeb4SingleStepsTest.java @@ -340,8 +340,7 @@ public class LedgerInitializeWeb4SingleStepsTest { } public AsyncCallback startInit(PrivKey privKey, LedgerInitProperties setting, - ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter, CountDownLatch quitLatch) { + DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { ThreadInvoker invoker = new ThreadInvoker() { @Override @@ -350,8 +349,8 @@ public class LedgerInitializeWeb4SingleStepsTest { // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); NodeWebContext.this.dbConnConfig = dbConnConfig; - HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, csProps, - csProvider, dbConnConfig, prompter); + HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, + dbConnConfig, prompter); quitLatch.countDown(); return ledgerHash; @@ -362,9 +361,8 @@ public class LedgerInitializeWeb4SingleStepsTest { } public AsyncCallback startInitCommand(PrivKey privKey, String base58Pwd, - LedgerInitProperties ledgerSetting, ConsensusSettings csProps, ConsensusProvider csProvider, - DBConnectionConfig dbConnConfig, Prompter prompter, LedgerBindingConfig conf, - CountDownLatch quitLatch) { + LedgerInitProperties ledgerSetting, DBConnectionConfig dbConnConfig, Prompter prompter, + LedgerBindingConfig conf, CountDownLatch quitLatch) { this.db = new CompositeConnectionFactory(); this.dbConnConfig = dbConnConfig; @@ -372,8 +370,8 @@ public class LedgerInitializeWeb4SingleStepsTest { @Override protected HashDigest invoke() throws Exception { LedgerInitCommand initCmd = new LedgerInitCommand(); - HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, - csProvider, dbConnConfig, prompter, conf, db); + HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, + prompter, conf, db); NodeWebContext.this.ledgerManager = initCmd.getLedgerManager(); quitLatch.countDown(); return ledgerHash; diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java index c350f232..a97a26c4 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java @@ -141,41 +141,36 @@ public class LedgerBlockGeneratingTest { NodeContext node3 = new NodeContext(initSetting.getConsensusParticipant(3).getInitializerAddress(), serviceRegisterMap); - String[] memConns = new String[]{ - "memory://local/0", - "memory://local/1", - "memory://local/2", - "memory://local/3" - }; - + String[] memConns = new String[] { "memory://local/0", "memory://local/1", "memory://local/2", + "memory://local/3" }; PrivKey privkey0 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[0], LedgerInitializeTest.PASSWORD); DBConnectionConfig testDb0 = new DBConnectionConfig(); testDb0.setConnectionUri(memConns[0]); - AsyncCallback callback0 = node0.startInit(0, privkey0, initSetting, csProps, csProvider, testDb0, - consolePrompter, !optimized); + AsyncCallback callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter, + !optimized); PrivKey privkey1 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[1], LedgerInitializeTest.PASSWORD); DBConnectionConfig testDb1 = new DBConnectionConfig(); testDb1.setConnectionUri(memConns[1]); - AsyncCallback callback1 = node1.startInit(1, privkey1, initSetting, csProps, csProvider, testDb1, - consolePrompter, !optimized); + AsyncCallback callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter, + !optimized); PrivKey privkey2 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[2], LedgerInitializeTest.PASSWORD); DBConnectionConfig testDb2 = new DBConnectionConfig(); testDb2.setConnectionUri(memConns[2]); - AsyncCallback callback2 = node2.startInit(2, privkey2, initSetting, csProps, csProvider, testDb2, - consolePrompter, !optimized); + AsyncCallback callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter, + !optimized); PrivKey privkey3 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[3], LedgerInitializeTest.PASSWORD); DBConnectionConfig testDb03 = new DBConnectionConfig(); testDb03.setConnectionUri(memConns[3]); - AsyncCallback callback3 = node3.startInit(3, privkey3, initSetting, csProps, csProvider, testDb03, - consolePrompter, !optimized); + AsyncCallback callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter, + !optimized); HashDigest ledgerHash0 = callback0.waitReturn(); HashDigest ledgerHash1 = callback1.waitReturn(); diff --git a/source/test/test-integration/src/test/resources/keys/parti2.pub b/source/test/test-integration/src/test/resources/keys/parti2.pub new file mode 100644 index 00000000..dde44b8e --- /dev/null +++ b/source/test/test-integration/src/test/resources/keys/parti2.pub @@ -0,0 +1 @@ +3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x \ No newline at end of file diff --git a/source/test/test-integration/src/test/resources/ledger.init b/source/test/test-integration/src/test/resources/ledger.init index d25b002d..9df38d79 100644 --- a/source/test/test-integration/src/test/resources/ledger.init +++ b/source/test/test-integration/src/test/resources/ledger.init @@ -5,6 +5,18 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 #璐︽湰鐨勬弿杩板悕绉帮紱姝ゅ睘鎬т笉鍙備笌鍏辫瘑锛屼粎浠呭湪褰撳墠鍙備笌鏂圭殑鏈湴鑺傜偣鐢ㄤ簬鎻忚堪鐢ㄩ旓紱 ledger.name= + +#鍏辫瘑鏈嶅姟鎻愪緵鑰咃紱蹇呴』锛 +consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider + +#鍏辫瘑鏈嶅姟鐨勫弬鏁伴厤缃紱蹇呴』锛 +consensus.conf=classpath:bftsmart.config + +#瀵嗙爜鏈嶅姟鎻愪緵鑰呭垪琛紝浠ヨ嫳鏂囬楃偣鈥,鈥濆垎闅旓紱蹇呴』锛 +crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ +com.jd.blockchain.crypto.service.sm.SMCryptoService + + #鍙備笌鏂圭殑涓暟锛屽悗缁互 cons_parti.id 鍒嗗埆鏍囪瘑姣忎竴涓弬涓庢柟鐨勯厤缃紱 cons_parti.count=4 @@ -49,7 +61,7 @@ cons_parti.1.initializer.secure=false #绗2涓弬涓庢柟鐨勫悕绉帮紱 cons_parti.2.name=bt.com #绗2涓弬涓庢柟鐨勫叕閽ユ枃浠惰矾寰勶紱 -cons_parti.2.pubkey-path=keys/bt-com.pub +cons_parti.2.pubkey-path=classpath:keys/parti2.pub #绗2涓弬涓庢柟鐨勫叕閽ュ唴瀹癸紙鐢眐eygen宸ュ叿鐢熸垚锛夛紱姝ゅ弬鏁颁紭鍏堜簬 pubkey-path 鍙傛暟锛 cons_parti.2.pubkey= #绗2涓弬涓庢柟鐨勫叡璇嗘湇鍔$殑涓绘満鍦板潃锛 diff --git a/source/test/test-integration/src/test/resources/ledger_init_test.init b/source/test/test-integration/src/test/resources/ledger_init_test.init index 9c9959c2..518d88c1 100644 --- a/source/test/test-integration/src/test/resources/ledger_init_test.init +++ b/source/test/test-integration/src/test/resources/ledger_init_test.init @@ -5,6 +5,16 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 #璐︽湰鐨勬弿杩板悕绉帮紱姝ゅ睘鎬т笉鍙備笌鍏辫瘑锛屼粎浠呭湪褰撳墠鍙備笌鏂圭殑鏈湴鑺傜偣鐢ㄤ簬鎻忚堪鐢ㄩ旓紱 ledger.name= +#鍏辫瘑鏈嶅姟鎻愪緵鑰咃紱蹇呴』锛 +consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider + +#鍏辫瘑鏈嶅姟鐨勫弬鏁伴厤缃紱蹇呴』锛 +consensus.conf=classpath:bftsmart.config + +#瀵嗙爜鏈嶅姟鎻愪緵鑰呭垪琛紝浠ヨ嫳鏂囬楃偣鈥,鈥濆垎闅旓紱蹇呴』锛 +crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ +com.jd.blockchain.crypto.service.sm.SMCryptoService + #鍙備笌鏂圭殑涓暟锛屽悗缁互 cons_parti.id 鍒嗗埆鏍囪瘑姣忎竴涓弬涓庢柟鐨勯厤缃紱 cons_parti.count=4 diff --git a/source/test/test-integration/src/test/resources/ledger_init_test_web2.init b/source/test/test-integration/src/test/resources/ledger_init_test_web2.init index 849f223e..73626947 100644 --- a/source/test/test-integration/src/test/resources/ledger_init_test_web2.init +++ b/source/test/test-integration/src/test/resources/ledger_init_test_web2.init @@ -5,6 +5,17 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 #璐︽湰鐨勬弿杩板悕绉帮紱姝ゅ睘鎬т笉鍙備笌鍏辫瘑锛屼粎浠呭湪褰撳墠鍙備笌鏂圭殑鏈湴鑺傜偣鐢ㄤ簬鎻忚堪鐢ㄩ旓紱 #ledger.name= +#鍏辫瘑鏈嶅姟鎻愪緵鑰咃紱蹇呴』锛 +consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider + +#鍏辫瘑鏈嶅姟鐨勫弬鏁伴厤缃紱蹇呴』锛 +consensus.conf=classpath:bftsmart.config + +#瀵嗙爜鏈嶅姟鎻愪緵鑰呭垪琛紝浠ヨ嫳鏂囬楃偣鈥,鈥濆垎闅旓紱蹇呴』锛 +crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ +com.jd.blockchain.crypto.service.sm.SMCryptoService + + #鍙備笌鏂圭殑涓暟锛屽悗缁互 cons_parti.id 鍒嗗埆鏍囪瘑姣忎竴涓弬涓庢柟鐨勯厤缃紱 cons_parti.count=4 diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitCommand.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitCommand.java index f010164d..4947975a 100644 --- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitCommand.java +++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitCommand.java @@ -1,7 +1,6 @@ package com.jd.blockchain.tools.initializer; import java.io.File; -import java.util.Properties; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.boot.SpringApplication; @@ -11,9 +10,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import com.jd.blockchain.consensus.ConsensusProvider; -import com.jd.blockchain.consensus.ConsensusProviders; -import com.jd.blockchain.consensus.ConsensusSettings; import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PrivKey; @@ -23,7 +19,6 @@ import com.jd.blockchain.tools.initializer.LedgerBindingConfig.BindingConfig; import com.jd.blockchain.tools.initializer.LedgerInitProperties.ConsensusParticipantConfig; import com.jd.blockchain.tools.keygen.KeyGenCommand; import com.jd.blockchain.utils.ArgumentSet; -import com.jd.blockchain.utils.ConsoleUtils; import com.jd.blockchain.utils.ArgumentSet.ArgEntry; import com.jd.blockchain.utils.ArgumentSet.Setting; import com.jd.blockchain.utils.io.FileUtils; @@ -51,72 +46,68 @@ public class LedgerInitCommand { // 鏄惁杈撳嚭璋冭瘯淇℃伅锛 private static final String DEBUG_OPT = "-debug"; + private static final Prompter DEFAULT_PROMPTER = new ConsolePrompter(); + /** * 鍏ュ彛锛 * * @param args */ public static void main(String[] args) { + Prompter prompter = DEFAULT_PROMPTER; + Setting argSetting = ArgumentSet.setting().prefix(LOCAL_ARG, INI_ARG).option(DEBUG_OPT); ArgumentSet argset = ArgumentSet.resolve(args, argSetting); try { ArgEntry localArg = argset.getArg(LOCAL_ARG); if (localArg == null) { - ConsoleUtils.info("Miss local config file which can be specified with arg [%s]!!!", LOCAL_ARG); + prompter.info("Miss local config file which can be specified with arg [%s]!!!", LOCAL_ARG); } LocalConfig localConf = LocalConfig.resolve(localArg.getValue()); ArgEntry iniArg = argset.getArg(INI_ARG); if (iniArg == null) { - ConsoleUtils.info("Miss ledger initializing config file which can be specified with arg [%s]!!!", - INI_ARG); + prompter.info("Miss ledger initializing config file which can be specified with arg [%s]!!!", INI_ARG); return; } - // // load ledger init setting; - LedgerInitProperties ledgerInitSetting = LedgerInitProperties.resolve(iniArg.getValue()); + // load ledger init setting; + LedgerInitProperties ledgerInitProperties = LedgerInitProperties.resolve(iniArg.getValue()); String localNodePubKeyString = localConf.getLocal().getPubKeyString(); PubKey localNodePubKey = KeyGenCommand.decodePubKey(localNodePubKeyString); // 鍦板潃鏍规嵁鍏挜鐢熸垚 String localNodeAddress = AddressEncoding.generateAddress(localNodePubKey).toBase58(); - // load all pub keys; + // 鍔犺浇鍏ㄩ儴鍏挜; int currId = -1; - for (int i = 0; i < ledgerInitSetting.getConsensusParticipantCount(); i++) { - ConsensusParticipantConfig pconf = ledgerInitSetting.getConsensusParticipant(i); - String currPartAddress = pconf.getAddress(); - if (currPartAddress == null) { - if (pconf.getPubKeyPath() != null) { - PubKey pubKey = KeyGenCommand.readPubKey(pconf.getPubKeyPath()); - pconf.setPubKey(pubKey); - currPartAddress = pconf.getAddress(); - } - } - if (localNodeAddress.equals(currPartAddress)) { + for (int i = 0; i < ledgerInitProperties.getConsensusParticipantCount(); i++) { + ConsensusParticipantConfig partiConf = ledgerInitProperties.getConsensusParticipant(i); +// String partiAddress = partiConf.getAddress(); +// if (partiAddress == null) { +// if (partiConf.getPubKeyPath() != null) { +// PubKey pubKey = KeyGenCommand.readPubKey(partiConf.getPubKeyPath()); +// partiConf.setPubKey(pubKey); +// partiAddress = partiConf.getAddress(); +// } +// } + if (localNodeAddress.equals(partiConf.getAddress())) { currId = i; } } if (currId == -1) { - throw new IllegalStateException("The current node specified in local.conf is not found in ledger.init!"); + throw new IllegalStateException( + "The current node specified in local.conf is not found in ledger.init!"); } + // 鍔犺浇褰撳墠鑺傜偣鐨勭閽ワ紱 String base58Pwd = localConf.getLocal().getPassword(); if (base58Pwd == null) { base58Pwd = KeyGenCommand.readPasswordString(); } PrivKey privKey = KeyGenCommand.decodePrivKey(localConf.getLocal().getPrivKeyString(), base58Pwd); - // Load consensus properties; - Properties props = FileUtils.readProperties(localConf.getConsensusConfig()); - ConsensusProvider csProvider = ConsensusProviders.getProvider(localConf.getConsensusProvider()); - ConsensusSettings csSettings = csProvider.getSettingsFactory().getConsensusSettingsBuilder() - .createSettings(props); - - - // ConsensusProperties csProps = new ConsensusProperties(props); - // Output ledger binding config of peer; if (!FileUtils.existDirectory(localConf.getBindingOutDir())) { FileUtils.makeDirectory(localConf.getBindingOutDir()); @@ -131,27 +122,26 @@ public class LedgerInitCommand { // 鍚姩鍒濆鍖栵紱 LedgerInitCommand initCommand = new LedgerInitCommand(); - HashDigest newLedgerHash = initCommand.startInit(currId, privKey, base58Pwd, ledgerInitSetting, csSettings, csProvider, - localConf.getStoragedDb(), new ConsolePrompter(), conf); + HashDigest newLedgerHash = initCommand.startInit(currId, privKey, base58Pwd, ledgerInitProperties, + localConf.getStoragedDb(), prompter, conf); if (newLedgerHash != null) { // success; // so save ledger binding config to file system; conf.store(ledgerBindingFile); - ConsoleUtils.info("\r\n------ Update Ledger binding configuration success! ------[%s]", + prompter.info("\r\n------ Update Ledger binding configuration success! ------[%s]", ledgerBindingFile.getAbsolutePath()); } - // ConsoleUtils.confirm("\r\n\r\n Press any key to quit. :>"); - } catch (Exception e) { - ConsoleUtils.error("\r\nError!! -- %s\r\n", e.getMessage()); + prompter.error("\r\nError!! -- %s\r\n", e.getMessage()); if (argset.hasOption(DEBUG_OPT)) { e.printStackTrace(); } - ConsoleUtils.error("\r\n Ledger init process has been broken by error!"); + prompter.error("\r\n Ledger init process has been broken by error!"); } + prompter.confirm(InitializingStep.LEDGER_INIT_COMPLETED.toString(), "\r\n\r\n Press any key to quit. :>"); } @@ -164,20 +154,19 @@ public class LedgerInitCommand { public LedgerInitCommand() { } - public HashDigest startInit(int currId, PrivKey privKey, String base58Pwd, LedgerInitProperties ledgerSetting, - ConsensusSettings csSettings, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter, LedgerBindingConfig conf, Object... extBeans) { - if (currId < 0 || currId >= ledgerSetting.getConsensusParticipantCount()) { - ConsoleUtils.info( + public HashDigest startInit(int currId, PrivKey privKey, String base58Pwd, + LedgerInitProperties ledgerInitProperties, DBConnectionConfig dbConnConfig, Prompter prompter, + LedgerBindingConfig conf, Object... extBeans) { + if (currId < 0 || currId >= ledgerInitProperties.getConsensusParticipantCount()) { + prompter.info( "Your participant id is illegal which is less than 1 or great than the total participants count[%s]!!!", - ledgerSetting.getConsensusParticipantCount()); + ledgerInitProperties.getConsensusParticipantCount()); return null; } // generate binding config; BindingConfig bindingConf = new BindingConfig(); - // bindingConf.setCsConfigFile(localConf.getConsensusConfig()); - bindingConf.getParticipant().setAddress(ledgerSetting.getConsensusParticipant(currId).getAddress()); + bindingConf.getParticipant().setAddress(ledgerInitProperties.getConsensusParticipant(currId).getAddress()); String encodedPrivKey = KeyGenCommand.encodePrivKey(privKey, base58Pwd); bindingConf.getParticipant().setPk(encodedPrivKey); bindingConf.getParticipant().setPassword(base58Pwd); @@ -185,16 +174,13 @@ public class LedgerInitCommand { bindingConf.getDbConnection().setConnectionUri(dbConnConfig.getUri()); bindingConf.getDbConnection().setPassword(dbConnConfig.getPassword()); - // bindingConf.getMqConnection().setServer(mqConnConfig.getServer()); - // bindingConf.getMqConnection().setTopic(mqConnConfig.getTopic()); - // confirm continue锛 prompter.info("\r\n\r\n This is participant [%s], the ledger initialization is ready to start!\r\n", currId); - // ConsoleUtils.confirm("Press any key to continue... "); - // prompter.confirm("Press any key to continue... "); +// ConsoleUtils.confirm("Press any key to continue... "); +// prompter.confirm("Press any key to continue... "); - // start web listener; - NetworkAddress serverAddress = ledgerSetting.getConsensusParticipant(currId).getInitializerAddress(); + // start the web controller of Ledger Initializer; + NetworkAddress serverAddress = ledgerInitProperties.getConsensusParticipant(currId).getInitializerAddress(); String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); String[] innerArgs = { argServerAddress, argServerPort }; @@ -211,21 +197,21 @@ public class LedgerInitCommand { ConfigurableApplicationContext ctx = app.run(innerArgs); this.ledgerManager = ctx.getBean(LedgerManager.class); - prompter.info("\r\n------ Web listener[%s:%s] was started. ------\r\n", serverAddress.getHost(), - serverAddress.getPort()); + prompter.info("\r\n------ Web controller of Ledger Initializer[%s:%s] was started. ------\r\n", + serverAddress.getHost(), serverAddress.getPort()); try { LedgerInitProcess initProc = ctx.getBean(LedgerInitProcess.class); - HashDigest ledgerHash = initProc.initialize(currId, privKey, ledgerSetting, csSettings, csProvider, + HashDigest ledgerHash = initProc.initialize(currId, privKey, ledgerInitProperties, bindingConf.getDbConnection(), prompter); if (ledgerHash == null) { // ledger init fail; - ConsoleUtils.error("\r\n------ Ledger initialize fail! ------\r\n"); + prompter.error("\r\n------ Ledger initialize fail! ------\r\n"); return null; } else { - ConsoleUtils.info("\r\n------ Ledger initialize success! ------"); - ConsoleUtils.info("New Ledger Hash is :[%s]", ledgerHash.toBase58()); + prompter.info("\r\n------ Ledger initialize success! ------"); + prompter.info("New Ledger Hash is :[%s]", ledgerHash.toBase58()); if (conf == null) { conf = new LedgerBindingConfig(); @@ -237,7 +223,7 @@ public class LedgerInitCommand { } } finally { ctx.close(); - ConsoleUtils.info("\r\n------ Web listener[%s:%s] was closed. ------\r\n", serverAddress.getHost(), + prompter.info("\r\n------ Web listener[%s:%s] was closed. ------\r\n", serverAddress.getHost(), serverAddress.getPort()); } } diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProcess.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProcess.java index 1e19232d..ee1b1692 100644 --- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProcess.java +++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProcess.java @@ -17,44 +17,26 @@ public interface LedgerInitProcess { /** * Init a new ledger; * - * @param currentId - * @param privKey - * @param ledgerInitProps - * 璐︽湰鍒濆鍖栭厤缃睘鎬э紱 - * @param consensusSettings - * 鍏辫瘑閰嶇疆灞炴э紱 - * @param consensusServiceProvider - * @param prompter - * @return 杩斿洖鏂拌处鏈殑 hash锛涘鏋滄湭鍒濆鍖栨垚鍔燂紝鍒欒繑鍥 null锛 - */ - /** - * Init a new ledger; - * @param currentId Id of current participant; - * @param privKey Private key of current participant; - * @param ledgerInitProps The settings about this initialization; - * @param consensusSettings The consensus settings - * @param consensusProvider - * @param dbConnConfig - * @param prompter + * @param currentId Id of current participant. + * @param privKey Private key of current participant. + * @param ledgerInitProps The settings about this initialization. + * @param dbConnConfig The configuration of DB Connection. + * @param prompter Prompter for interaction. * @return */ HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, - ConsensusSettings consensusSettings, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, Prompter prompter); /** * @param currentId * @param privKey * @param ledgerInitProps - * @param consensusSettings - * @param consensusProvider * @param dbConnConfig * @param prompter * @param cryptoSetting * @return */ HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, - ConsensusSettings consensusSettings, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, Prompter prompter, CryptoSetting cryptoSetting); } diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java index 805315f9..2ee028b2 100644 --- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java +++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java @@ -1,23 +1,23 @@ package com.jd.blockchain.tools.initializer; -import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileNotFoundException; -import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Properties; +import org.springframework.util.ResourceUtils; + import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.tools.keygen.KeyGenCommand; +import com.jd.blockchain.utils.PropertiesUtils; import com.jd.blockchain.utils.codec.HexUtils; import com.jd.blockchain.utils.io.FileUtils; import com.jd.blockchain.utils.net.NetworkAddress; -import org.springframework.core.io.ClassPathResource; - public class LedgerInitProperties { // 璐︽湰绉嶅瓙锛 @@ -32,12 +32,7 @@ public class LedgerInitProperties { public static final String PART_PUBKEY_PATH = "pubkey-path"; // 鍙備笌鏂圭殑鍏挜鏂囦欢璺緞锛 public static final String PART_PUBKEY = "pubkey"; - // //鍏辫瘑鍙備笌鏂圭殑鍏辫瘑鏈嶅姟鐨勪富鏈哄湴鍧锛 - // public static final String PART_CONSENSUS_HOST = "consensus.host"; - // // 鍏辫瘑鍙備笌鏂圭殑鍏辫瘑鏈嶅姟鐨勭鍙o紱 - // public static final String PART_CONSENSUS_PORT = "consensus.port"; - // // 鍏辫瘑鍙備笌鏂圭殑鍏辫瘑鏈嶅姟鏄惁寮鍚畨鍏ㄨ繛鎺ワ紱 - // public static final String PART_CONSENSUS_SECURE = "consensus.secure"; + // 鍏辫瘑鍙備笌鏂圭殑璐︽湰鍒濆鏈嶅姟鐨勪富鏈猴紱 public static final String PART_INITIALIZER_HOST = "initializer.host"; // 鍏辫瘑鍙備笌鏂圭殑璐︽湰鍒濆鏈嶅姟鐨勭鍙o紱 @@ -45,70 +40,37 @@ public class LedgerInitProperties { // 鍏辫瘑鍙備笌鏂圭殑璐︽湰鍒濆鏈嶅姟鏄惁寮鍚畨鍏ㄨ繛鎺ワ紱 public static final String PART_INITIALIZER_SECURE = "initializer.secure"; + // 鍏辫瘑鏈嶅姟鐨勫弬鏁伴厤缃紱蹇呴』锛 + public static final String CONSENSUS_CONFIG = "consensus.conf"; + + // 鍏辫瘑鏈嶅姟鎻愪緵鑰咃紱蹇呴』锛 + public static final String CONSENSUS_SERVICE_PROVIDER = "consensus.service-provider"; + + // 瀵嗙爜鏈嶅姟鎻愪緵鑰呭垪琛紝浠ヨ嫳鏂囬楃偣鈥,鈥濆垎闅旓紱蹇呴』锛 + public static final String CRYPTO_SERVICE_PROVIDERS = "crypto.service-providers"; + + public static final String CRYPTO_SERVICE_PROVIDERS_SPLITTER = ","; + private byte[] ledgerSeed; private List consensusParticipants = new ArrayList<>(); + private String consensusProvider; + + private Properties consensusConfig; + + private String[] cryptoProviders; + public byte[] getLedgerSeed() { - return ledgerSeed; + return ledgerSeed.clone(); } - public static byte[] getHostSettingValue() throws Exception { - ClassPathResource hostConfigResource = new ClassPathResource("hosts.config"); - InputStream fis = hostConfigResource.getInputStream(); - ByteArrayOutputStream bos = null; - byte[] buffer = null; - try { - bos = new ByteArrayOutputStream(1000); - byte[] b = new byte[1000]; - int n; - while ((n = fis.read(b)) != -1) { - bos.write(b, 0, n); - } - // host file to bytes - buffer = bos.toByteArray(); - } catch (FileNotFoundException e) { - throw new Exception(e.getMessage(), e); - } catch (IOException e) { - throw new Exception(e.getMessage(), e); - } finally { - if (fis != null) { - fis.close(); - } - if (bos != null) { - bos.close(); - } - } - return buffer; + public Properties getConsensusConfig() { + return consensusConfig; } - public static byte[] getSystemSettingValue() throws Exception { - ClassPathResource systemConfigResource = new ClassPathResource("bftsmart.config"); - InputStream fis = systemConfigResource.getInputStream(); - ByteArrayOutputStream bos = null; - byte[] buffer = null; - try { - bos = new ByteArrayOutputStream(1000); - byte[] b = new byte[1000]; - int n; - while ((n = fis.read(b)) != -1) { - bos.write(b, 0, n); - } - // file to bytes - buffer = bos.toByteArray(); - } catch (FileNotFoundException e) { - throw new Exception(e.getMessage(), e); - } catch (IOException e) { - throw new Exception(e.getMessage(), e); - } finally { - if (fis != null) { - fis.close(); - } - if (bos != null) { - bos.close(); - } - } - return buffer; + public String getConsensusProvider() { + return consensusProvider; } public int getConsensusParticipantCount() { @@ -118,21 +80,24 @@ public class LedgerInitProperties { public List getConsensusParticipants() { return consensusParticipants; } - - public ConsensusParticipantConfig[] getConsensusParticipantArray() { - return consensusParticipants.toArray(new ConsensusParticipantConfig[consensusParticipants.size()]); + + public String[] getCryptoProviders() { + return cryptoProviders.clone(); + } + + public void setCryptoProviders(String[] cryptoProviders) { + this.cryptoProviders = cryptoProviders; } /** * 杩斿洖鍙備笌鑰咃紱 * - * @param address - * 浠 1 寮濮嬶紱 灏忎簬绛変簬 {@link #getConsensusParticipantCount()}; + * @param address 浠 1 寮濮嬶紱 灏忎簬绛変簬 {@link #getConsensusParticipantCount()}; * @return */ public ConsensusParticipantConfig getConsensusParticipant(int id) { for (ConsensusParticipantConfig p : consensusParticipants) { - if (p.getId()== id) { + if (p.getId() == id) { return p; } } @@ -163,11 +128,31 @@ public class LedgerInitProperties { } private static LedgerInitProperties resolve(Properties props) { - String hexLedgerSeed = getProperty(props, LEDGER_SEED).replace("-", ""); + String hexLedgerSeed = PropertiesUtils.getRequiredProperty(props, LEDGER_SEED).replace("-", ""); byte[] ledgerSeed = HexUtils.decode(hexLedgerSeed); - LedgerInitProperties setting = new LedgerInitProperties(ledgerSeed); + LedgerInitProperties initProps = new LedgerInitProperties(ledgerSeed); + + // 瑙f瀽鍏辫瘑鐩稿叧鐨勫睘鎬э紱 + initProps.consensusProvider = PropertiesUtils.getRequiredProperty(props, CONSENSUS_SERVICE_PROVIDER); + String consensusConfigFilePath = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONFIG); + try { + File consensusConfigFile = ResourceUtils.getFile(consensusConfigFilePath); + initProps.consensusConfig = FileUtils.readProperties(consensusConfigFile); + } catch (FileNotFoundException e) { + throw new IllegalArgumentException( + String.format("Consensus config file[%s] doesn't exist! ", consensusConfigFilePath), e); + } - int partCount = getInt(getProperty(props, PART_COUNT)); + // 瑙f瀽瀵嗙爜鎻愪緵鑰呭垪琛紱 + String cryptoProviderNames = PropertiesUtils.getProperty(props, CRYPTO_SERVICE_PROVIDERS, true); + String[] cryptoProviders = cryptoProviderNames.split(CRYPTO_SERVICE_PROVIDERS_SPLITTER); + for (int i = 0; i < cryptoProviders.length; i++) { + cryptoProviders[i] = cryptoProviders[i].trim(); + } + initProps.cryptoProviders = cryptoProviders; + + // 瑙f瀽鍙備笌鏂硅妭鐐瑰垪琛紱 + int partCount = getInt(PropertiesUtils.getRequiredProperty(props, PART_COUNT)); if (partCount < 0) { throw new IllegalArgumentException(String.format("Property[%s] is negative!", PART_COUNT)); } @@ -180,62 +165,40 @@ public class LedgerInitProperties { parti.setId(i); String nameKey = getKeyOfCsParti(i, PART_NAME); - parti.setName(getProperty(props, nameKey)); + parti.setName(PropertiesUtils.getRequiredProperty(props, nameKey)); String pubkeyPathKey = getKeyOfCsParti(i, PART_PUBKEY_PATH); - parti.setPubKeyPath(getProperty(props, pubkeyPathKey)); + String pubkeyPath = PropertiesUtils.getProperty(props, pubkeyPathKey, false); String pubkeyKey = getKeyOfCsParti(i, PART_PUBKEY); - String base58PubKey = getProperty(props, pubkeyKey); + String base58PubKey = PropertiesUtils.getProperty(props, pubkeyKey, false); if (base58PubKey != null) { PubKey pubKey = KeyGenCommand.decodePubKey(base58PubKey); parti.setPubKey(pubKey); + } else if (pubkeyPath != null) { + PubKey pubKey = KeyGenCommand.readPubKey(pubkeyPath); + parti.setPubKey(pubKey); + } else { + throw new IllegalArgumentException( + String.format("Property[%s] and property[%s] are all empty!", pubkeyKey, pubkeyPathKey)); } - // String consensusHostKey = getKeyOfCsParti(i, PART_CONSENSUS_HOST); - // String consensusHost = getProperty(props, consensusHostKey); - // - // String consensusPortKey = getKeyOfCsParti(i, PART_CONSENSUS_PORT); - // int consensusPort = getInt(getProperty(props, consensusPortKey)); - // - // String consensusSecureKey = getKeyOfCsParti(i, PART_CONSENSUS_SECURE); - // boolean consensusSecure = Boolean.parseBoolean(getProperty(props, - // consensusSecureKey)); - // NetworkAddress consensusAddress = new NetworkAddress(consensusHost, - // consensusPort, consensusSecure); - // parti.setConsensusAddress(consensusAddress); - String initializerHostKey = getKeyOfCsParti(i, PART_INITIALIZER_HOST); - String initializerHost = getProperty(props, initializerHostKey); + String initializerHost = PropertiesUtils.getRequiredProperty(props, initializerHostKey); String initializerPortKey = getKeyOfCsParti(i, PART_INITIALIZER_PORT); - int initializerPort = getInt(getProperty(props, initializerPortKey)); + int initializerPort = getInt(PropertiesUtils.getRequiredProperty(props, initializerPortKey)); String initializerSecureKey = getKeyOfCsParti(i, PART_INITIALIZER_SECURE); - boolean initializerSecure = Boolean.parseBoolean(getProperty(props, initializerSecureKey)); + boolean initializerSecure = Boolean + .parseBoolean(PropertiesUtils.getRequiredProperty(props, initializerSecureKey)); NetworkAddress initializerAddress = new NetworkAddress(initializerHost, initializerPort, initializerSecure); parti.setInitializerAddress(initializerAddress); - setting.addConsensusParticipant(parti); + initProps.addConsensusParticipant(parti); } - return setting; - } - - private static String getProperty(Properties props, String key) { - return getProperty(props, key, true); - } - - private static String getProperty(Properties props, String key, boolean required) { - String value = props.getProperty(key); - if (value == null) { - if (required) { - throw new IllegalArgumentException("Miss property[" + key + "]!"); - } - return null; - } - value = value.trim(); - return value.length() == 0 ? null : value; + return initProps; } private static int getInt(String strInt) { @@ -249,14 +212,14 @@ public class LedgerInitProperties { * */ public static class ConsensusParticipantConfig implements ParticipantNode { - + private int id; - + private String address; private String name; - private String pubKeyPath; +// private String pubKeyPath; private PubKey pubKey; @@ -271,7 +234,7 @@ public class LedgerInitProperties { public void setId(int id) { this.id = id; } - + @Override public String getAddress() { return address; @@ -285,13 +248,13 @@ public class LedgerInitProperties { this.name = name; } - public String getPubKeyPath() { - return pubKeyPath; - } - - public void setPubKeyPath(String pubKeyPath) { - this.pubKeyPath = pubKeyPath; - } +// public String getPubKeyPath() { +// return pubKeyPath; +// } +// +// public void setPubKeyPath(String pubKeyPath) { +// this.pubKeyPath = pubKeyPath; +// } public NetworkAddress getInitializerAddress() { return initializerAddress; diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LocalConfig.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LocalConfig.java index 8696263c..c3ad268e 100644 --- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LocalConfig.java +++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LocalConfig.java @@ -2,8 +2,6 @@ package com.jd.blockchain.tools.initializer; import java.io.File; import java.io.InputStream; -import java.net.URI; -import java.nio.file.Path; import java.util.Properties; import com.jd.blockchain.utils.PathUtils; @@ -30,17 +28,11 @@ public class LocalConfig { // 璐︽湰鏁版嵁搴撶殑杩炴帴鍙d护锛 public static final String LEDGER_DB_PWD = "ledger.db.pwd"; - // 璐︽湰娑堟伅闃熷垪鐨勫湴鍧 -// public static final String LEDGER_MQ_SERVER = "ledger.mq.server"; -// -// // 璐︽湰娑堟伅闃熷垪鐨勪富棰 -// public static final String LEDGER_MQ_TOPIC = "ledger.mq.topic"; - - // 鍏辫瘑绯荤粺鐨勫弬鏁伴厤缃紱蹇呴』鍙傛暟锛 - public static final String CONSENSUS_CONF = "consensus.conf"; - - // 鍏辫瘑绯荤粺鐨勫弬鏁伴厤缃紱蹇呴』鍙傛暟锛 - public static final String CONSENSUS_SERVICE_PROVIDER = "consensus.service-provider"; +// // 鍏辫瘑绯荤粺鐨勫弬鏁伴厤缃紱蹇呴』鍙傛暟锛 +// public static final String CONSENSUS_CONF = "consensus.conf"; +// +// // 鍏辫瘑绯荤粺鐨勫弬鏁伴厤缃紱蹇呴』鍙傛暟锛 +// public static final String CONSENSUS_SERVICE_PROVIDER = "consensus.service-provider"; private LocalParticipantConfig local = new LocalParticipantConfig(); @@ -48,10 +40,9 @@ public class LocalConfig { private DBConnectionConfig storagedDb = new DBConnectionConfig(); -// private MQConnectionConfig handleMq = new MQConnectionConfig(); - private String consensusConfig; - private String consensusProvider; +// private String consensusConfig; +// private String consensusProvider; public LocalParticipantConfig getLocal() { return local; @@ -77,22 +68,6 @@ public class LocalConfig { this.storagedDb = storagedDb; } -// public MQConnectionConfig getHandleMq() { -// return handleMq; -// } -// -// public void setHandleMq(MQConnectionConfig handleMq) { -// this.handleMq = handleMq; -// } - - public String getConsensusConfig() { - return consensusConfig; - } - - public void setConsensusConfig(String consensusConfig) { - this.consensusConfig = consensusConfig; - } - public static LocalConfig resolve(String initSettingFile) { Properties props = FileUtils.readProperties(initSettingFile, "UTF-8"); return resolve(props, initSettingFile); @@ -118,17 +93,12 @@ public class LocalConfig { if (initSettingFile == null) { conf.bindingOutDir = PropertiesUtils.getRequiredProperty(props, LEDGER_BINDING_OUT); - conf.consensusConfig = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONF); } else { String bindingOutDir = PropertiesUtils.getRequiredProperty(props, LEDGER_BINDING_OUT); - String consensusConfig = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONF); String initSettingDir = PathUtils.concatPaths(initSettingFile, "../"); conf.bindingOutDir = absolutePath(initSettingDir, bindingOutDir); - conf.consensusConfig = absolutePath(initSettingDir, consensusConfig); } - conf.consensusProvider = PropertiesUtils.getRequiredProperty(props, CONSENSUS_SERVICE_PROVIDER); - return conf; } @@ -141,18 +111,6 @@ public class LocalConfig { return absolutePath; } - private static int getInt(String strInt) { - return Integer.parseInt(strInt.trim()); - } - - public String getConsensusProvider() { - return consensusProvider; - } - - public void setConsensusProvider(String consensusProvider) { - this.consensusProvider = consensusProvider; - } - /** * 褰撳墠鍙備笌鏂圭殑鏈湴閰嶇疆淇℃伅锛 * @@ -192,12 +150,4 @@ public class LocalConfig { } - public static void main(String[] args) { - String currPath = "/Users/zhanglin33/Ddisk/20mintest/0/config/init/local.conf"; -// String settingPath = "../"; - String settingPath = "bftsmart.config"; - String path = absolutePath(PathUtils.concatPaths(currPath, "../"), settingPath); - System.out.println(path); - - } } diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/Prompter.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/Prompter.java index 663a2c46..b1f589dd 100644 --- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/Prompter.java +++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/Prompter.java @@ -2,6 +2,28 @@ package com.jd.blockchain.tools.initializer; public interface Prompter { + //瀹氫箟涓浜涘父鐢ㄧ殑闂瓟甯搁噺锛 + + /** + * 璇㈤棶鏄垨鍚︼紱 + */ + public static final String QUESTION_YESNO = "YES/NO"; + + /** + * 鎻愮ず鎸変换鎰忛敭缁х画锛 + */ + public static final String PROMPT_ANYKEY_TO_CONTINUE = "ANYKEY"; + + /** + * + */ + public static final String ANSWER_YES = "Y"; + + public static final String ANSWER_NO = "N"; + + + + void info(String format, Object... args); void error(String format, Object... args); diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java index 42e1d5d6..4c9af288 100644 --- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java +++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; +import java.util.Properties; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -18,14 +19,17 @@ import org.springframework.web.bind.annotation.RestController; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.consensus.ConsensusProvider; +import com.jd.blockchain.consensus.ConsensusProviders; import com.jd.blockchain.consensus.ConsensusSettings; -import com.jd.blockchain.crypto.CryptoAlgorithm; import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PrivKey; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.crypto.SignatureDigest; import com.jd.blockchain.crypto.SignatureFunction; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.BlockchainIdentityData; import com.jd.blockchain.ledger.CryptoSetting; @@ -53,11 +57,11 @@ import com.jd.blockchain.tools.initializer.LedgerInitException; import com.jd.blockchain.tools.initializer.LedgerInitProcess; import com.jd.blockchain.tools.initializer.LedgerInitProperties; import com.jd.blockchain.tools.initializer.LedgerInitProperties.ConsensusParticipantConfig; +import com.jd.blockchain.tools.initializer.Prompter; import com.jd.blockchain.transaction.DigitalSignatureBlob; import com.jd.blockchain.transaction.LedgerInitSettingData; import com.jd.blockchain.transaction.TxBuilder; import com.jd.blockchain.transaction.TxRequestBuilder; -import com.jd.blockchain.tools.initializer.Prompter; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.concurrent.InvocationResult; import com.jd.blockchain.utils.io.BytesUtils; @@ -76,8 +80,11 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI DataContractRegistry.register(TransactionRequest.class); } + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + private static final String DEFAULT_SIGN_ALGORITHM = "ED25519"; - + private final SignatureFunction SIGN_FUNC; private volatile LedgerInitPermission localPermission; @@ -122,7 +129,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI public LedgerInitializeWebController(LedgerManage ledgerManager, DbConnectionFactory dbConnFactory, InitConsensusServiceFactory initCsServiceFactory) { this.SIGN_FUNC = Crypto.getSignatureFunction(DEFAULT_SIGN_ALGORITHM); - + this.ledgerManager = ledgerManager; this.dbConnFactory = dbConnFactory; this.initCsServiceFactory = initCsServiceFactory; @@ -148,36 +155,39 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI this.prompter = prompter; } - public ConsensusProvider getConsensusProvider() { - return consensusProvider; - } +// private ConsensusProvider getConsensusProvider() { +// return consensusProvider; +// } - public void setConsensusProvider(ConsensusProvider consensusProvider) { + private void setConsensusProvider(ConsensusProvider consensusProvider) { this.consensusProvider = consensusProvider; } @Override public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, - ConsensusSettings csSettings, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter) { - return initialize(currentId, privKey, ledgerInitProps, csSettings, csProvider, dbConnConfig, prompter, - createDefaultCryptoSetting()); + DBConnectionConfig dbConnConfig, Prompter prompter) { + return initialize(currentId, privKey, ledgerInitProps, dbConnConfig, prompter, createDefaultCryptoSetting()); } @Override public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, - ConsensusSettings consensusProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, - Prompter prompter, CryptoSetting cryptoSetting) { + DBConnectionConfig dbConnConfig, Prompter prompter, CryptoSetting cryptoSetting) { if (this.ledgerInitSetting != null) { throw new IllegalStateException("ledger init process has already started."); } setPrompter(prompter); + + Properties csProps = ledgerInitProps.getConsensusConfig(); + ConsensusProvider csProvider = ConsensusProviders.getProvider(ledgerInitProps.getConsensusProvider()); + ConsensusSettings csSettings = csProvider.getSettingsFactory().getConsensusSettingsBuilder() + .createSettings(csProps); setConsensusProvider(csProvider); + prompter.info("Init settings and sign permision..."); - prepareLocalPermission(currentId, privKey, ledgerInitProps, consensusProps, cryptoSetting); + prepareLocalPermission(currentId, privKey, ledgerInitProps, csSettings, cryptoSetting); prompter.confirm(InitializingStep.PERMISSION_READY.toString(), "Ledger init permission has already prepared! Any key to continue..."); @@ -230,7 +240,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI this.decisions[i] = new DecisionResultHandle(i); } // 棰勭疆褰撳墠鍙備笌鏂圭殑鈥滃喅瀹氣濆埌鍒楄〃锛岄伩鍏嶅悜鑷繁鍙戣捣璇锋眰锛 - this.decisions[currentId].setResult(localDecision); + this.decisions[currentId].setValue(localDecision); return localDecision; } @@ -299,7 +309,12 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI } public CryptoSetting createDefaultCryptoSetting() { + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; + for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { + supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); + } CryptoConfig defCryptoSetting = new CryptoConfig(); + defCryptoSetting.setSupportedProviders(supportedProviders); defCryptoSetting.setAutoVerifyHash(true); defCryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); @@ -318,7 +333,9 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI LedgerInitSettingData initSetting = new LedgerInitSettingData(); initSetting.setLedgerSeed(ledgerProps.getLedgerSeed()); initSetting.setCryptoSetting(cryptoSetting); - ConsensusParticipantConfig[] parties = ledgerProps.getConsensusParticipantArray(); + + List partiList = ledgerProps.getConsensusParticipants(); + ConsensusParticipantConfig[] parties = partiList.toArray(new ConsensusParticipantConfig[partiList.size()]); ConsensusParticipantConfig[] orderedParties = sortAndVerify(parties); initSetting.setConsensusParticipants(orderedParties); @@ -447,7 +464,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI List waitingIds = new ArrayList<>(); for (int i = 0; i < results.length; i++) { if (results[i] != null) { - if (results[i].getResult() == null) { + if (results[i].getValue() == null) { waitingIds.add("" + (i + 1)); } } @@ -474,7 +491,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI continue; } PubKey pubKey = participants[i].getPubKey(); - LedgerInitPermission permission = (LedgerInitPermission) results[i].getResult(); + LedgerInitPermission permission = (LedgerInitPermission) results[i].getValue(); if (permission.getParticipantId() != participants[i].getId()) { prompter.error("\r\nThe id of received permission isn't equal to it's participant ! --[Id=%s][name=%s]", participants[i].getAddress(), participants[i].getName()); @@ -525,7 +542,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI public void run() { try { LedgerInitPermission permission = initConsensus.requestPermission(currentId, reqAuthSign); - result.setResult(permission); + result.setValue(permission); } catch (Exception e) { result.setError(e); } finally { @@ -595,7 +612,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI while (!allDecided) { allDecided = true; for (int i = 0; i < randDecHdls.length; i++) { - if (randDecHdls[i].getResult() != null) { + if (randDecHdls[i].getValue() != null) { // 蹇界暐褰撳墠鍙備笌鏂硅嚜宸(鍦ㄥ垵濮嬪寲鈥滃喅瀹氣濇椂宸茬粡缃负闈炵┖)锛屼互鍙婂凡缁忔敹鍒颁富鍔ㄦ彁浜も滃喅瀹氣濈殑鍙備笌鏂; continue; } @@ -636,10 +653,11 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI try { targetDecision = initConsensus.synchronizeDecision(localDecision); } catch (Exception e1) { - prompter.info("Error occurred on synchronizing decision . --%s", e1.getMessage()); + prompter.info("Error occurred on synchronizing decision . --[%s] %s", e1.getClass().getName(), + e1.getMessage()); } if (targetDecision == null) { - if (resultHandle.getResult() != null) { + if (resultHandle.getValue() != null) { // 宸茬粡楠岃瘉杩囷紱 return true; } @@ -666,7 +684,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI } } while (targetDecision == null); - if (targetDecision.getParticipantId() != targetId && resultHandle.getResult() == null) { + if (targetDecision.getParticipantId() != targetId && resultHandle.getValue() == null) { prompter.error( "The received id of participant isn't equal to id of request target participant! --[Id=%s]", targetId); @@ -684,7 +702,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI /** * 鏍¢獙骞惰褰曟寚瀹氱殑鍙備笌鏂瑰仛鍑虹殑鍐冲畾锛 *

- * 娉細瀵 {@link DecisionResultHandle#setResult(LedgerInitDecision)} + * 娉細瀵 {@link DecisionResultHandle#setValue(LedgerInitDecision)} * 鏂规硶鐨勮皟鐢ㄤ笉鏄嚎绋嬪畨鍏ㄧ殑锛屼絾鐢变簬鏄湪婊¤冻鏈夋晥鎬ф牎楠屼箣鍚庢墠璋冪敤锛屽叿鏈夊箓绛夋э紝鎵浠ヤ笉蹇呭璇ユ柟娉曠殑澶氬璋冪敤杩涜鍚屾锛 * * @param targetDecision @@ -695,7 +713,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI private synchronized boolean validateAndRecordDecision(LedgerInitDecision targetDecision, DecisionResultHandle resultHandle) { if ((!localDecision.getLedgerHash().equals(targetDecision.getLedgerHash())) - && resultHandle.getResult() == null) { + && resultHandle.getValue() == null) { // 濡傛灉缁撴灉宸茬粡琚 prompter.error( "The received ledger hash of participant isn't equal to ledger hash of current participant! --[Id=%s]", @@ -708,13 +726,13 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI .getPubKey(); byte[] deciBytes = getDecisionBytes(targetDecision.getParticipantId(), targetDecision.getLedgerHash()); if ((!SIGN_FUNC.verify(targetDecision.getSignature(), targetPubKey, deciBytes)) - && resultHandle.getResult() == null) { + && resultHandle.getValue() == null) { prompter.error("The signature of received decision is invalid! --[Id=%s]", targetDecision.getParticipantId()); return false; } - resultHandle.setResult(targetDecision); + resultHandle.setValue(targetDecision); return true; } @@ -723,20 +741,38 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI public LedgerInitDecision synchronizeDecision(@RequestBody LedgerInitDecision initDecision) { int remoteId = initDecision.getParticipantId(); if (remoteId == currentId) { + prompter.error("Reject decision because of self-synchronization! --[Id=%s]", remoteId); throw new LedgerInitException( String.format("Reject decision because of self-synchronization! --[Id=%s]", remoteId)); } + if (this.genesisBlock == null) { // 褰撳墠鍙備笌鑰呭皻鏈噯澶囧氨缁,杩斿洖 null锛 + prompter.info("Not ready for genesis block! --[RemoteId=%s][CurrentId=%s]", remoteId, currentId); return null; } - DecisionResultHandle resultHandle = this.decisions[remoteId]; - if (!validateAndRecordDecision(initDecision, resultHandle)) { - // 绛惧悕鏃犳晥锛 + + prompter.info("Received request of synchronizing decision! --[RemoteId=%s][CurrentId=%s]", remoteId, currentId); + + try { + + DecisionResultHandle resultHandle = this.decisions[remoteId]; + if (!validateAndRecordDecision(initDecision, resultHandle)) { + // 绛惧悕鏃犳晥锛 + prompter.error("Reject decision because of invalid signature! --[RemoteId=%s][CurrentId=%s]", remoteId, + currentId); + throw new LedgerInitException( + String.format("Reject decision because of invalid signature! --[RemoteId=%s][CurrentId=%s]", + remoteId, currentId)); + } + return localDecision; + } catch (Exception e) { + prompter.error(e, + "Error occurred while receiving the request of synchronizing decision! --[RemoteId=%s][CurrentId=%s] %s", + remoteId, currentId, e.getMessage()); throw new LedgerInitException( - String.format("Reject decision because of invalid signature! --[Id=%s]", remoteId)); + "Error occurred while receiving the request of synchronizing decision! --" + e.getMessage(), e); } - return localDecision; } /** diff --git a/source/tools/tools-initializer/src/main/resources/local.conf b/source/tools/tools-initializer/src/main/resources/local.conf index 9df0303c..dc7c7347 100644 --- a/source/tools/tools-initializer/src/main/resources/local.conf +++ b/source/tools/tools-initializer/src/main/resources/local.conf @@ -16,10 +16,3 @@ ledger.db.uri=redis://127.0.0.1/0 #璐︽湰鏁版嵁搴撶殑杩炴帴鍙d护锛 ledger.db.pwd= - -#鍏辫瘑鍗忚鐨勫弬鏁伴厤缃紱蹇呴』鍙傛暟锛 -consensus.conf=mq.config - -#鍏辫瘑鍗忚鐨勫疄鐜扮被鍨嬶紱蹇呴』鍙傛暟锛 -consensus.service-provider=com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider - diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java index bb04964e..c787a014 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java @@ -1,14 +1,7 @@ package com.jd.blockchain.utils; import java.lang.reflect.Array; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; +import java.util.*; /** * @author haiq @@ -83,5 +76,4 @@ public abstract class ArrayUtils { } return new ReadonlyArrayListWrapper(array, fromIndex, toIndex); } - } diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/PropertiesUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/PropertiesUtils.java index ec6f5da9..994272b0 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/PropertiesUtils.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/PropertiesUtils.java @@ -37,9 +37,10 @@ public abstract class PropertiesUtils { /** * 鍒涘缓閰嶇疆瀵硅薄鐨勫疄渚嬶紝骞朵笖浠庢寚瀹氱殑灞炴ц〃涓垵濮嬪寲瀵瑰簲鐨勫疄渚嬪瓧娈碉紱 + * * @param configClass configClass - * @param properties properties - * @param T + * @param properties properties + * @param T * @return T */ @SuppressWarnings("unchecked") @@ -56,13 +57,10 @@ public abstract class PropertiesUtils { /** * 鍒涘缓閰嶇疆瀵硅薄鐨勫疄渚嬶紝骞朵笖浠庢寚瀹氱殑灞炴ц〃涓垵濮嬪寲瀵瑰簲鐨勫疄渚嬪瓧娈碉紱 * - * @param configClass - * 閰嶇疆瀵硅薄鐨勭被鍨嬶紱 - * @param properties - * 灞炴ц〃锛 - * @param propsPrefix - * 鍦ㄥ睘鎬ц〃涓笌閰嶇疆瀵硅薄鐩稿叧鐨勫睘鎬х殑key鐨勫墠缂锛 - * @param T + * @param configClass 閰嶇疆瀵硅薄鐨勭被鍨嬶紱 + * @param properties 灞炴ц〃锛 + * @param propsPrefix 鍦ㄥ睘鎬ц〃涓笌閰嶇疆瀵硅薄鐩稿叧鐨勫睘鎬х殑key鐨勫墠缂锛 + * @param T * @return T */ public static T createInstance(Class configClass, Properties properties, String propsPrefix) { @@ -77,12 +75,9 @@ public abstract class PropertiesUtils { /** * 璁剧疆閰嶇疆鍊硷紱 * - * @param obj - * 閰嶇疆瀵硅薄锛涢厤缃煎皢璁剧疆鍒版瀵硅薄鍖归厤鐨勫睘鎬э紱 - * @param configValues - * 閰嶇疆鍊硷紱 - * @param propPrefix - * 鑷姩鍔犲叆鐨勫睘鎬у墠缂锛 + * @param obj 閰嶇疆瀵硅薄锛涢厤缃煎皢璁剧疆鍒版瀵硅薄鍖归厤鐨勫睘鎬э紱 + * @param configValues 閰嶇疆鍊硷紱 + * @param propPrefix 鑷姩鍔犲叆鐨勫睘鎬у墠缂锛 */ public static void setValues(Object obj, Properties configValues, String propPrefix) { Properties values = new Properties(); @@ -93,10 +88,8 @@ public abstract class PropertiesUtils { /** * 璁剧疆閰嶇疆鍊硷紱 * - * @param obj - * 閰嶇疆瀵硅薄锛涢厤缃煎皢璁剧疆鍒版瀵硅薄鍖归厤鐨勫睘鎬э紱 - * @param configValues - * 閰嶇疆鍊硷紱 + * @param obj 閰嶇疆瀵硅薄锛涢厤缃煎皢璁剧疆鍒版瀵硅薄鍖归厤鐨勫睘鎬э紱 + * @param configValues 閰嶇疆鍊硷紱 */ public static void setValues(Object obj, Properties configValues) { BeanWrapper confBean = new BeanWrapperImpl(obj); @@ -109,13 +102,10 @@ public abstract class PropertiesUtils { /** * 浠庢寚瀹氱殑璺緞鍔犺浇閰嶇疆锛 * - * @param configClass - * 閰嶇疆瀵硅薄鐨勭被鍨嬶紱 - * @param configFilePathPattern - * properties閰嶇疆鏂囦欢鐨勮矾寰勶紱鍙互鎸囧畾 spring 璧勬簮璺緞琛ㄨ揪寮忥紱 - * @param charset - * 瀛楃闆嗭紱 - * @param class + * @param configClass 閰嶇疆瀵硅薄鐨勭被鍨嬶紱 + * @param configFilePathPattern properties閰嶇疆鏂囦欢鐨勮矾寰勶紱鍙互鎸囧畾 spring 璧勬簮璺緞琛ㄨ揪寮忥紱 + * @param charset 瀛楃闆嗭紱 + * @param class * @return T * @throws IOException exception */ @@ -127,12 +117,9 @@ public abstract class PropertiesUtils { /** * 浠庢寚瀹氱殑璺緞鍔犺浇閰嶇疆锛 * - * @param obj - * 閰嶇疆瀵硅薄锛涢厤缃枃浠剁殑鍊煎皢璁剧疆鍒版瀵硅薄鍖归厤鐨勫睘鎬э紱 - * @param configFilePathPattern - * properties閰嶇疆鏂囦欢鐨勮矾寰勶紱鍙互鎸囧畾 spring 璧勬簮璺緞琛ㄨ揪寮忥紱 - * @param charset - * 瀛楃闆嗭紱 + * @param obj 閰嶇疆瀵硅薄锛涢厤缃枃浠剁殑鍊煎皢璁剧疆鍒版瀵硅薄鍖归厤鐨勫睘鎬э紱 + * @param configFilePathPattern properties閰嶇疆鏂囦欢鐨勮矾寰勶紱鍙互鎸囧畾 spring 璧勬簮璺緞琛ㄨ揪寮忥紱 + * @param charset 瀛楃闆嗭紱 * @throws IOException exception */ public static void load(Object obj, String configFilePathPattern, String charset) throws IOException { @@ -180,10 +167,8 @@ public abstract class PropertiesUtils { /** * 鍚堝苟涓や釜 properties 锛 * - * @param props - * 瑕佸皢鍏跺畠鍊煎悎骞惰繘鏉ョ殑灞炴ч泦鍚堬紱鎿嶄綔灏嗗鍏朵骇鐢熶慨鏀癸紱 - * @param from - * 灞炴у煎皢瑕佸悎骞惰繘鍏ュ叾瀹冨睘鎬ч泦鍚堬紱鎿嶄綔涓嶅鍏朵骇鐢熶慨鏀癸紱 + * @param props 瑕佸皢鍏跺畠鍊煎悎骞惰繘鏉ョ殑灞炴ч泦鍚堬紱鎿嶄綔灏嗗鍏朵骇鐢熶慨鏀癸紱 + * @param from 灞炴у煎皢瑕佸悎骞惰繘鍏ュ叾瀹冨睘鎬ч泦鍚堬紱鎿嶄綔涓嶅鍏朵骇鐢熶慨鏀癸紱 */ public static void mergeFrom(Properties props, Properties from) { mergeFrom(props, from, null); @@ -192,12 +177,9 @@ public abstract class PropertiesUtils { /** * 鍚堝苟涓や釜 properties 锛 * - * @param props - * 瑕佸皢鍏跺畠鍊煎悎骞惰繘鏉ョ殑灞炴ч泦鍚堬紱鎿嶄綔灏嗗鍏朵骇鐢熶慨鏀癸紱 - * @param from - * 灞炴у煎皢瑕佸悎骞惰繘鍏ュ叾瀹冨睘鎬ч泦鍚堬紱鎿嶄綔涓嶅鍏朵骇鐢熶慨鏀癸紱 - * @param propertyNamePrefix - * 灞炴у悕绉板墠缂锛 + * @param props 瑕佸皢鍏跺畠鍊煎悎骞惰繘鏉ョ殑灞炴ч泦鍚堬紱鎿嶄綔灏嗗鍏朵骇鐢熶慨鏀癸紱 + * @param from 灞炴у煎皢瑕佸悎骞惰繘鍏ュ叾瀹冨睘鎬ч泦鍚堬紱鎿嶄綔涓嶅鍏朵骇鐢熶慨鏀癸紱 + * @param propertyNamePrefix 灞炴у悕绉板墠缂锛 */ public static void mergeFrom(Properties props, Properties from, String propertyNamePrefix) { if (propertyNamePrefix == null || propertyNamePrefix.length() == 0) { @@ -214,12 +196,9 @@ public abstract class PropertiesUtils { /** * 鑾峰彇鎸囧畾 properties 涓互鎸囧畾鐨勫墠缂寮澶寸殑瀛愰泦锛 * - * @param props - * 瑕佹娊鍙栫殑灞炴ч泦鍚堬紱 - * @param propertyNamePrefix - * 灞炴у悕绉板墠缂锛 - * @param trimPrefix - * 鏄惁鍦ㄥ鍒剁殑鏂扮殑灞炴ч泦鍚堝幓鎺夋寚瀹氱殑鍓嶇紑锛 + * @param props 瑕佹娊鍙栫殑灞炴ч泦鍚堬紱 + * @param propertyNamePrefix 灞炴у悕绉板墠缂锛 + * @param trimPrefix 鏄惁鍦ㄥ鍒剁殑鏂扮殑灞炴ч泦鍚堝幓鎺夋寚瀹氱殑鍓嶇紑锛 * @return properties */ public static Properties subset(Properties props, String propertyNamePrefix, boolean trimPrefix) { @@ -278,13 +257,22 @@ public abstract class PropertiesUtils { * 濡傛灉涓嶅瓨鍦紝鎴栬呰繑鍥炲间负绌猴紙null 鎴 绌虹櫧瀛楃锛夛紝鍒欐姏鍑 {@link IllegalArgumentException} 寮傚父锛 * * @param props props - * @param key key + * @param key key * @return String */ public static String getRequiredProperty(Properties props, String key) { return getProperty(props, key, true); } + /** + * 杩斿洖鎸囧畾鐨勫睘鎬э紱
+ * + * @param props 灞炴ц〃锛 + * @param key 瑕佹煡鎵剧殑 key锛 + * @param required 鍊间负 false 鏃讹紝濡傛灉涓嶅瓨鍦ㄥ垯杩斿洖 null锛涘间负 true 鏃讹紝濡傛灉涓嶅瓨鍦紝鎴栬呰繑鍥炲间负绌猴紙null 鎴 + * 绌虹櫧瀛楃锛夛紝鍒欐姏鍑 {@link IllegalArgumentException} 寮傚父锛 + * @return + */ public static String getProperty(Properties props, String key, boolean required) { String value = props.getProperty(key); if (value == null) { @@ -319,7 +307,7 @@ public abstract class PropertiesUtils { setValues(props, propValues); return props; } - + public static Properties setValues(Properties props, Property[] propValues) { for (Property p : propValues) { props.setProperty(p.getName(), p.getValue()); diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/StringUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/StringUtils.java new file mode 100644 index 00000000..5ae1a856 --- /dev/null +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/StringUtils.java @@ -0,0 +1,24 @@ +package com.jd.blockchain.utils; + +import java.util.regex.Pattern; + +/** + * @Author zhaogw + * date 2018/11/26 20:46 + */ +public class StringUtils { + public static boolean isEmpty(Object str) { + return str == null || "".equals(str); + } + + /* + * 鍒ゆ柇鏄惁涓烘暣鏁 + * @param str 浼犲叆鐨勫瓧绗︿覆 + * @return 鏄暣鏁拌繑鍥瀟rue,鍚﹀垯杩斿洖false + */ + + public static boolean isNumber(String str) { + Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); + return pattern.matcher(str).matches(); + } +} \ No newline at end of file diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/concurrent/InvocationResult.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/concurrent/InvocationResult.java index 84533ba7..27a7e68f 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/concurrent/InvocationResult.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/concurrent/InvocationResult.java @@ -2,16 +2,16 @@ package com.jd.blockchain.utils.concurrent; public class InvocationResult { - private volatile T result; + private volatile T value; private volatile Exception error; - public T getResult() { - return result; + public T getValue() { + return value; } - public void setResult(T result) { - this.result = result; + public void setValue(T value) { + this.value = value; } public Exception getError() { diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java index e5ba84f9..77cfca01 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java @@ -1,9 +1,23 @@ package com.jd.blockchain.utils.io; -import java.io.*; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; import java.util.ArrayList; import java.util.Properties; +import org.springframework.util.ResourceUtils; + /** * @author haiq * @@ -41,7 +55,7 @@ public class FileUtils { throw new IllegalStateException(e.getMessage(), e); } } - + /** * 杩斿洖鐖剁洰褰曠殑璺緞锛 * @@ -67,9 +81,8 @@ public class FileUtils { /** * 璇诲彇鎸囧畾鏂囦欢鐨勯琛岋紱 * - * @param file file - * @param charset - * 瀛楃闆嗭紱 + * @param file file + * @param charset 瀛楃闆嗭紱 * @return 杩斿洖棣栬闈炵┖琛岋紱杩斿洖缁撴灉涓嶄細鑷姩鎴彇涓ゅご鐨勭┖瀛楃涓诧紱 * @throws IOException exception */ @@ -90,9 +103,8 @@ public class FileUtils { /** * 杩斿洖鎸囧畾鏂囦欢鐨勬墍鏈夎锛 * - * @param file file - * @param charset - * 瀛楃闆嗭紱 + * @param file file + * @param charset 瀛楃闆嗭紱 * @return 杩斿洖棣栬闈炵┖琛岋紱杩斿洖缁撴灉涓嶄細鑷姩鎴彇涓ゅご鐨勭┖瀛楃涓诧紱 */ public static String[] readLines(File file, String charset) { @@ -155,10 +167,8 @@ public class FileUtils { /** * 浠ラ粯璁ゅ瓧绗﹂泦锛圲TF-8锛夊皢鎸囧畾鐨勬枃鏈繚瀛樺埌鎸囧畾鐨勬枃浠朵腑锛 * - * @param file - * 瑕佷繚瀛樼殑鏂囦欢锛 - * @param text - * 鏂囨湰鍐呭锛 + * @param file 瑕佷繚瀛樼殑鏂囦欢锛 + * @param text 鏂囨湰鍐呭锛 */ public static void writeText(String text, File file) { writeText(text, file, DEFAULT_CHARSET); @@ -166,12 +176,10 @@ public class FileUtils { /** * 灏嗘寚瀹氱殑鏂囨湰淇濆瓨鍒版寚瀹氱殑鏂囦欢涓紱 - * @param text - * 鏂囨湰鍐呭锛 - * @param file - * 瑕佷繚瀛樼殑鏂囦欢锛 - * @param charset - * 瀛楃闆嗭紱 + * + * @param text 鏂囨湰鍐呭锛 + * @param file 瑕佷繚瀛樼殑鏂囦欢锛 + * @param charset 瀛楃闆嗭紱 */ public static void writeText(String text, File file, String charset) { try (FileOutputStream out = new FileOutputStream(file, false)) { @@ -181,7 +189,7 @@ public class FileUtils { throw new RuntimeIOException(e.getMessage(), e); } } - + public static void writeBytes(byte[] content, File file) { try (FileOutputStream out = new FileOutputStream(file, false)) { out.write(content); @@ -190,7 +198,7 @@ public class FileUtils { throw new RuntimeIOException(e.getMessage(), e); } } - + public static void appendBytes(byte[] content, File file) { try (FileOutputStream out = new FileOutputStream(file, true)) { out.write(content); @@ -224,16 +232,23 @@ public class FileUtils { /** * 浠ラ粯璁ゅ瓧绗﹂泦锛圲TF-8锛変粠鏂囦欢璇诲彇鏂囨湰锛 + * * @param file file * @return String */ - public static String readText(String file) { - return readText(new File(file), DEFAULT_CHARSET); + public static String readText(String filePath) { + try { + File file = ResourceUtils.getFile(filePath); + return readText(file, DEFAULT_CHARSET); + } catch (FileNotFoundException e) { + throw new RuntimeIOException(e.getMessage(), e); + } } /** * 浠庢枃浠惰鍙栨枃鏈紱 - * @param file file + * + * @param file file * @param charset charset * @return String */ @@ -254,7 +269,7 @@ public class FileUtils { /** * 浠庢枃浠惰鍙栨枃鏈紱 * - * @param file file + * @param file file * @param charset charset * @return String */ @@ -278,7 +293,7 @@ public class FileUtils { /** * 浠庢祦璇诲彇鏂囨湰锛 * - * @param in in + * @param in in * @param charset charset * @return String * @throws IOException exception @@ -310,7 +325,7 @@ public class FileUtils { throw new RuntimeIOException(e.getMessage(), e); } } - + public static byte[] readBytes(File file) { try { FileInputStream in = new FileInputStream(file); @@ -324,8 +339,12 @@ public class FileUtils { } } - public static Properties readProperties(String systemConfig) { - return readProperties(systemConfig, DEFAULT_CHARSET); + public static Properties readProperties(String file) { + return readProperties(file, DEFAULT_CHARSET); + } + + public static Properties readProperties(File file) { + return readProperties(file, DEFAULT_CHARSET); } public static Properties readProperties(String file, String charset) { @@ -417,11 +436,11 @@ public class FileUtils { throw new IllegalStateException(e.getMessage(), e); } } - + public static void deleteFile(String dir) { deleteFile(dir, false); } - + public static void deleteFile(File file) { deleteFile(file, false); } @@ -435,8 +454,7 @@ public class FileUtils { * 鍒犻櫎鏂囦欢锛 * * @param file - * @param silent - * 鏄惁闈欓粯鍒犻櫎锛涘鏋滀负 true 锛屽垯鍚炲櫖鍒犻櫎杩囩▼涓殑寮傚父锛屾剰鍛崇潃鏂规硶鍗充究姝e父杩斿洖鏃朵篃鏈夊彲鑳藉垹闄や笉瀹屽叏锛 + * @param silent 鏄惁闈欓粯鍒犻櫎锛涘鏋滀负 true 锛屽垯鍚炲櫖鍒犻櫎杩囩▼涓殑寮傚父锛屾剰鍛崇潃鏂规硶鍗充究姝e父杩斿洖鏃朵篃鏈夊彲鑳藉垹闄や笉瀹屽叏锛 */ public static void deleteFile(File file, boolean silent) { if (file.isFile()) {