From 2602fb7c9664ab726747432521b2a238608929c6 Mon Sep 17 00:00:00 2001 From: zhaoguangwei Date: Tue, 25 Jun 2019 18:13:22 +0800 Subject: [PATCH 01/11] =?UTF-8?q?clean=20the=20project=EF=BC=9B=20fixed=20?= =?UTF-8?q?the=20bug:=20get=2010+=20results=20by=20/accounts/.../entries?= =?UTF-8?q?=3FfromIndex=3D10&count=3D10,=20no=20results=20in=20the=20secon?= =?UTF-8?q?ds=20page;=20delete=20the=20modules=20of=20stp/state-transfer/c?= =?UTF-8?q?rypto-impl;=20delete=20the=20dependency=20out=20the=20dependenc?= =?UTF-8?q?yManagement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/binary-proto/pom.xml | 4 + source/contract/contract-samples/pom.xml | 10 + source/crypto/crypto-impl/pom.xml | 20 - .../impl/AsymmtricCryptographyImpl.java | 220 ---- .../crypto/impl/CryptoFactoryImpl.java | 30 - .../crypto/impl/HashCryptographyImpl.java | 84 -- .../impl/SymmetricCryptographyImpl.java | 101 -- .../MyAsymmetricEncryptionTest.java | 55 - .../crypto/performance/MyHashTest.java | 62 - .../crypto/performance/MySignatureTest.java | 83 -- .../MySymmetricEncryptionTest.java | 92 -- source/ledger/ledger-core/pom.xml | 5 + .../ledger/core/impl/LedgerQueryService.java | 797 ++++++------- .../JVMContractEventSendOperationHandle.java | 10 +- .../ledger/ContractInvokingTest.java | 48 +- source/ledger/ledger-rpc/pom.xml | 24 +- .../peer/web/LedgerQueryController.java | 1011 +++++++++-------- source/pom.xml | 13 - source/sdk/sdk-base/pom.xml | 121 +- .../sdk/proxy/BlockchainServiceProxyTest.java | 186 ++- source/sdk/sdk-mq/pom.xml | 45 - source/state-transfer/pom.xml | 34 - .../statetransfer/DataSequence.java | 75 -- .../statetransfer/DataSequenceElement.java | 53 - .../statetransfer/DataSequenceInfo.java | 37 - .../callback/DataSequenceReader.java | 39 - .../callback/DataSequenceReaderImpl.java | 59 - .../callback/DataSequenceWriter.java | 30 - .../callback/DataSequenceWriterImpl.java | 142 --- .../comparator/DataSequenceComparator.java | 32 - .../exception/DataSequenceException.java | 21 - .../message/DSDefaultMessageExecutor.java | 80 -- .../message/DSMsgResolverFactory.java | 34 - .../message/DataSequenceLoadMessage.java | 28 - .../message/DataSequenceMsgDecoder.java | 107 -- .../message/DataSequenceMsgEncoder.java | 133 --- .../process/DSProcessManager.java | 186 --- .../process/DSTransferProcess.java | 216 ---- .../result/DSDiffRequestResult.java | 45 - .../result/DSInfoResponseResult.java | 37 - .../statetransfer/StateTransferLayerTest.java | 155 --- source/storage/storage-redis/pom.xml | 86 +- source/storage/storage-rocksdb/pom.xml | 4 + source/storage/storage-service/pom.xml | 47 +- .../service/utils/BufferedKVStorageTest.java | 30 +- source/stp/pom.xml | 21 - source/stp/stp-communication/pom.xml | 50 - .../stp/communication/MessageExecutor.java | 56 - .../stp/communication/RemoteSession.java | 206 ---- .../callback/CallBackBarrier.java | 74 -- .../callback/CallBackDataListener.java | 113 -- .../callback/CallBackLauncher.java | 80 -- .../connection/AbstractAsyncExecutor.java | 71 -- .../connection/AsyncExecutor.java | 36 - .../communication/connection/Connection.java | 220 ---- .../communication/connection/Receiver.java | 161 --- .../stp/communication/connection/Sender.java | 207 ---- .../handler/HeartBeatReceiverHandler.java | 43 - .../handler/HeartBeatReceiverTrigger.java | 42 - .../handler/HeartBeatSenderHandler.java | 42 - .../handler/HeartBeatSenderTrigger.java | 48 - .../connection/handler/ReceiverHandler.java | 345 ------ .../connection/handler/SenderHandler.java | 67 -- .../connection/handler/WatchDogHandler.java | 267 ----- .../connection/listener/ReplyListener.java | 87 -- .../manager/ConnectionManager.java | 175 --- .../manager/RemoteSessionManager.java | 180 --- .../message/AbstractMessage.java | 30 - .../message/HeartBeatMessage.java | 76 -- .../stp/communication/message/IMessage.java | 33 - .../communication/message/LoadMessage.java | 26 - .../communication/message/SessionMessage.java | 112 -- .../message/TransferMessage.java | 182 --- .../stp/communication/node/LocalNode.java | 88 -- .../stp/communication/node/RemoteNode.java | 79 -- .../com/jd/blockchain/SessionMessageTest.java | 37 - .../jd/blockchain/intgr/IntegrationBase.java | 2 +- .../intgr/IntegrationTest4Bftsmart.java | 9 +- source/tools/tools-mocker/pom.xml | 13 + source/tools/tools-package/pom.xml | 45 - 80 files changed, 1213 insertions(+), 6841 deletions(-) delete mode 100644 source/crypto/crypto-impl/pom.xml delete mode 100644 source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/AsymmtricCryptographyImpl.java delete mode 100644 source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/CryptoFactoryImpl.java delete mode 100644 source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/HashCryptographyImpl.java delete mode 100644 source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/SymmetricCryptographyImpl.java delete mode 100644 source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyAsymmetricEncryptionTest.java delete mode 100644 source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyHashTest.java delete mode 100644 source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySignatureTest.java delete mode 100644 source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySymmetricEncryptionTest.java delete mode 100644 source/sdk/sdk-mq/pom.xml delete mode 100644 source/state-transfer/pom.xml delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceElement.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceInfo.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReader.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/comparator/DataSequenceComparator.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/exception/DataSequenceException.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSDefaultMessageExecutor.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSMsgResolverFactory.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceLoadMessage.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgDecoder.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgEncoder.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSProcessManager.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSTransferProcess.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSDiffRequestResult.java delete mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSInfoResponseResult.java delete mode 100644 source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java delete mode 100644 source/stp/pom.xml delete mode 100644 source/stp/stp-communication/pom.xml delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/MessageExecutor.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/RemoteSession.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackBarrier.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackDataListener.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/callback/CallBackLauncher.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AbstractAsyncExecutor.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/AsyncExecutor.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Connection.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Receiver.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/Sender.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverHandler.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatReceiverTrigger.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderHandler.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/HeartBeatSenderTrigger.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/ReceiverHandler.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/SenderHandler.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/handler/WatchDogHandler.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/connection/listener/ReplyListener.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/ConnectionManager.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/manager/RemoteSessionManager.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/AbstractMessage.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/HeartBeatMessage.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/IMessage.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/LoadMessage.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/SessionMessage.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/message/TransferMessage.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/LocalNode.java delete mode 100644 source/stp/stp-communication/src/main/java/com/jd/blockchain/stp/communication/node/RemoteNode.java delete mode 100644 source/stp/stp-communication/src/test/java/com/jd/blockchain/SessionMessageTest.java delete mode 100644 source/tools/tools-package/pom.xml diff --git a/source/binary-proto/pom.xml b/source/binary-proto/pom.xml index 508639db..3200942b 100644 --- a/source/binary-proto/pom.xml +++ b/source/binary-proto/pom.xml @@ -15,5 +15,9 @@ utils-common ${project.version} + + junit + junit + \ No newline at end of file diff --git a/source/contract/contract-samples/pom.xml b/source/contract/contract-samples/pom.xml index b54f9e5f..ef3d3407 100644 --- a/source/contract/contract-samples/pom.xml +++ b/source/contract/contract-samples/pom.xml @@ -55,6 +55,16 @@ + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + + true + + + diff --git a/source/crypto/crypto-impl/pom.xml b/source/crypto/crypto-impl/pom.xml deleted file mode 100644 index cb07d6c5..00000000 --- a/source/crypto/crypto-impl/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - 4.0.0 - - com.jd.blockchain - crypto - 0.9.0-SNAPSHOT - - crypto-impl - - - - com.jd.blockchain - crypto-framework - ${project.version} - - - - \ No newline at end of file diff --git a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/AsymmtricCryptographyImpl.java b/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/AsymmtricCryptographyImpl.java deleted file mode 100644 index 41b38408..00000000 --- a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/AsymmtricCryptographyImpl.java +++ /dev/null @@ -1,220 +0,0 @@ -//package com.jd.blockchain.crypto.impl; -// -//import com.jd.blockchain.crypto.Ciphertext; -//import com.jd.blockchain.crypto.CryptoAlgorithm; -//import com.jd.blockchain.crypto.PrivKey; -//import com.jd.blockchain.crypto.PubKey; -//import com.jd.blockchain.crypto.asymmetric.*; -//import com.jd.blockchain.crypto.impl.jni.asymmetric.JNIED25519SignatureFunction; -//import com.jd.blockchain.crypto.impl.sm.asymmetric.SM2CryptoFunction; -//import com.jd.blockchain.crypto.service.classic.ED25519SignatureFunction; -// -//public class AsymmtricCryptographyImpl implements AsymmetricCryptography { -// -// private static final SignatureFunction ED25519_SIGF = new ED25519SignatureFunction(); -// -// private static final SignatureFunction SM2_SIGF = new SM2CryptoFunction(); -// -// private static final SignatureFunction JNIED25519_SIGF = new JNIED25519SignatureFunction(); -// -// private static final AsymmetricEncryptionFunction SM2_ENCF = new SM2CryptoFunction(); -// -// /** -// * 封装了非对称密码算法对应的密钥生成算法 -// */ -// @Override -// public CryptoKeyPair generateKeyPair(CryptoAlgorithm algorithm) { -// -// //判断算法是签名算法还是非对称加密算法,并根据算法生成密钥对,否则抛出异常 -// if (algorithm.isSignable() && algorithm.hasAsymmetricKey()){ -// return getSignatureFunction(algorithm).generateKeyPair(); -// } -// else if (algorithm.isEncryptable() && algorithm.hasAsymmetricKey()){ -// return getAsymmetricEncryptionFunction(algorithm).generateKeyPair(); -// } -// else throw new IllegalArgumentException("The specified algorithm is not signature or asymmetric encryption algorithm!"); -// } -// -// @Override -// public SignatureFunction getSignatureFunction(CryptoAlgorithm algorithm) { -// //遍历签名算法,如果满足,则返回实例 -// switch (algorithm) { -// case ED25519: -// return ED25519_SIGF; -// case SM2: -// return SM2_SIGF; -// case JNIED25519: -// return JNIED25519_SIGF; -// default: -// break; -// } -// throw new IllegalArgumentException("The specified algorithm is not signature algorithm!"); -// } -// -// @Override -// public boolean verify(byte[] digestBytes, byte[] pubKeyBytes, byte[] data) { -// -// //得到SignatureDigest类型的签名摘要,并得到算法标识 -// SignatureDigest signatureDigest = resolveSignatureDigest(digestBytes); -// CryptoAlgorithm algorithm = signatureDigest.getAlgorithm(); -// PubKey pubKey = resolvePubKey(pubKeyBytes); -// -// //验证两个输入中算法标识一致,否则抛出异常 -// if (algorithm != signatureDigest.getAlgorithm()) -// throw new IllegalArgumentException("Digest's algorithm and key's are not matching!"); -// -// //根据算法标识,调用对应算法实例来验证签名摘要 -// return getSignatureFunction(algorithm).verify(signatureDigest,pubKey,data); -// } -// -// @Override -// public AsymmetricEncryptionFunction getAsymmetricEncryptionFunction(CryptoAlgorithm algorithm) { -// //遍历非对称加密算法,如果满足,则返回实例 -// switch (algorithm) { -// case SM2: -// return SM2_ENCF; -// default: -// break; -// } -// throw new IllegalArgumentException("The specified algorithm is not asymmetric encryption algorithm!"); -// } -// -// @Override -// public byte[] decrypt(byte[] privKeyBytes, byte[] ciphertextBytes) { -// -// //分别得到PrivKey和Ciphertext类型的密钥和密文,以及privKey对应的算法 -// PrivKey privKey = resolvePrivKey(privKeyBytes); -// Ciphertext ciphertext = resolveCiphertext(ciphertextBytes); -// CryptoAlgorithm algorithm = privKey.getAlgorithm(); -// -// //验证两个输入中算法标识一致,否则抛出异常 -// if (algorithm != ciphertext.getAlgorithm()) -// throw new IllegalArgumentException("Ciphertext's algorithm and key's are not matching!"); -// -// //根据算法标识,调用对应算法实例来计算返回明文 -// return getAsymmetricEncryptionFunction(algorithm).decrypt(privKey,ciphertext); -// } -// -// @Override -// public Ciphertext resolveCiphertext(byte[] ciphertextBytes) { -// Ciphertext ciphertext = tryResolveCiphertext(ciphertextBytes); -// if (ciphertext == null) -// throw new IllegalArgumentException("This ciphertextBytes cannot be resolved!"); -// else return ciphertext; -// } -// -// @Override -// public Ciphertext tryResolveCiphertext(byte[] ciphertextBytes) { -// //遍历非对称加密算法,如果满足,则返回解析结果 -// if (SM2_ENCF.supportCiphertext(ciphertextBytes)){ -// return SM2_ENCF.resolveCiphertext(ciphertextBytes); -// } -// //否则返回null -// return null; -// } -// -// @Override -// public SignatureDigest resolveSignatureDigest(byte[] digestBytes) { -// SignatureDigest signatureDigest = tryResolveSignatureDigest(digestBytes); -// if (signatureDigest == null) -// throw new IllegalArgumentException("This digestBytes cannot be resolved!"); -// else return signatureDigest; -// } -// -// @Override -// public SignatureDigest tryResolveSignatureDigest(byte[] digestBytes) { -// //遍历签名算法,如果满足,则返回解析结果 -// if (ED25519_SIGF.supportDigest(digestBytes)){ -// return ED25519_SIGF.resolveDigest(digestBytes); -// } -// if (SM2_SIGF.supportDigest(digestBytes)){ -// return SM2_SIGF.resolveDigest(digestBytes); -// } -// if (JNIED25519_SIGF.supportDigest(digestBytes)){ -// return JNIED25519_SIGF.resolveDigest(digestBytes); -// } -// //否则返回null -// return null; -// } -// -// @Override -// public byte[] retrievePubKeyBytes(byte[] privKeyBytes) { -// byte[] pubKeyBytes = tryRetrievePubKeyBytes(privKeyBytes); -// if (pubKeyBytes == null) -// throw new IllegalArgumentException("The specified algorithm in privKeyBytes is not signature or asymmetric encryption algorithm!"); -// else return pubKeyBytes; -// } -// -// @Override -// public byte[] tryRetrievePubKeyBytes(byte[] privKeyBytes) { -// //解析私钥获得算法标识 -// CryptoAlgorithm algorithm = resolvePrivKey(privKeyBytes).getAlgorithm(); -// -// //判断算法是签名算法还是非对称加密算法,并根据算法生成密钥对,否则抛出异常 -// if (algorithm.isSignable() && algorithm.hasAsymmetricKey()){ -// return getSignatureFunction(algorithm).retrievePubKeyBytes(privKeyBytes); -// } -// else if (algorithm.isEncryptable() && algorithm.hasAsymmetricKey()){ -// return getAsymmetricEncryptionFunction(algorithm).retrievePubKeyBytes(privKeyBytes); -// } -// //否则返回null -// return null; -// } -// -// @Override -// public PubKey resolvePubKey(byte[] pubKeyBytes) { -// PubKey pubKey = tryResolvePubKey(pubKeyBytes); -// if (pubKey == null) -// throw new IllegalArgumentException("This pubKeyBytes cannot be resolved!"); -// else return pubKey; -// -// } -// -// @Override -// public PubKey tryResolvePubKey(byte[] pubKeyBytes) { -// //遍历签名算法,如果满足,则返回解析结果 -// if (ED25519_SIGF.supportPubKey(pubKeyBytes)){ -// return ED25519_SIGF.resolvePubKey(pubKeyBytes); -// } -// if (SM2_SIGF.supportPubKey(pubKeyBytes)){ -// return SM2_SIGF.resolvePubKey(pubKeyBytes); -// } -// if (JNIED25519_SIGF.supportPubKey(pubKeyBytes)){ -// return JNIED25519_SIGF.resolvePubKey(pubKeyBytes); -// } -// //遍历非对称加密算法,如果满足,则返回解析结果 -// if (SM2_ENCF.supportPubKey(pubKeyBytes)){ -// return SM2_ENCF.resolvePubKey(pubKeyBytes); -// } -// //否则返回null -// return null; -// } -// -// @Override -// public PrivKey resolvePrivKey(byte[] privKeyBytes) { -// PrivKey privKey = tryResolvePrivKey(privKeyBytes); -// if (privKey == null) -// throw new IllegalArgumentException("This privKeyBytes cannot be resolved!"); -// else return privKey; -// } -// -// @Override -// public PrivKey tryResolvePrivKey(byte[] privKeyBytes) { -// //遍历签名算法,如果满足,则返回解析结果 -// if (ED25519_SIGF.supportPrivKey(privKeyBytes)){ -// return ED25519_SIGF.resolvePrivKey(privKeyBytes); -// } -// if (SM2_SIGF.supportPrivKey(privKeyBytes)){ -// return SM2_SIGF.resolvePrivKey(privKeyBytes); -// } -// if (JNIED25519_SIGF.supportPrivKey(privKeyBytes)){ -// return JNIED25519_SIGF.resolvePrivKey(privKeyBytes); -// } -// //遍历非对称加密算法,如果满足,则返回解析结果 -// if (SM2_ENCF.supportPrivKey(privKeyBytes)){ -// return SM2_ENCF.resolvePrivKey(privKeyBytes); -// } -// //否则返回null -// return null; -// } -//} diff --git a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/CryptoFactoryImpl.java b/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/CryptoFactoryImpl.java deleted file mode 100644 index ffd35e66..00000000 --- a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/CryptoFactoryImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -//package com.jd.blockchain.crypto.impl; -// -//import com.jd.blockchain.crypto.CryptoFactory; -//import com.jd.blockchain.crypto.asymmetric.AsymmetricCryptography; -//import com.jd.blockchain.crypto.hash.HashCryptography; -//import com.jd.blockchain.crypto.symmetric.SymmetricCryptography; -// -//public class CryptoFactoryImpl implements CryptoFactory { -// -// //Field; -// private static HashCryptography hashCryptography = new HashCryptographyImpl(); -// private static AsymmetricCryptography asymmetricCryptography = new AsymmtricCryptographyImpl(); -// private static SymmetricCryptography symmetricCryptography = new SymmetricCryptographyImpl(); -// -// @Override -// public HashCryptography hashCryptography() { -// return hashCryptography; -// } -// -// @Override -// public AsymmetricCryptography asymmetricCryptography() { -// return asymmetricCryptography; -// } -// -// @Override -// public SymmetricCryptography symmetricCryptography() { -// return symmetricCryptography; -// } -// -//} diff --git a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/HashCryptographyImpl.java b/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/HashCryptographyImpl.java deleted file mode 100644 index 59a1defc..00000000 --- a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/HashCryptographyImpl.java +++ /dev/null @@ -1,84 +0,0 @@ -//package com.jd.blockchain.crypto.impl; -// -//import com.jd.blockchain.crypto.CryptoAlgorithm; -//import com.jd.blockchain.crypto.hash.HashCryptography; -//import com.jd.blockchain.crypto.hash.HashDigest; -//import com.jd.blockchain.crypto.hash.HashFunction; -//import com.jd.blockchain.crypto.impl.jni.hash.JNIRIPEMD160HashFunction; -//import com.jd.blockchain.crypto.impl.jni.hash.JNISHA256HashFunction; -//import com.jd.blockchain.crypto.impl.sm.hash.SM3HashFunction; -//import com.jd.blockchain.crypto.service.classic.RIPEMD160HashFunction; -//import com.jd.blockchain.crypto.service.classic.SHA256HashFunction; -// -//public class HashCryptographyImpl implements HashCryptography { -// -// private static final HashFunction SHA256_FUNC = new SHA256HashFunction(); -// private static final HashFunction RIPEMD160_FUNC = new RIPEMD160HashFunction(); -// private static final HashFunction SM3_FUNC = new SM3HashFunction(); -// -// private static final HashFunction JNISHA256_FUNC = new JNISHA256HashFunction(); -// private static final HashFunction JNIRIPEMD160_FUNC = new JNIRIPEMD160HashFunction(); -// -// @Override -// public HashFunction getFunction(CryptoAlgorithm algorithm) { -// -// // 遍历哈希算法,如果满足,则返回实例 -// switch (algorithm) { -// case SHA256: -// return SHA256_FUNC; -// case RIPEMD160: -// return RIPEMD160_FUNC; -// case SM3: -// return SM3_FUNC; -// case JNISHA256: -// return JNISHA256_FUNC; -// case JNIRIPEMD160: -// return JNIRIPEMD160_FUNC; -// default: -// break; -// } -// throw new IllegalArgumentException("The specified algorithm is not hash algorithm!"); -// } -// -// @Override -// public boolean verify(byte[] digestBytes, byte[] data) { -// HashDigest hashDigest = resolveHashDigest(digestBytes); -// return verify(hashDigest,data); -// } -// -// @Override -// public boolean verify(HashDigest digest, byte[] data) { -// CryptoAlgorithm algorithm = digest.getAlgorithm(); -// return getFunction(algorithm).verify(digest, data); -// } -// -// @Override -// public HashDigest resolveHashDigest(byte[] digestBytes) { -// HashDigest hashDigest = tryResolveHashDigest(digestBytes); -// if (hashDigest == null) -// throw new IllegalArgumentException("This digestBytes cannot be resolved!"); -// else return hashDigest; -// } -// -// @Override -// public HashDigest tryResolveHashDigest(byte[] digestBytes) { -// //遍历哈希函数,如果满足,则返回解析结果 -// if (SHA256_FUNC.supportHashDigest(digestBytes)) { -// return SHA256_FUNC.resolveHashDigest(digestBytes); -// } -// if (RIPEMD160_FUNC.supportHashDigest(digestBytes)) { -// return RIPEMD160_FUNC.resolveHashDigest(digestBytes); -// } -// if (SM3_FUNC.supportHashDigest(digestBytes)) { -// return SM3_FUNC.resolveHashDigest(digestBytes); -// } -// if (JNISHA256_FUNC.supportHashDigest(digestBytes)) { -// return JNISHA256_FUNC.resolveHashDigest(digestBytes); -// } -// if (JNIRIPEMD160_FUNC.supportHashDigest(digestBytes)) { -// return JNIRIPEMD160_FUNC.resolveHashDigest(digestBytes); -// } -// //否则返回null -// return null; -// } -//} \ No newline at end of file diff --git a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/SymmetricCryptographyImpl.java b/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/SymmetricCryptographyImpl.java deleted file mode 100644 index 115855d0..00000000 --- a/source/crypto/crypto-impl/src/main/java/com/jd/blockchain/crypto/impl/SymmetricCryptographyImpl.java +++ /dev/null @@ -1,101 +0,0 @@ -//package com.jd.blockchain.crypto.impl; -// -//import com.jd.blockchain.crypto.Ciphertext; -//import com.jd.blockchain.crypto.CryptoAlgorithm; -//import com.jd.blockchain.crypto.SingleKey; -//import com.jd.blockchain.crypto.impl.sm.symmetric.SM4SymmetricEncryptionFunction; -//import com.jd.blockchain.crypto.service.classic.AESSymmetricEncryptionFunction; -//import com.jd.blockchain.crypto.symmetric.SymmetricCryptography; -//import com.jd.blockchain.crypto.symmetric.SymmetricEncryptionFunction; -// -//public class SymmetricCryptographyImpl implements SymmetricCryptography { -// -// private static final SymmetricEncryptionFunction AES_ENCF = new AESSymmetricEncryptionFunction(); -// private static final SymmetricEncryptionFunction SM4_ENCF = new SM4SymmetricEncryptionFunction(); -// -// /** -// * 封装了对称密码算法对应的密钥生成算法 -// */ -// @Override -// public SingleKey generateKey(CryptoAlgorithm algorithm) { -// -// //验证算法标识是对称加密算法,并根据算法生成对称密钥,否则抛出异常 -// if (algorithm.isEncryptable() && algorithm.isSymmetric() ){ -// return (SingleKey) getSymmetricEncryptionFunction(algorithm).generateSymmetricKey(); -// } -// else throw new IllegalArgumentException("The specified algorithm is not symmetric encryption algorithm!"); -// } -// -// @Override -// public SymmetricEncryptionFunction getSymmetricEncryptionFunction(CryptoAlgorithm algorithm) { -// -// // 遍历对称加密算法,如果满足,则返回实例 -// switch (algorithm) { -// case AES: -// return AES_ENCF; -// case SM4: -// return SM4_ENCF; -// default: -// break; -// } -// throw new IllegalArgumentException("The specified algorithm is not symmetric encryption algorithm!"); -// } -// -// @Override -// public byte[] decrypt(byte[] symmetricKeyBytes, byte[] ciphertextBytes) { -// -// //分别得到SymmetricKey和Ciphertext类型的密钥和密文,以及symmetricKey对应的算法 -// SingleKey symmetricKey = resolveSymmetricKey(symmetricKeyBytes); -// Ciphertext ciphertext = resolveCiphertext(ciphertextBytes); -// CryptoAlgorithm algorithm = symmetricKey.getAlgorithm(); -// -// //验证两个输入中算法标识一致,否则抛出异常 -// if (algorithm != ciphertext.getAlgorithm()) -// throw new IllegalArgumentException("Ciphertext's algorithm and key's are not matching!"); -// -// //根据算法标识,调用对应算法实例来计算返回明文 -// return getSymmetricEncryptionFunction(algorithm).decrypt(symmetricKey,ciphertext); -// } -// -// @Override -// public Ciphertext resolveCiphertext(byte[] ciphertextBytes) { -// Ciphertext ciphertext = tryResolveCiphertext(ciphertextBytes); -// if (ciphertext == null) -// throw new IllegalArgumentException("This ciphertextBytes cannot be resolved!"); -// else return ciphertext; -// } -// -// @Override -// public Ciphertext tryResolveCiphertext(byte[] ciphertextBytes) { -// //遍历对称加密算法,如果满足,则返回解析结果 -// if (AES_ENCF.supportCiphertext(ciphertextBytes)) { -// return AES_ENCF.resolveCiphertext(ciphertextBytes); -// } -// if (SM4_ENCF.supportCiphertext(ciphertextBytes)) { -// return SM4_ENCF.resolveCiphertext(ciphertextBytes); -// } -// //否则返回null -// return null; -// } -// -// @Override -// public SingleKey resolveSymmetricKey(byte[] symmetricKeyBytes) { -// SingleKey symmetricKey = tryResolveSymmetricKey(symmetricKeyBytes); -// if (symmetricKey == null) -// throw new IllegalArgumentException("This symmetricKeyBytes cannot be resolved!"); -// else return symmetricKey; -// } -// -// @Override -// public SingleKey tryResolveSymmetricKey(byte[] symmetricKeyBytes) { -// //遍历对称加密算法,如果满足,则返回解析结果 -// if(AES_ENCF.supportSymmetricKey(symmetricKeyBytes)) { -// return AES_ENCF.resolveSymmetricKey(symmetricKeyBytes); -// } -// if(SM4_ENCF.supportSymmetricKey(symmetricKeyBytes)) { -// return SM4_ENCF.resolveSymmetricKey(symmetricKeyBytes); -// } -// //否则返回null -// return null; -// } -//} diff --git a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyAsymmetricEncryptionTest.java b/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyAsymmetricEncryptionTest.java deleted file mode 100644 index 87ff496f..00000000 --- a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyAsymmetricEncryptionTest.java +++ /dev/null @@ -1,55 +0,0 @@ -//package test.com.jd.blockchain.crypto.performance; -// -//import com.jd.blockchain.crypto.Ciphertext; -//import com.jd.blockchain.crypto.PrivKey; -//import com.jd.blockchain.crypto.PubKey; -//import com.jd.blockchain.crypto.asymmetric.CryptoKeyPair; -//import com.jd.blockchain.crypto.impl.sm.asymmetric.SM2CryptoFunction; -//import org.bouncycastle.util.encoders.Hex; -// -//public class MyAsymmetricEncryptionTest { -// -// public static void main(String[] args) { -// -// String string1K = "0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210"; -// String string1M = ""; -// for (int i = 0; i < 1024 ; i++) -// { -// string1M = string1M + string1K; -// } -// -// byte[] data1K = Hex.decode(string1K); -// byte[] data1M = Hex.decode(string1M); -// int count = 10000; -// -// SM2CryptoFunction sm2 = new SM2CryptoFunction(); -// CryptoKeyPair keyPairSM2 = sm2.generateKeyPair(); -// PrivKey privKeySM2 = keyPairSM2.getPrivKey(); -// PubKey pubKeySM2 = keyPairSM2.getPubKey(); -// -// System.out.println("=================== do SM2 encrypt test ==================="); -// Ciphertext ciphertextSM2 = null; -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// ciphertextSM2 = sm2.encrypt(pubKeySM2,data1K); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SM2 Encrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// System.out.println("=================== do SM2 decrypt test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// sm2.decrypt(privKeySM2,ciphertextSM2); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SM2 Decrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// } -//} diff --git a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyHashTest.java b/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyHashTest.java deleted file mode 100644 index dfa922fc..00000000 --- a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MyHashTest.java +++ /dev/null @@ -1,62 +0,0 @@ -//package test.com.jd.blockchain.crypto.performance; -// -//import com.jd.blockchain.crypto.impl.sm.hash.SM3HashFunction; -//import com.jd.blockchain.crypto.service.classic.RIPEMD160HashFunction; -//import com.jd.blockchain.crypto.service.classic.SHA256HashFunction; -// -//import java.util.Random; -// -//public class MyHashTest { -// -// public static void main(String[] args) { -// -// Random rand = new Random(); -// byte[] data1K = new byte[1024]; -// rand.nextBytes(data1K); -// int count = 1000000; -// -// SHA256HashFunction sha256hf = new SHA256HashFunction(); -// -// System.out.println("=================== do SHA256 hash test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// sha256hf.hash(data1K); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SHA256 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// RIPEMD160HashFunction ripemd160hf = new RIPEMD160HashFunction(); -// -// System.out.println("=================== do RIPEMD160 hash test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// ripemd160hf.hash(data1K); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("RIPEMD160 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// SM3HashFunction sm3hf = new SM3HashFunction(); -// -// System.out.println("=================== do SM3 hash test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// sm3hf.hash(data1K); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SM3 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// } -//} -// diff --git a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySignatureTest.java b/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySignatureTest.java deleted file mode 100644 index 684ecdb6..00000000 --- a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySignatureTest.java +++ /dev/null @@ -1,83 +0,0 @@ -//package test.com.jd.blockchain.crypto.performance; -// -//import com.jd.blockchain.crypto.PrivKey; -//import com.jd.blockchain.crypto.PubKey; -//import com.jd.blockchain.crypto.asymmetric.CryptoKeyPair; -//import com.jd.blockchain.crypto.asymmetric.SignatureDigest; -//import com.jd.blockchain.crypto.impl.sm.asymmetric.SM2CryptoFunction; -//import com.jd.blockchain.crypto.service.classic.ED25519SignatureFunction; -// -//import java.util.Random; -// -//public class MySignatureTest { -// -// public static void main(String[] args) { -// -// Random rand = new Random(); -// byte[] data = new byte[64]; -// rand.nextBytes(data); -// int count = 10000; -// -// ED25519SignatureFunction ed25519sf = new ED25519SignatureFunction(); -// CryptoKeyPair keyPairED25519 = ed25519sf.generateKeyPair(); -// PrivKey privKeyED25519 = keyPairED25519.getPrivKey(); -// PubKey pubKeyED25519 = keyPairED25519.getPubKey(); -// -// System.out.println("=================== do ED25519 sign test ==================="); -// SignatureDigest signatureDigestED25519 = null; -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// signatureDigestED25519 = ed25519sf.sign(privKeyED25519,data); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("ED25519 Signing Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// System.out.println("=================== do ED25519 verify test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// ed25519sf.verify(signatureDigestED25519,pubKeyED25519,data); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("ED25519 Verifying Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// SM2CryptoFunction sm2 = new SM2CryptoFunction(); -// CryptoKeyPair keyPairSM2 = sm2.generateKeyPair(); -// PrivKey privKeySM2 = keyPairSM2.getPrivKey(); -// PubKey pubKeySM2 = keyPairSM2.getPubKey(); -// -// -// System.out.println("=================== do SM2 sign test ==================="); -// SignatureDigest signatureDigestSM2 = null; -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// signatureDigestSM2 = sm2.sign(privKeySM2,data); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SM2 Signing Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// System.out.println("=================== do SM2 verify test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// sm2.verify(signatureDigestSM2,pubKeySM2,data); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SM2 Verifying Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// } -//} diff --git a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySymmetricEncryptionTest.java b/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySymmetricEncryptionTest.java deleted file mode 100644 index fbab4b13..00000000 --- a/source/crypto/crypto-impl/src/test/java/test/com/jd/blockchain/crypto/performance/MySymmetricEncryptionTest.java +++ /dev/null @@ -1,92 +0,0 @@ -//package test.com.jd.blockchain.crypto.performance; -// -//import com.jd.blockchain.crypto.Ciphertext; -//import com.jd.blockchain.crypto.SingleKey; -//import com.jd.blockchain.crypto.impl.sm.symmetric.SM4SymmetricEncryptionFunction; -//import com.jd.blockchain.crypto.service.classic.AESSymmetricEncryptionFunction; -// -//import org.bouncycastle.util.encoders.Hex; -// -//public class MySymmetricEncryptionTest { -// -// public static void main(String[] args) { -// -// String string1K = "0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210"; -// -//// String string1M = ""; -//// for (int i = 0; i < 1024 ; i++) -//// { -//// string1M = string1M + string1K; -//// } -// -// byte[] data1K = Hex.decode(string1K); -//// byte[] data1M = Hex.decode(string1M); -// -// int count = 100000; -// -// -// AESSymmetricEncryptionFunction aes = new AESSymmetricEncryptionFunction(); -// SingleKey keyAES = (SingleKey) aes.generateSymmetricKey(); -// Ciphertext ciphertext1KAES = null; -// Ciphertext ciphertext1MAES = null; -// -// System.out.println("=================== do AES encrypt test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// ciphertext1KAES = aes.encrypt(keyAES,data1K); -//// ciphertext1MAES = aes.encrypt(keyAES,data1M); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("AES Encrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// -// -// System.out.println("=================== do AES decrypt test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// aes.decrypt(keyAES,ciphertext1KAES); -//// aes.decrypt(keyAES,ciphertext1MAES); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("AES Decrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// SM4SymmetricEncryptionFunction sm4 = new SM4SymmetricEncryptionFunction(); -// SingleKey keySM4 = (SingleKey) sm4.generateSymmetricKey(); -// Ciphertext ciphertext1KSM4 = null; -// Ciphertext ciphertext1MSM4 = null; -// -// System.out.println("=================== do SM4 encrypt test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// ciphertext1KSM4 = sm4.encrypt(keySM4,data1K); -//// ciphertext1MSM4 =sm4.encrypt(keySM4,data1M); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SM4 Encrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// -// System.out.println("=================== do SM4 decrypt test ==================="); -// for (int r = 0; r < 5; r++) { -// System.out.println("------------- round[" + r + "] --------------"); -// long startTS = System.currentTimeMillis(); -// for (int i = 0; i < count; i++) { -// sm4.decrypt(keySM4,ciphertext1KSM4); -//// sm4.decrypt(keySM4,ciphertext1MSM4); -// } -// long elapsedTS = System.currentTimeMillis() - startTS; -// System.out.println(String.format("SM4 Decrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, -// (count * 1000.00D) / elapsedTS)); -// } -// } -//} diff --git a/source/ledger/ledger-core/pom.xml b/source/ledger/ledger-core/pom.xml index 34497874..ac1e9948 100644 --- a/source/ledger/ledger-core/pom.xml +++ b/source/ledger/ledger-core/pom.xml @@ -62,6 +62,11 @@ ${project.version} test + + org.mockito + mockito-core + test + 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 13625600..5696ded7 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 @@ -1,398 +1,399 @@ -package com.jd.blockchain.ledger.core.impl; - -import java.util.ArrayList; -import java.util.List; - -import com.jd.blockchain.contract.ContractException; -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.*; -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.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; - -public class LedgerQueryService implements BlockchainQueryService { - - private LedgerService ledgerService; - - public LedgerQueryService(LedgerService ledgerService) { - this.ledgerService = ledgerService; - } - - @Override - public HashDigest[] getLedgerHashs() { - return ledgerService.getLedgerHashs(); - } - - @Override - public LedgerInfo getLedger(HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerInfo ledgerInfo = new LedgerInfo(); - ledgerInfo.setHash(ledger.getHash()); - ledgerInfo.setLatestBlockHash(ledger.getLatestBlockHash()); - ledgerInfo.setLatestBlockHeight(ledger.getLatestBlockHeight()); - return ledgerInfo; - } - - @Override - public ParticipantNode[] getConsensusParticipants(HashDigest ledgerHash) { - return ledgerAdministration(ledgerHash).getParticipants(); - } - - @Override - public LedgerMetadata getLedgerMetadata(HashDigest ledgerHash) { - return ledgerAdministration(ledgerHash).getMetadata(); - } - - @Override - public LedgerBlock getBlock(HashDigest ledgerHash, long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - return ledger.getBlock(height); - } - - @Override - public LedgerBlock getBlock(HashDigest ledgerHash, HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - return ledger.getBlock(blockHash); - } - - @Override - public long getTransactionCount(HashDigest ledgerHash, long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(height); - TransactionSet txset = ledger.getTransactionSet(block); - return txset.getTotalCount(); - } - - @Override - public long getTransactionCount(HashDigest ledgerHash, HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - TransactionSet txset = ledger.getTransactionSet(block); - return txset.getTotalCount(); - } - - @Override - public long getTransactionTotalCount(HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - TransactionSet txset = ledger.getTransactionSet(block); - return txset.getTotalCount(); - } - - @Override - public long getDataAccountCount(HashDigest ledgerHash, long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(height); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getTotalCount(); - } - - @Override - public long getDataAccountCount(HashDigest ledgerHash, HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getTotalCount(); - } - - @Override - public long getDataAccountTotalCount(HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getTotalCount(); - } - - @Override - public long getUserCount(HashDigest ledgerHash, long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(height); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getTotalCount(); - } - - @Override - public long getUserCount(HashDigest ledgerHash, HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getTotalCount(); - } - - @Override - public long getUserTotalCount(HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getTotalCount(); - } - - @Override - public long getContractCount(HashDigest ledgerHash, long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(height); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getTotalCount(); - } - - @Override - public long getContractCount(HashDigest ledgerHash, HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getTotalCount(); - } - - @Override - public long getContractTotalCount(HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getTotalCount(); - } - - @Override - public LedgerTransaction[] getTransactions(HashDigest ledgerHash, long height, int fromIndex, int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock ledgerBlock = ledger.getBlock(height); - TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); - int lastHeightTxTotalNums = 0; - - if (height > 0) { - lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); - } - - int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); - // 取当前高度的增量交易数,在增量交易里进行查找 - int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; -// -// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { -// fromIndex = 0; -// } -// if (count == -1) { -// fromIndex = 0; -// count = currentHeightTxNums; -// } -// if (count > currentHeightTxNums) { -// count = currentHeightTxNums - fromIndex; -// } - int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); - } - - @Override - public LedgerTransaction[] getTransactions(HashDigest ledgerHash, HashDigest blockHash, int fromIndex, int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock ledgerBlock = ledger.getBlock(blockHash); - long height = ledgerBlock.getHeight(); - TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); - int lastHeightTxTotalNums = 0; - - if (height > 0) { - lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); - } - - int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); - // 取当前块hash的增量交易数,在增量交易里进行查找 - int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; - -// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { -// fromIndex = 0; -// } -// if (count == -1) { -// fromIndex = 0; -// count = currentHeightTxNums; -// } -// if (count > currentHeightTxNums) { -// count = currentHeightTxNums - fromIndex; -// } - int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); - } - - @Override - public LedgerTransaction getTransactionByContentHash(HashDigest ledgerHash, HashDigest contentHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - TransactionSet txset = ledger.getTransactionSet(block); - return txset.get(contentHash); - } - - @Override - public TransactionState getTransactionStateByContentHash(HashDigest ledgerHash, HashDigest contentHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - TransactionSet txset = ledger.getTransactionSet(block); - return txset.getTxState(contentHash); - } - - @Override - public UserInfo getUser(HashDigest ledgerHash, String address) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getUser(address); - - } - - @Override - public AccountHeader getDataAccount(HashDigest ledgerHash, String address) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getDataAccount(Bytes.fromBase58(address)); - } - - @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { - if (keys == null || keys.length == 0) { - return null; - } - 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; - for (int i = 0; i < entries.length; i++) { - final String currKey = keys[i]; - - ver = dataAccount.getDataVersion(Bytes.fromString(currKey)); - - if (ver < 0) { - entries[i] = new KVDataObject(currKey, -1, null); - } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(currKey), ver); - entries[i] = new KVDataObject(currKey, ver, value); - } - } - - 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, 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, null); - } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); - entries[i] = new KVDataObject(keys[i], ver, value); - } - } - } - - return entries; - } - - @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { - - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); - - return dataAccount.getDataEntries(fromIndex, count); - } - - @Override - public long getDataEntriesTotalCount(HashDigest ledgerHash, String address) { - - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); - - return dataAccount.getDataEntriesTotalCount(); - } - - @Override - public ContractInfo getContract(HashDigest ledgerHash, String address) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getContract(Bytes.fromBase58(address)); - } - - @Override - public AccountHeader[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) userAccountSet.getTotalCount()); - return userAccountSet.getAccounts(pages[0], pages[1]); - } - - @Override - public AccountHeader[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccountSet.getTotalCount()); - return dataAccountSet.getAccounts(pages[0], pages[1]); - } - - @Override - public AccountHeader[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) contractAccountSet.getTotalCount()); - return contractAccountSet.getAccounts(pages[0], pages[1]); - } - - private LedgerAdministration ledgerAdministration(HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - LedgerAdministration administration = ledger.getAdminAccount(block); - return administration; - } -} +package com.jd.blockchain.ledger.core.impl; + +import java.util.ArrayList; +import java.util.List; + +import com.jd.blockchain.contract.ContractException; +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.*; +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.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; + +public class LedgerQueryService implements BlockchainQueryService { + + private LedgerService ledgerService; + + public LedgerQueryService(LedgerService ledgerService) { + this.ledgerService = ledgerService; + } + + @Override + public HashDigest[] getLedgerHashs() { + return ledgerService.getLedgerHashs(); + } + + @Override + public LedgerInfo getLedger(HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerInfo ledgerInfo = new LedgerInfo(); + ledgerInfo.setHash(ledger.getHash()); + ledgerInfo.setLatestBlockHash(ledger.getLatestBlockHash()); + ledgerInfo.setLatestBlockHeight(ledger.getLatestBlockHeight()); + return ledgerInfo; + } + + @Override + public ParticipantNode[] getConsensusParticipants(HashDigest ledgerHash) { + return ledgerAdministration(ledgerHash).getParticipants(); + } + + @Override + public LedgerMetadata getLedgerMetadata(HashDigest ledgerHash) { + return ledgerAdministration(ledgerHash).getMetadata(); + } + + @Override + public LedgerBlock getBlock(HashDigest ledgerHash, long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + return ledger.getBlock(height); + } + + @Override + public LedgerBlock getBlock(HashDigest ledgerHash, HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + return ledger.getBlock(blockHash); + } + + @Override + public long getTransactionCount(HashDigest ledgerHash, long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(height); + TransactionSet txset = ledger.getTransactionSet(block); + return txset.getTotalCount(); + } + + @Override + public long getTransactionCount(HashDigest ledgerHash, HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + TransactionSet txset = ledger.getTransactionSet(block); + return txset.getTotalCount(); + } + + @Override + public long getTransactionTotalCount(HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + TransactionSet txset = ledger.getTransactionSet(block); + return txset.getTotalCount(); + } + + @Override + public long getDataAccountCount(HashDigest ledgerHash, long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(height); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getTotalCount(); + } + + @Override + public long getDataAccountCount(HashDigest ledgerHash, HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getTotalCount(); + } + + @Override + public long getDataAccountTotalCount(HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getTotalCount(); + } + + @Override + public long getUserCount(HashDigest ledgerHash, long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(height); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getTotalCount(); + } + + @Override + public long getUserCount(HashDigest ledgerHash, HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getTotalCount(); + } + + @Override + public long getUserTotalCount(HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getTotalCount(); + } + + @Override + public long getContractCount(HashDigest ledgerHash, long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(height); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getTotalCount(); + } + + @Override + public long getContractCount(HashDigest ledgerHash, HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getTotalCount(); + } + + @Override + public long getContractTotalCount(HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getTotalCount(); + } + + @Override + public LedgerTransaction[] getTransactions(HashDigest ledgerHash, long height, int fromIndex, int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock ledgerBlock = ledger.getBlock(height); + TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); + int lastHeightTxTotalNums = 0; + + if (height > 0) { + lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); + } + + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); + // 取当前高度的增量交易数,在增量交易里进行查找 + int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; +// +// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { +// fromIndex = 0; +// } +// if (count == -1) { +// fromIndex = 0; +// count = currentHeightTxNums; +// } +// if (count > currentHeightTxNums) { +// count = currentHeightTxNums - fromIndex; +// } + int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); + return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); + } + + @Override + public LedgerTransaction[] getTransactions(HashDigest ledgerHash, HashDigest blockHash, int fromIndex, int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock ledgerBlock = ledger.getBlock(blockHash); + long height = ledgerBlock.getHeight(); + TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); + int lastHeightTxTotalNums = 0; + + if (height > 0) { + lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); + } + + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); + // 取当前块hash的增量交易数,在增量交易里进行查找 + int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; + +// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { +// fromIndex = 0; +// } +// if (count == -1) { +// fromIndex = 0; +// count = currentHeightTxNums; +// } +// if (count > currentHeightTxNums) { +// count = currentHeightTxNums - fromIndex; +// } + int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); + return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); + } + + @Override + public LedgerTransaction getTransactionByContentHash(HashDigest ledgerHash, HashDigest contentHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + TransactionSet txset = ledger.getTransactionSet(block); + return txset.get(contentHash); + } + + @Override + public TransactionState getTransactionStateByContentHash(HashDigest ledgerHash, HashDigest contentHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + TransactionSet txset = ledger.getTransactionSet(block); + return txset.getTxState(contentHash); + } + + @Override + public UserInfo getUser(HashDigest ledgerHash, String address) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getUser(address); + + } + + @Override + public AccountHeader getDataAccount(HashDigest ledgerHash, String address) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + } + + @Override + public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { + if (keys == null || keys.length == 0) { + return null; + } + 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; + for (int i = 0; i < entries.length; i++) { + final String currKey = keys[i]; + + ver = dataAccount.getDataVersion(Bytes.fromString(currKey)); + + if (ver < 0) { + entries[i] = new KVDataObject(currKey, -1, null); + } else { + BytesValue value = dataAccount.getBytes(Bytes.fromString(currKey), ver); + entries[i] = new KVDataObject(currKey, ver, value); + } + } + + 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, 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, null); + } else { + BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + entries[i] = new KVDataObject(keys[i], ver, value); + } + } + } + + return entries; + } + + @Override + public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { + + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataEntriesTotalCount()); + return dataAccount.getDataEntries(pages[0], pages[1]); + } + + @Override + public long getDataEntriesTotalCount(HashDigest ledgerHash, String address) { + + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + + return dataAccount.getDataEntriesTotalCount(); + } + + @Override + public ContractInfo getContract(HashDigest ledgerHash, String address) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getContract(Bytes.fromBase58(address)); + } + + @Override + public AccountHeader[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) userAccountSet.getTotalCount()); + return userAccountSet.getAccounts(pages[0], pages[1]); + } + + @Override + public AccountHeader[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccountSet.getTotalCount()); + return dataAccountSet.getAccounts(pages[0], pages[1]); + } + + @Override + public AccountHeader[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) contractAccountSet.getTotalCount()); + return contractAccountSet.getAccounts(pages[0], pages[1]); + } + + private LedgerAdministration ledgerAdministration(HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + LedgerAdministration administration = ledger.getAdminAccount(block); + return administration; + } +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java index a5b592ab..da4da430 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java @@ -1,17 +1,11 @@ package com.jd.blockchain.ledger.core.impl.handles; -import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; - import com.jd.blockchain.contract.engine.ContractCode; import com.jd.blockchain.contract.engine.ContractEngine; import com.jd.blockchain.contract.engine.ContractServiceProviders; -import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.ledger.core.ContractAccount; -import com.jd.blockchain.ledger.core.LedgerDataSet; -import com.jd.blockchain.ledger.core.LedgerService; -import com.jd.blockchain.ledger.core.TransactionRequestContext; -import com.jd.blockchain.ledger.core.impl.OperationHandleContext; -import com.jd.blockchain.utils.concurrent.AsyncFuture; + +import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; public class JVMContractEventSendOperationHandle extends AbtractContractEventHandle { diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java index eab81350..41d28ab2 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java @@ -1,45 +1,10 @@ package test.com.jd.blockchain.ledger; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Random; - -import org.junit.Test; -import org.mockito.Mockito; - import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.BlockchainKeyGenerator; -import com.jd.blockchain.ledger.BlockchainKeypair; -import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.BytesData; -import com.jd.blockchain.ledger.EndpointRequest; -import com.jd.blockchain.ledger.LedgerBlock; -import com.jd.blockchain.ledger.LedgerInitSetting; -import com.jd.blockchain.ledger.LedgerTransaction; -import com.jd.blockchain.ledger.NodeRequest; -import com.jd.blockchain.ledger.OperationResult; -import com.jd.blockchain.ledger.TransactionContent; -import com.jd.blockchain.ledger.TransactionContentBody; -import com.jd.blockchain.ledger.TransactionRequest; -import com.jd.blockchain.ledger.TransactionRequestBuilder; -import com.jd.blockchain.ledger.TransactionResponse; -import com.jd.blockchain.ledger.TransactionState; -import com.jd.blockchain.ledger.UserRegisterOperation; -import com.jd.blockchain.ledger.core.LedgerDataSet; -import com.jd.blockchain.ledger.core.LedgerEditor; -import com.jd.blockchain.ledger.core.LedgerRepository; -import com.jd.blockchain.ledger.core.LedgerTransactionContext; -import com.jd.blockchain.ledger.core.UserAccount; +import com.jd.blockchain.ledger.*; +import com.jd.blockchain.ledger.core.*; import com.jd.blockchain.ledger.core.impl.DefaultOperationHandleRegisteration; import com.jd.blockchain.ledger.core.impl.LedgerManager; import com.jd.blockchain.ledger.core.impl.LedgerTransactionalEditor; @@ -48,6 +13,15 @@ import com.jd.blockchain.service.TransactionBatchResultHandle; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.transaction.TxBuilder; import com.jd.blockchain.utils.Bytes; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.Random; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; public class ContractInvokingTest { static { diff --git a/source/ledger/ledger-rpc/pom.xml b/source/ledger/ledger-rpc/pom.xml index cd84bde7..04e46715 100644 --- a/source/ledger/ledger-rpc/pom.xml +++ b/source/ledger/ledger-rpc/pom.xml @@ -36,16 +36,16 @@ - - - - org.apache.maven.plugins - maven-deploy-plugin - 2.8.2 - - true - - - - + + + + + + + + + + + + \ No newline at end of file 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 53f5b36e..341136b0 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,505 +1,506 @@ -package com.jd.blockchain.peer.web; - -import java.util.ArrayList; -import java.util.List; - -import com.jd.blockchain.ledger.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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 com.jd.blockchain.contract.ContractException; -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; - -@RestController -@RequestMapping(path = "/") -public class LedgerQueryController implements BlockchainQueryService { - - @Autowired - private LedgerService ledgerService; - - @RequestMapping(method = RequestMethod.GET, path = "ledgers") - @Override - public HashDigest[] getLedgerHashs() { - return ledgerService.getLedgerHashs(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}") - @Override - public LedgerInfo getLedger(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - // TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher - // ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; - LedgerInfo ledgerInfo = new LedgerInfo(); - ledgerInfo.setHash(ledgerHash); - ledgerInfo.setLatestBlockHash(ledger.getLatestBlockHash()); - ledgerInfo.setLatestBlockHeight(ledger.getLatestBlockHeight()); - return ledgerInfo; - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/participants") - @Override - public ParticipantNode[] getConsensusParticipants(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerAdministration ledgerAdministration = ledger.getAdminInfo(); - long participantCount = ledgerAdministration.getParticipantCount(); - if (participantCount <= 0) { - return null; - } - ParticipantNode[] participantNodes = ledgerAdministration.getParticipants(); - // 重新封装,处理Proxy的问题 - if (participantNodes != null && participantNodes.length > 0) { - ParticipantNode[] convertNodes = new ParticipantNode[participantNodes.length]; - for (int i = 0, length = participantNodes.length; i < length; i++) { - convertNodes[i] = new ParticipantCertData(participantNodes[i]); - } - return convertNodes; - } - return null; - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/metadata") - @Override - public LedgerMetadata getLedgerMetadata(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerAdministration ledgerAdministration = ledger.getAdminInfo(); - LedgerMetadata ledgerMetadata = ledgerAdministration.getMetadata(); - return ledgerMetadata; - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}") - @Override - public LedgerBlock getBlock(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHeight") long blockHeight) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - // TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher - // ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; - return ledger.getBlock(blockHeight); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}") - @Override - public LedgerBlock getBlock(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHash") HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - // TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher - // ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; - return ledger.getBlock(blockHash); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/txs/count") - @Override - public long getTransactionCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHeight") long blockHeight) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHeight); - TransactionSet txSet = ledger.getTransactionSet(block); - return txSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/txs/count") - @Override - public long getTransactionCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHash") HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - TransactionSet txSet = ledger.getTransactionSet(block); - return txSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/txs/count") - @Override - public long getTransactionTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - TransactionSet txSet = ledger.getTransactionSet(block); - return txSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/accounts/count") - @Override - public long getDataAccountCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHeight") long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(height); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/accounts/count") - @Override - public long getDataAccountCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHash") HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/count") - @Override - public long getDataAccountTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/users/count") - @Override - public long getUserCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHeight") long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(height); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/users/count") - @Override - public long getUserCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHash") HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users/count") - @Override - public long getUserTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/contracts/count") - @Override - public long getContractCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHeight") long height) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(height); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/contracts/count") - @Override - public long getContractCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHash") HashDigest blockHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getBlock(blockHash); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/count") - @Override - public long getContractTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/txs") - @Override - public LedgerTransaction[] getTransactions(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHeight") long blockHeight, - @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, - @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { - - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock ledgerBlock = ledger.getBlock(blockHeight); - TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); - int lastHeightTxTotalNums = 0; - - if (blockHeight > 0) { - lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(blockHeight - 1)).getTotalCount(); - } - - int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(blockHeight)).getTotalCount(); - // 取当前高度的增量交易数,在增量交易里进行查找 - int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; - -// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { -// fromIndex = 0; -// } -// if (count == -1) { -// fromIndex = 0; -// count = currentHeightTxNums; -// } -// if (count > currentHeightTxNums) { -// count = currentHeightTxNums - fromIndex; -// } - int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/txs") - @Override - public LedgerTransaction[] getTransactions(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHash") HashDigest blockHash, - @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, - @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock ledgerBlock = ledger.getBlock(blockHash); - long height = ledgerBlock.getHeight(); - TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); - int lastHeightTxTotalNums = 0; - - if (height > 0) { - lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); - } - - int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); - // 取当前块hash的增量交易数,在增量交易里进行查找 - int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; - -// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { -// fromIndex = 0; -// } -// if (count == -1) { -// fromIndex = 0; -// count = currentHeightTxNums; -// } -// if (count > currentHeightTxNums) { -// count = currentHeightTxNums - fromIndex; -// } - int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/txs/{contentHash}") - @Override - public LedgerTransaction getTransactionByContentHash(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "contentHash") HashDigest contentHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - TransactionSet txset = ledger.getTransactionSet(block); - return txset.get(contentHash); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/txs/state/{contentHash}") - @Override - public TransactionState getTransactionStateByContentHash(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "contentHash") HashDigest contentHash) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - TransactionSet txset = ledger.getTransactionSet(block); - return txset.getTxState(contentHash); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users/address/{address}") - @Override - public UserInfo getUser(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - return userAccountSet.getUser(address); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/address/{address}") - @Override - public AccountHeader getDataAccount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getDataAccount(Bytes.fromBase58(address)); - } - - @RequestMapping(method = { RequestMethod.GET, - RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/{address}/entries") - @Override - public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address, @RequestParam("keys") String... keys) { - if (keys == null || keys.length == 0) { - return null; - } - 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; - for (int i = 0; i < entries.length; i++) { - ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); - if (ver < 0) { - entries[i] = new KVDataObject(keys[i], -1, null); - } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); - entries[i] = new KVDataObject(keys[i], ver, value); - } - } - - 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, 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, null); - } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); - entries[i] = new KVDataObject(keys[i], ver, value); - } - } - } - - return entries; - } - - @RequestMapping(method = { RequestMethod.GET, - RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") - @Override - public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address, - @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, - @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { - - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); - - return dataAccount.getDataEntries(fromIndex, count); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries/count") - @Override - public long getDataEntriesTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { - - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); - - return dataAccount.getDataEntriesTotalCount(); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/address/{address}") - @Override - public ContractInfo getContract(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - return contractAccountSet.getContract(Bytes.fromBase58(address)); - } - - /** - * get more users by fromIndex and count; - * - * @param ledgerHash - * @param fromIndex - * @param count - * @return - */ - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users") - @Override - public AccountHeader[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, - @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - UserAccountSet userAccountSet = ledger.getUserAccountSet(block); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) userAccountSet.getTotalCount()); - return userAccountSet.getAccounts(pages[0], pages[1]); - } - - /** - * get more dataAccounts by fromIndex and count; - * - * @param ledgerHash - * @param fromIndex - * @param count - * @return - */ - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts") - @Override - public AccountHeader[] getDataAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, - @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccountSet.getTotalCount()); - return dataAccountSet.getAccounts(pages[0], pages[1]); - } - - @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts") - @Override - public AccountHeader[] getContractAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, - @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { - LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerBlock block = ledger.getLatestBlock(); - ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) contractAccountSet.getTotalCount()); - return contractAccountSet.getAccounts(pages[0], pages[1]); - } - -} +package com.jd.blockchain.peer.web; + +import java.util.ArrayList; +import java.util.List; + +import com.jd.blockchain.ledger.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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 com.jd.blockchain.contract.ContractException; +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; + +@RestController +@RequestMapping(path = "/") +public class LedgerQueryController implements BlockchainQueryService { + + @Autowired + private LedgerService ledgerService; + + @RequestMapping(method = RequestMethod.GET, path = "ledgers") + @Override + public HashDigest[] getLedgerHashs() { + return ledgerService.getLedgerHashs(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}") + @Override + public LedgerInfo getLedger(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + // TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher + // ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; + LedgerInfo ledgerInfo = new LedgerInfo(); + ledgerInfo.setHash(ledgerHash); + ledgerInfo.setLatestBlockHash(ledger.getLatestBlockHash()); + ledgerInfo.setLatestBlockHeight(ledger.getLatestBlockHeight()); + return ledgerInfo; + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/participants") + @Override + public ParticipantNode[] getConsensusParticipants(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerAdministration ledgerAdministration = ledger.getAdminInfo(); + long participantCount = ledgerAdministration.getParticipantCount(); + if (participantCount <= 0) { + return null; + } + ParticipantNode[] participantNodes = ledgerAdministration.getParticipants(); + // 重新封装,处理Proxy的问题 + if (participantNodes != null && participantNodes.length > 0) { + ParticipantNode[] convertNodes = new ParticipantNode[participantNodes.length]; + for (int i = 0, length = participantNodes.length; i < length; i++) { + convertNodes[i] = new ParticipantCertData(participantNodes[i]); + } + return convertNodes; + } + return null; + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/metadata") + @Override + public LedgerMetadata getLedgerMetadata(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerAdministration ledgerAdministration = ledger.getAdminInfo(); + LedgerMetadata ledgerMetadata = ledgerAdministration.getMetadata(); + return ledgerMetadata; + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}") + @Override + public LedgerBlock getBlock(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHeight") long blockHeight) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + // TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher + // ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; + return ledger.getBlock(blockHeight); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}") + @Override + public LedgerBlock getBlock(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHash") HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + // TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher + // ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; + return ledger.getBlock(blockHash); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/txs/count") + @Override + public long getTransactionCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHeight") long blockHeight) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHeight); + TransactionSet txSet = ledger.getTransactionSet(block); + return txSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/txs/count") + @Override + public long getTransactionCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHash") HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + TransactionSet txSet = ledger.getTransactionSet(block); + return txSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/txs/count") + @Override + public long getTransactionTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + TransactionSet txSet = ledger.getTransactionSet(block); + return txSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/accounts/count") + @Override + public long getDataAccountCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHeight") long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(height); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/accounts/count") + @Override + public long getDataAccountCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHash") HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/count") + @Override + public long getDataAccountTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/users/count") + @Override + public long getUserCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHeight") long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(height); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/users/count") + @Override + public long getUserCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHash") HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users/count") + @Override + public long getUserTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/contracts/count") + @Override + public long getContractCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHeight") long height) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(height); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/contracts/count") + @Override + public long getContractCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHash") HashDigest blockHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getBlock(blockHash); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/count") + @Override + public long getContractTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}/txs") + @Override + public LedgerTransaction[] getTransactions(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHeight") long blockHeight, + @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, + @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { + + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock ledgerBlock = ledger.getBlock(blockHeight); + TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); + int lastHeightTxTotalNums = 0; + + if (blockHeight > 0) { + lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(blockHeight - 1)).getTotalCount(); + } + + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(blockHeight)).getTotalCount(); + // 取当前高度的增量交易数,在增量交易里进行查找 + int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; + +// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { +// fromIndex = 0; +// } +// if (count == -1) { +// fromIndex = 0; +// count = currentHeightTxNums; +// } +// if (count > currentHeightTxNums) { +// count = currentHeightTxNums - fromIndex; +// } + int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); + return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/hash/{blockHash}/txs") + @Override + public LedgerTransaction[] getTransactions(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "blockHash") HashDigest blockHash, + @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, + @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock ledgerBlock = ledger.getBlock(blockHash); + long height = ledgerBlock.getHeight(); + TransactionSet transactionSet = ledger.getTransactionSet(ledgerBlock); + int lastHeightTxTotalNums = 0; + + if (height > 0) { + lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); + } + + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); + // 取当前块hash的增量交易数,在增量交易里进行查找 + int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; + +// if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { +// fromIndex = 0; +// } +// if (count == -1) { +// fromIndex = 0; +// count = currentHeightTxNums; +// } +// if (count > currentHeightTxNums) { +// count = currentHeightTxNums - fromIndex; +// } + int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); + return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/txs/{contentHash}") + @Override + public LedgerTransaction getTransactionByContentHash(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "contentHash") HashDigest contentHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + TransactionSet txset = ledger.getTransactionSet(block); + return txset.get(contentHash); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/txs/state/{contentHash}") + @Override + public TransactionState getTransactionStateByContentHash(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "contentHash") HashDigest contentHash) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + TransactionSet txset = ledger.getTransactionSet(block); + return txset.getTxState(contentHash); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users/address/{address}") + @Override + public UserInfo getUser(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "address") String address) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + return userAccountSet.getUser(address); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/address/{address}") + @Override + public AccountHeader getDataAccount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "address") String address) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + return dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + } + + @RequestMapping(method = { RequestMethod.GET, + RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/{address}/entries") + @Override + public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "address") String address, @RequestParam("keys") String... keys) { + if (keys == null || keys.length == 0) { + return null; + } + 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; + for (int i = 0; i < entries.length; i++) { + ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); + if (ver < 0) { + entries[i] = new KVDataObject(keys[i], -1, null); + } else { + BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + entries[i] = new KVDataObject(keys[i], ver, value); + } + } + + 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, 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, null); + } else { + BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + entries[i] = new KVDataObject(keys[i], ver, value); + } + } + } + + return entries; + } + + @RequestMapping(method = { RequestMethod.GET, + RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") + @Override + public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "address") String address, + @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, + @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { + + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataEntriesTotalCount()); + return dataAccount.getDataEntries(pages[0], pages[1]); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries/count") + @Override + public long getDataEntriesTotalCount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "address") String address) { + + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); + + return dataAccount.getDataEntriesTotalCount(); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/address/{address}") + @Override + public ContractInfo getContract(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @PathVariable(name = "address") String address) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + return contractAccountSet.getContract(Bytes.fromBase58(address)); + } + + /** + * get more users by fromIndex and count; + * + * @param ledgerHash + * @param fromIndex + * @param count + * @return + */ + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users") + @Override + public AccountHeader[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, + @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + UserAccountSet userAccountSet = ledger.getUserAccountSet(block); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) userAccountSet.getTotalCount()); + return userAccountSet.getAccounts(pages[0], pages[1]); + } + + /** + * get more dataAccounts by fromIndex and count; + * + * @param ledgerHash + * @param fromIndex + * @param count + * @return + */ + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts") + @Override + public AccountHeader[] getDataAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, + @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccountSet.getTotalCount()); + return dataAccountSet.getAccounts(pages[0], pages[1]); + } + + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts") + @Override + public AccountHeader[] getContractAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, + @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { + LedgerRepository ledger = ledgerService.getLedger(ledgerHash); + LedgerBlock block = ledger.getLatestBlock(); + ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) contractAccountSet.getTotalCount()); + return contractAccountSet.getAccounts(pages[0], pages[1]); + } + +} diff --git a/source/pom.xml b/source/pom.xml index f2a8ac32..ddd514bf 100644 --- a/source/pom.xml +++ b/source/pom.xml @@ -81,19 +81,6 @@ 3.4.2 - - - junit - junit - test - - - org.mockito - mockito-core - test - - - diff --git a/source/sdk/sdk-base/pom.xml b/source/sdk/sdk-base/pom.xml index 688b689b..1618061c 100644 --- a/source/sdk/sdk-base/pom.xml +++ b/source/sdk/sdk-base/pom.xml @@ -1,58 +1,65 @@ - - 4.0.0 - - com.jd.blockchain - sdk - 1.0.0.RELEASE - - sdk-base - - - - - com.jd.blockchain - ledger-model - ${project.version} - - - - com.jd.blockchain - consensus-framework - ${project.version} - - - binary-proto - com.jd.blockchain - - - crypto-framework - com.jd.blockchain - - - utils-common - com.jd.blockchain - - - - - - com.jd.blockchain - utils-serialize - ${project.version} - - - utils-common - com.jd.blockchain - - - - - - + + 4.0.0 + + com.jd.blockchain + sdk + 1.0.0.RELEASE + + sdk-base + + + + + com.jd.blockchain + ledger-model + ${project.version} + + + + com.jd.blockchain + consensus-framework + ${project.version} + + + binary-proto + com.jd.blockchain + + + crypto-framework + com.jd.blockchain + + + utils-common + com.jd.blockchain + + + + + + com.jd.blockchain + utils-serialize + ${project.version} + + + utils-common + com.jd.blockchain + + + + + + org.mockito + mockito-core + ${mockito.version} + test + + + + \ No newline at end of file diff --git a/source/sdk/sdk-base/src/test/java/test/com/jd/blockchain/sdk/proxy/BlockchainServiceProxyTest.java b/source/sdk/sdk-base/src/test/java/test/com/jd/blockchain/sdk/proxy/BlockchainServiceProxyTest.java index a4a5c45a..6387bd48 100644 --- a/source/sdk/sdk-base/src/test/java/test/com/jd/blockchain/sdk/proxy/BlockchainServiceProxyTest.java +++ b/source/sdk/sdk-base/src/test/java/test/com/jd/blockchain/sdk/proxy/BlockchainServiceProxyTest.java @@ -1,95 +1,91 @@ -package test.com.jd.blockchain.sdk.proxy; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; - -public class BlockchainServiceProxyTest { - -// private static class ArgCaptorMatcher extends CustomMatcher { -// -// private T arg; -// -// public ArgCaptorMatcher() { -// super("OK"); -// } -// -// @Override -// public boolean matches(Object item) { -// this.arg = (T) item; -// return true; -// } -// -// public T getArg() { -// return arg; -// } -// } -// -// @Test -// public void testRegisterAccount() throws IOException { -// -// BlockchainKeyPair gatewayAccount = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); -// BlockchainKeyPair sponsorAccount = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); -// BlockchainKeyPair subjectAccount = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); -// long sequenceNumber = 110; -// -// ArgCaptorMatcher txReqCaptor = new ArgCaptorMatcher<>(); -// -// TransactionService consensusService = Mockito.mocker(TransactionService.class); -// BlockchainQueryService queryService = Mockito.mocker(BlockchainQueryService.class); -// -// HashDigest txContentHash =CryptoUtils.hash(CryptoAlgorithm.SHA_256).hash(UUID.randomUUID().toString().getBytes("UTF-8")); -// TxResponseMessage expectedResponse = new TxResponseMessage(txContentHash); -// expectedResponse.setExecutionState(ExecutionState.SUCCESS); -// -// when(consensusService.process(argThat(txReqCaptor))).thenReturn(expectedResponse); -// -// HashDigest ledgerHash = CryptoUtils.hash(CryptoAlgorithm.SHA_256).hash(UUID.randomUUID().toString().getBytes("UTF-8")); -// -// BlockchainTransactionService serviceProxy = new BlockchainServiceProxy(consensusService, queryService); -// -// TransactionTemplate txTemplate = serviceProxy.newTransaction(ledgerHash); -// txTemplate.setSubject(subjectAccount.getAddress(), sequenceNumber); -// -// BlockchainKeyPair regAccountKeyPair = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); -// AccountStateType stateType = AccountStateType.MAP; -// txTemplate.users().register(regAccountKeyPair.getIdentity(), stateType); -// -// PreparedTransaction prepTx = txTemplate.prepare(); -// HashDigest txHash = prepTx.getHash(); -// prepTx.sign(sponsorAccount); -// -// TransactionResponse result = prepTx.commit(); -// -// // 验证; -// // 仅被提交一次; -// verify(consensusService, times(1)).process(any()); -// -// assertEquals(ExecutionState.SUCCESS, result.getExecutionState()); -// -// // 验证内容; -// TransactionRequest resolvedTxRequest = txReqCaptor.getArg(); -// -// TransactionContent resolvedTxContent = resolvedTxRequest.getTransactionContent(); -// -// assertEquals(txHash, resolvedTxContent.getHash()); -// -// assertEquals(subjectAccount.getAddress(), resolvedTxContent.getSubjectAccount()); -// assertEquals(sequenceNumber, resolvedTxContent.getSequenceNumber()); -// -// -// Operation[] resolvedOps = resolvedTxContent.getOperations(); -// assertEquals(1, resolvedOps.length); -// Operation resolvedOP = resolvedOps[0]; -//// assertEquals(OperationType.REGISTER_USER.CODE, resolvedOP.getCode()); -// -// UserRegisterOpTemplate accRegOP = new UserRegisterOpTemplate(); -// accRegOP.resolvFrom((OpBlob) resolvedOP); -// -// assertEquals(regAccountKeyPair.getAddress(), accRegOP.getId().getAddress()); -// assertEquals(regAccountKeyPair.getPubKey().getType(), accRegOP.getId().getPubKey().getType()); -// assertEquals(regAccountKeyPair.getPubKey().getValue(), accRegOP.getId().getPubKey().getValue()); -// assertEquals(stateType, accRegOP.getStateType()); -// } - -} +package test.com.jd.blockchain.sdk.proxy; + +public class BlockchainServiceProxyTest { + +// private static class ArgCaptorMatcher extends CustomMatcher { +// +// private T arg; +// +// public ArgCaptorMatcher() { +// super("OK"); +// } +// +// @Override +// public boolean matches(Object item) { +// this.arg = (T) item; +// return true; +// } +// +// public T getArg() { +// return arg; +// } +// } +// +// @Test +// public void testRegisterAccount() throws IOException { +// +// BlockchainKeyPair gatewayAccount = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); +// BlockchainKeyPair sponsorAccount = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); +// BlockchainKeyPair subjectAccount = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); +// long sequenceNumber = 110; +// +// ArgCaptorMatcher txReqCaptor = new ArgCaptorMatcher<>(); +// +// TransactionService consensusService = Mockito.mocker(TransactionService.class); +// BlockchainQueryService queryService = Mockito.mocker(BlockchainQueryService.class); +// +// HashDigest txContentHash =CryptoUtils.hash(CryptoAlgorithm.SHA_256).hash(UUID.randomUUID().toString().getBytes("UTF-8")); +// TxResponseMessage expectedResponse = new TxResponseMessage(txContentHash); +// expectedResponse.setExecutionState(ExecutionState.SUCCESS); +// +// when(consensusService.process(argThat(txReqCaptor))).thenReturn(expectedResponse); +// +// HashDigest ledgerHash = CryptoUtils.hash(CryptoAlgorithm.SHA_256).hash(UUID.randomUUID().toString().getBytes("UTF-8")); +// +// BlockchainTransactionService serviceProxy = new BlockchainServiceProxy(consensusService, queryService); +// +// TransactionTemplate txTemplate = serviceProxy.newTransaction(ledgerHash); +// txTemplate.setSubject(subjectAccount.getAddress(), sequenceNumber); +// +// BlockchainKeyPair regAccountKeyPair = BlockchainKeyGenerator.getInstance().generate(CryptoKeyType.ED25519); +// AccountStateType stateType = AccountStateType.MAP; +// txTemplate.users().register(regAccountKeyPair.getIdentity(), stateType); +// +// PreparedTransaction prepTx = txTemplate.prepare(); +// HashDigest txHash = prepTx.getHash(); +// prepTx.sign(sponsorAccount); +// +// TransactionResponse result = prepTx.commit(); +// +// // 验证; +// // 仅被提交一次; +// verify(consensusService, times(1)).process(any()); +// +// assertEquals(ExecutionState.SUCCESS, result.getExecutionState()); +// +// // 验证内容; +// TransactionRequest resolvedTxRequest = txReqCaptor.getArg(); +// +// TransactionContent resolvedTxContent = resolvedTxRequest.getTransactionContent(); +// +// assertEquals(txHash, resolvedTxContent.getHash()); +// +// assertEquals(subjectAccount.getAddress(), resolvedTxContent.getSubjectAccount()); +// assertEquals(sequenceNumber, resolvedTxContent.getSequenceNumber()); +// +// +// Operation[] resolvedOps = resolvedTxContent.getOperations(); +// assertEquals(1, resolvedOps.length); +// Operation resolvedOP = resolvedOps[0]; +//// assertEquals(OperationType.REGISTER_USER.CODE, resolvedOP.getCode()); +// +// UserRegisterOpTemplate accRegOP = new UserRegisterOpTemplate(); +// accRegOP.resolvFrom((OpBlob) resolvedOP); +// +// assertEquals(regAccountKeyPair.getAddress(), accRegOP.getId().getAddress()); +// assertEquals(regAccountKeyPair.getPubKey().getType(), accRegOP.getId().getPubKey().getType()); +// assertEquals(regAccountKeyPair.getPubKey().getValue(), accRegOP.getId().getPubKey().getValue()); +// assertEquals(stateType, accRegOP.getStateType()); +// } + +} diff --git a/source/sdk/sdk-mq/pom.xml b/source/sdk/sdk-mq/pom.xml deleted file mode 100644 index 5a735573..00000000 --- a/source/sdk/sdk-mq/pom.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - sdk - com.jd.blockchain - 0.9.0-SNAPSHOT - - 4.0.0 - - sdk-mq - - - UTF-8 - 1.8 - 1.8 - - - - - junit - junit - 4.11 - test - - - com.jd.blockchain - sdk-base - ${project.version} - - - com.lmax - disruptor - - - io.nats - jnats - - - - - - - diff --git a/source/state-transfer/pom.xml b/source/state-transfer/pom.xml deleted file mode 100644 index d17c8e03..00000000 --- a/source/state-transfer/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - 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 deleted file mode 100644 index 237a6d47..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java +++ /dev/null @@ -1,75 +0,0 @@ -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 deleted file mode 100644 index aaf6e7f5..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceElement.java +++ /dev/null @@ -1,53 +0,0 @@ -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 deleted file mode 100644 index 6f0f2e10..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequenceInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -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 deleted file mode 100644 index e137b929..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReader.java +++ /dev/null @@ -1,39 +0,0 @@ -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 deleted file mode 100644 index 3d581b2d..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -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 deleted file mode 100644 index b45eb3ac..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java +++ /dev/null @@ -1,30 +0,0 @@ -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 deleted file mode 100644 index c510e843..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java +++ /dev/null @@ -1,142 +0,0 @@ -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 需要更新到本地结点的数据序列元素List - * @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 deleted file mode 100644 index 9e0afbe5..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/comparator/DataSequenceComparator.java +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index 5e6248c0..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/exception/DataSequenceException.java +++ /dev/null @@ -1,21 +0,0 @@ -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 deleted file mode 100644 index 6c67e8c8..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSDefaultMessageExecutor.java +++ /dev/null @@ -1,80 +0,0 @@ -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; - -/** - * 数据序列差异提供者使用,解析收到的差异请求消息并产生响应 - * @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 请求消息的Key - * @param data 需要解码的字节数组 - * @param session 指定响应需要使用的目标结点会话 - * @return 配置为自动响应时,返回值为响应的字节数组,配置为手动响应时,不需要关注返回值 - */ - - @Override - public byte[] receive(String key, byte[] data, RemoteSession session) { - - try { - Object object = DSMsgResolverFactory.getDecoder(dsWriter, dsReader).decode(data); - - // 解析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)); - } - // 解析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 deleted file mode 100644 index c0dfae8d..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DSMsgResolverFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.jd.blockchain.statetransfer.message; - -import com.jd.blockchain.statetransfer.callback.DataSequenceReader; -import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; - -/** - * 数据序列消息解析器工厂 - * @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); - } - - /** - * 获得数据序列消息解码器实例 - * @param dsWriter 差异请求者执行数据序列更新的执行器 - * @param dsReader 差异响应者执行数据序列读取的执行器 - * @return 消息解码器实例 - */ - 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 deleted file mode 100644 index a4131e61..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceLoadMessage.java +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 6bfa4c97..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgDecoder.java +++ /dev/null @@ -1,107 +0,0 @@ -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; - -/** - * 数据序列消息解码器 - * @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 解码后的对象 - */ - 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 deleted file mode 100644 index 71b3ef4c..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/message/DataSequenceMsgEncoder.java +++ /dev/null @@ -1,133 +0,0 @@ -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与toHeight相同的情况,即每次只对一个高度的差异内容进行编码并响应 - * 把消息编码成字节数组,再交给通信层传输 - * @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,获得这个高度上的所有差异的数据序列内容,并组织成DataSequenceElement结构 - 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 deleted file mode 100644 index 97b14602..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSProcessManager.java +++ /dev/null @@ -1,186 +0,0 @@ -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 deleted file mode 100644 index 45fc89fb..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/process/DSTransferProcess.java +++ /dev/null @@ -1,216 +0,0 @@ -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 对差异字节数组的解码结果 - */ - 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 deleted file mode 100644 index af62bd6c..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSDiffRequestResult.java +++ /dev/null @@ -1,45 +0,0 @@ -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 deleted file mode 100644 index 7f6d48cc..00000000 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/result/DSInfoResponseResult.java +++ /dev/null @@ -1,37 +0,0 @@ -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 deleted file mode 100644 index 5741262e..00000000 --- a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java +++ /dev/null @@ -1,155 +0,0 @@ -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() { - - // 产生两个唯一的数据序列Id标识 - 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/storage/storage-redis/pom.xml b/source/storage/storage-redis/pom.xml index d8ec1035..2e9580d9 100644 --- a/source/storage/storage-redis/pom.xml +++ b/source/storage/storage-redis/pom.xml @@ -1,42 +1,46 @@ - - 4.0.0 - - com.jd.blockchain - storage - 1.0.0.RELEASE - - storage-redis - - - - com.jd.blockchain - storage-service - ${project.version} - - - com.jd.blockchain - utils-common - ${project.version} - - - org.springframework.boot - spring-boot - - - org.springframework.boot - spring-boot-autoconfigure - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - redis.clients - jedis - - - + + 4.0.0 + + com.jd.blockchain + storage + 1.0.0.RELEASE + + storage-redis + + + + com.jd.blockchain + storage-service + ${project.version} + + + com.jd.blockchain + utils-common + ${project.version} + + + org.springframework.boot + spring-boot + + + org.springframework.boot + spring-boot-autoconfigure + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + redis.clients + jedis + + + junit + junit + + + \ No newline at end of file diff --git a/source/storage/storage-rocksdb/pom.xml b/source/storage/storage-rocksdb/pom.xml index 806fab58..abce4bbb 100644 --- a/source/storage/storage-rocksdb/pom.xml +++ b/source/storage/storage-rocksdb/pom.xml @@ -31,6 +31,10 @@ org.apache.commons commons-collections4 + + junit + junit + - - - - - - - - - - - - - - - - - - - - - - - org.apache.maven.plugins maven-surefire-plugin @@ -142,29 +124,6 @@ true - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - - - - - - - - - - - - - - diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java new file mode 100644 index 00000000..a47e4eb6 --- /dev/null +++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java @@ -0,0 +1,221 @@ +package com.jd.blockchain; + +import com.jd.blockchain.utils.ConsoleUtils; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.shared.invoker.*; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + + +@Mojo(name = "contractCheck") +public class ContractCheckMojo extends AbstractMojo { + Logger logger = LoggerFactory.getLogger(ContractCheckMojo.class); + + @Parameter(defaultValue = "${project}", required = true, readonly = true) + private MavenProject project; + + /** + * jar's name; + */ + @Parameter + private String finalName; + + + /** + * mainClass; + */ + @Parameter + private String mainClass; + /** + * ledgerVersion; + */ + @Parameter + private String ledgerVersion; + + /** + * mvnHome; + */ + @Parameter + private String mvnHome; + + /** + * first compile the class, then parse it; + */ + @Override + public void execute() { + this.compileFiles(); + + } + + private void compileFiles(){ + // 获取当前项目pom.xml文件所在路径 +// URL targetClasses = this.getClass().getClassLoader().getResource(""); +// File file = new File(targetClasses.getPath()); +// String pomXmlPath = file.getParentFile().getParent() + File.separator + "pom.xml"; + + FileInputStream fis = null; + try { +// fis = new FileInputStream(new File(pomXmlPath)); + fis = new FileInputStream(project.getFile()); + MavenXpp3Reader reader = new MavenXpp3Reader(); + Model model = reader.read(fis); + + //delete this plugin(contractCheck) from destination pom.xml;then add the proper plugins; + Plugin plugin = model.getBuild().getPluginsAsMap().get("com.jd.blockchain:contract-maven-plugin"); + if(plugin == null){ + plugin = model.getBuild().getPluginsAsMap().get("org.apache.maven.plugins:contract-maven-plugin"); + } + + if(plugin == null) { + return; + } + + model.getBuild().removePlugin(plugin); +// model.getBuild().setPlugins(null); + +// ConsoleUtils.info("----- 不携带Plugin -----"); +// print(model); + + List plugins = new ArrayList<>(); + plugins.add(createAssembly()); + plugins.add(createCheckImports()); + + model.getBuild().setPlugins(plugins); + + ConsoleUtils.info("----- add Plugin -----"); + handle(model); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void invokeCompile(File file) { + InvocationRequest request = new DefaultInvocationRequest(); + + Invoker invoker = new DefaultInvoker(); + try { + request.setPomFile(file); + + request.setGoals( Collections.singletonList( "verify" ) ); +// request.setMavenOpts("-DmainClass="+mainClass); + invoker.setMavenHome(new File(mvnHome)); + invoker.execute(request); + } catch (MavenInvocationException e) { + e.printStackTrace(); + } + } + + private Plugin createCheckImports() { + Plugin plugin = new Plugin(); + plugin.setGroupId("com.jd.blockchain"); + plugin.setArtifactId("contract-maven-plugin"); + plugin.setVersion(ledgerVersion); + + Xpp3Dom finalNameNode = new Xpp3Dom("finalName"); + finalNameNode.setValue(finalName); + Xpp3Dom configuration = new Xpp3Dom("configuration"); + configuration.addChild(finalNameNode); + plugin.setConfiguration(configuration); + + PluginExecution pluginExecution = new PluginExecution(); + pluginExecution.setId("make-assembly"); + pluginExecution.setPhase("verify"); + List goals = new ArrayList<>(); + goals.add("checkImports"); + pluginExecution.setGoals(goals); + List pluginExecutions = new ArrayList<>(); + pluginExecutions.add(pluginExecution); + plugin.setExecutions(pluginExecutions); + + return plugin; + } + + private Plugin createAssembly() { + Plugin plugin = new Plugin(); + plugin.setArtifactId("maven-assembly-plugin"); + + Xpp3Dom configuration = new Xpp3Dom("configuration"); + + Xpp3Dom mainClassNode = new Xpp3Dom("mainClass"); + mainClassNode.setValue(mainClass); + + Xpp3Dom manifest = new Xpp3Dom("manifest"); + manifest.addChild(mainClassNode); + + Xpp3Dom archive = new Xpp3Dom("archive"); + archive.addChild(manifest); + + Xpp3Dom finalNameNode = new Xpp3Dom("finalName"); + finalNameNode.setValue(finalName); + + Xpp3Dom appendAssemblyId = new Xpp3Dom("appendAssemblyId"); + appendAssemblyId.setValue("false"); + + Xpp3Dom descriptorRef = new Xpp3Dom("descriptorRef"); + descriptorRef.setValue("jar-with-dependencies"); + Xpp3Dom descriptorRefs = new Xpp3Dom("descriptorRefs"); + descriptorRefs.addChild(descriptorRef); + + configuration.addChild(finalNameNode); + configuration.addChild(appendAssemblyId); + configuration.addChild(archive); + configuration.addChild(descriptorRefs); + plugin.setConfiguration(configuration); + + PluginExecution pluginExecution = new PluginExecution(); + pluginExecution.setId("make-assembly"); + pluginExecution.setPhase("package"); + List goals = new ArrayList<>(); + goals.add("single"); + pluginExecution.setGoals(goals); + List pluginExecutions = new ArrayList<>(); + pluginExecutions.add(pluginExecution); + plugin.setExecutions(pluginExecutions); + return plugin; + } + + private void handle(Model model) throws IOException { + MavenXpp3Writer mavenXpp3Writer = new MavenXpp3Writer(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + mavenXpp3Writer.write(outputStream, model); + + byte[] buffer = outputStream.toByteArray(); + + //输出文件 +// File fileOutput = new File("fileOut.xml"); +// File fileOutput = File.createTempFile("fileOut",".xml"); + File fileOutput = new File(project.getBasedir().getPath(),"fileOut.xml"); + fileOutput.createNewFile(); + + ConsoleUtils.info("fileOutput's path="+fileOutput.getPath()); + //创建文件输出流对象 + FileOutputStream fos = new FileOutputStream(fileOutput); + //将字节数组fileInput中的内容输出到文件fileOut.xml中; + ConsoleUtils.info(new String(buffer)); + fos.write(buffer); + invokeCompile(fileOutput); + fos.close(); + } +} diff --git a/source/contract/contract-maven-plugin/src/test/resources/project-to-test/pom.xml b/source/contract/contract-maven-plugin/src/test/resources/project-to-test/pom.xml index ea7962e8..80bf8e27 100644 --- a/source/contract/contract-maven-plugin/src/test/resources/project-to-test/pom.xml +++ b/source/contract/contract-maven-plugin/src/test/resources/project-to-test/pom.xml @@ -16,7 +16,7 @@ - contract1 + contract diff --git a/source/contract/contract-maven-plugin/src/test/resources/project-to-test/target/contract.jar b/source/contract/contract-maven-plugin/src/test/resources/project-to-test/target/contract.jar index 7c172d0edcb2a34e5aeecddac90a767afd4c204a..8e693437b273ffb193daabddc9ba9a683c034e26 100644 GIT binary patch literal 5330 zcmb7I1yod9+a5w1q+96*Ndc*m8eo6{N$Kt!xe&2Q0yWaC?s$yW`0lp3ooe9WalW!N?i@Um_jx3)F z1jMiT4Tb}NUcmB0-#tpdc-?YwlK%`-mxZW+6t#7(se=@IkwoE)~dO4CFwVEFy%LV!@r9RO7zK`&M9urt@AMYQjc008d41dMqRiItnnKe7HN0{a`n z(fSV{(jOp8XE!S+D|-tE*FWItev7wqbM^ADu=4tci1XKey`%U9vC#m4-HVg&&qOU7 z3v2mrD%Y%>Ej&F_HB3}dH;J=dthDKXhIc+s=B;hlfqKF zN6p>FWT)QwRjI-33f__!fn>U8Y8Wvt-SO|D-$gKs!EB5TW zeawpcoM>8i&4Qb+a=dzWp29}(YEPQISg%Qm(MvPWwYi0Or?FkTt)^3qchJs~E?ksE zup-<9OLEj{`rNj#D5@Fz`xo$cMiI%&21^(KK;XsqF8F`XsEUib^S7+(-tr|=B>&8= zf^?}ADXgY=%gs5UK2)yBLmFqU9!D-0M+mAo6&NE}t9|X-x5YjLoR8!G3}9Hl!T8>D zHVOMKT*b+PSmr4@Q8F#SZFvJtxL zu^F6k9JMS#rv$3w124cu3xpE~a?uBKOnAt~_5<3wr>EoE@*+~hwLz04bKyThX#pTF?S-h150(ccCY8V;tA!%)aWkVf~S^Z1}~! z*V0|5Qe;}ZxSebwksI>c;Fd!;q#8XMAhLW5ddl_!Vq;RBmB_S}UO8{u(6bf`JI(Xh z?z1##=bhFPj1b1#D&d?BjdghQWVD$bWi58=(q-MC2);{-6!&&&Vo95B?ebmaIfk^0 zHraI%+&b-)b58S(kX2dd031(z9;hIEN;zNkk;T{k@-jAozmU(X=jQ3p@%U%F=!YmI zT;cwF*JtktK>(o~D7m|3ELfpqS)Wwt-lkcE<el$B z137z7iC4ngMKST23cS!5?qj2(>XoZ7KgE#7ynY~cPLL!YKVWi9P@%TT24Ya6ijC5= z9PMiAP&?G!q++caY?qH0JWJfg@R=n`+I<{EKm#Ru;DApV6S0^~R6b#x<{tAtgTEI} z&U9{IuS^2TthO@0YjsN&3x7YAv4{7(tp4*Y3ul;Big8m_T#a>RWOZYAn^u!~H4Ow9&oj1}M&FTB zqA(0lua~&;*n=q|)s>ySNx;>|Ly?Nh-wuyj)MMS+yiF=y?78~az>3imVE_9<+?QsOmsOsoZWH71>G0s- zxL_K)x!1JYMfu*&?^S^HN{|SW@P}S!w#|?GAThXPAW2YDjx6A=#}2~ycYc8{nY+$$ z007I2=HmLFYx1x8{ZW@o^&R}k?XG<3HLdD|(cdr3!jj-BShVIV#DyW)nQCxfxHGv# z>#!r?))rOpJ_!1*y{?u^$w6Cqt(HPWfTpaGTw77_PRq*L-tm-M@Ltx;9l!G9Ksz6? z5xlret7YK!S^vxzznPQOg&BVI(U=oPay3lNIBOgZcP&jW8aPvd1xz4CVQdxd5u_2H^;!1%hzP+IVK@{XU|WO{tA zvVxK}=*&7uPPGUDZ4#-er}*%O)TBq@P#LFazpdU?24Ta_`j%45ybodk(h;CnPTZhj zTAavI<0w5Ro%BACCzZ+p$vw~<&r;hsABH0u{BP5#LksgqqMeGFdevfAHuF0(m2I~c zHZ8PO?K-@KSGT- zB2yOciV5F;uTc^EKn|)&OB<~+8ZaY8M5vj1w}ZrX*@R`kKTn&GOKr8UG1S zTrFRc zl5G{r<%i)0_Op&DluRA!tRXk*AKEijep1}~r1z7qX-&$LaszLpY09sws629b`*(=ctzyL{X$54U@vS zL-N^TkaO?6P;u{5L_?XGiLpEvB@pUxEURTaf6lmG&B7jR{G) zqD7q?I)U^OHxIr4fr9MI(sS2JQr^u+EDe*?I*i3z$++ zc&K-{QJfKNbNMlhuqiOOQ#I7Vrmln+F}0ds)S)3YO1}k+QSAxy;y(?{%UjShfq_9 zqu$&w%EJosm}(ltjo%d;Lj~r2_X>uJsK={!^~IJgcra)~=;h8?WOTB%oen7?ZBSYG z^hJzt(od-2T~4i`515*J)>5PYOUr9MMQfw%fOsN41n`AwYh**1a*wc~qagz|yu8V^ z9Ze~o9ZGE-c{x@-Qsb_Lp{kAE68nQTL^YeEET@qRPY>$7@-4eG8>>g_t0Xt3_4MDI z+;q=9adT>l9=^FNO-vGG$bI8!g5#hdpH)tmK!kKfXmIX0uRL+0K`s%#tUf0XU9=6y z?Q60L3eA)EZnNe`BXI?x9beAIqMK>K{r*6KMdVeQf zf4n|Kiz?HRvphtIA@^l`Z>`RY&NNa`8G@NZzhb&hZLGX*8A~+USAVT|BGFY+t})Gu z>^)gFVf+))K#~p;Da`Ph81|>fT(=YU7VEo^H!XmI{$a)%`4Qw+ee+CD^foI68(>of z#-i^)GGa?+?N`D6757Tm+`r%}S#KUqg1jjdb6YvCaGEILE(ORnII*Qn^QNG3mwB_B zqPHo-NM`bnT%L&HrShO$`sRr3Q!z?IZ#r=f7?SSRq=LXyM%|NqOQ}n#HdIhfEklDQ zL@BdYMTh{;yo6{j%651EJ`Bk0aYeVZ(vN%$&!hvzV|K}-47}W3*yB4x*kjQ@R#!O| zRDVQcUVN9tA;~RpmHk-IeAy!OdHF$gm9#{(2S?Io z<*uXq{>lUk16LU&P-jnHVW}2@*X)g5<29*XBun4jmo~EcWOWF?U3|S{)T`!(n4y%# zJ!-x_?h~=P3N_PR`Y-ZN)P3rXdCp1vcbU6cJlNJAV6U7#o4GsLwmer9Ep<<6{EQ?| za{k^FOoD#57g5AlJ`|yBj&`q-EIetJ(Aj{yktk(sNk739eWIW~A{wG!0Zm>!zihi7E*-Y0#Y)oT;kzeMZJckR$9CzXWvcB=@oYn3OV>l{^{% zBI$Pw?go)M)jdinmGd@T)>Ss32m=pf#~le8d7RB?s-mHjWBhkx=c1{)7{q`NvS05% z**xEAzc+fmg1?S}P>zf1KeV50pPv{0ox$=K{jY_0FQ$LnE#KGtz2WkML3Yt{e`Wk- zzx;R7R|Dn;N&E-tUv|uY=YKV1e(>#o%m2xq`7ZQ(gXX(bLFl7D3;m~E^COkNcPf5J z?_KS4K^j7Upf58wGntt$ zcfNH`ug6yJz0XrsKf1cMq6{PyJj8FyOs7-+_nRLlxTmX}n5q!Hl)N~j;tv=sgy|D3 z{_$%|^3&IyPY3#6VRAz9QsQDNstj`CVq>i@dx)@tHZudgHeiU#4-H!CGuen89N9a; zI#uX6Ip6HRWo=*cpMs^pmx0t@`3FqiR%%hhOQ#h_=rKKb?1OnIFA)-)QHb;Rj?2x) zpoWR!t8$78GRsHoI&op|UvzZl+&As%@VCj&=W!*diG@Oa@z^ISOeHnuRdwEYYIpJ~SZCEnQ1*4fd}*!fQ)?CPfb7EdX8>WmtE>M9{J+O8# zsJ-N3m`f$Wa{$zSF;GLQ%aBmswOs8;z|3+;sAaqg%nFwhhuphj;a z(OKTBhpDW}Yo48Wq7}O3BcCfyW9htEU7cL{MLV@f&k$XJ&7DgfQO0ADl||}f_2o!1 z(|77CMNr*2Bp^4~-4o6bNh;;maJYvTmeU0b#)vSVAr^X9NOj9zLd^Yz_p?7L{+|po zq|Gw%JY^3R5(0wpf5;%qe^OW&yCx4{Mt(OzBnY2JWwixq(FJ9VT-ju##P}jKlx#J* zuzPD-u0apghmFx2f^c}z_RgPu z!hv0FhXHFrNJ8AsD=Xq`^ul|B*(Z{{3)hGt7c^$^drmt$sY`xT&RlqJ6b2 zD+kNus27{?V?oVExfEB$76{clWgHMi zP6mt)+@k#3F!pL=5$q$1kMBNo@&3IGdz*;+5U>ys2PhB_EdN6pq-^X#KPsVd>x8y| z@lZi;sWH991$YqvH3A*>0t%YRg(-UL719b{fT~h(oily;aXoo?ODjwUhfj<^+@#y| zbITiPLaA&xYG!iTnTN^L(TmQ5=*&Y|-!UZFmD3aH8c<18YQ*uH(<%S{>S@MprqhD& zpAzz4sgki7JhIo#Fe77lvMuEFpcUxEy$s`!Ns%8A#B;9LQybl@=b8iI8xCJpt>6Sz9x(2ps+-BxqfVV zmY4=nn|yFi##Wti6dSNPwRt9!TATX7{A{cVl%Pw~G@zzoaH=^@^WN;dBs3r~eN66) z8Fk`zUitp&tbrI-1#9l@q+zW|iv+ZG{F;`3S5D$S1yV#R`Sz%;Lr)d!jc9kwVp#_8 zU8ml47iasy{fg|lg_lT@|(zG zzZ`4e3?Is3Y*qhkA{QyXxir!nF~)Y_I@nJk4oxa(x>z!G6m#-f*#)S*y9eSmZuaz7 zKQ(uDH5&Lh)ZS)cea5<+wmLA2SE+xYS{rnnqCTWjK4d*zk(JJ0p4`r=YA@RjF*M$y zXfM+3psYvqCaak>TzuYH*6Lfbbl>OcETt1&_7PZa#p!TV{cl}_Q{?y|c0DO|pk5WU z1F3aRCvxKX-Lx{M<(l0lj0v=>Qx7#54JUD}z208ph^rERaaPPPpJV8k4uqs|h4H^0 z5PL}8khN+^&E*_&)x32klfXG-TpMib<+j8)57MJ8C^lE)ZmG^3u{U{WHNuhHp_X1l`@oQmnmhksMLY3?qT^{I!pw9Cmv!<_Z}Nl_qOh=R2|`lsC(Sa)N;mRZ}BFy?N$UAG4bZn#jl=WbH0qigz>?u^RG zr*X%#$;w_IzYi~}s(U8&Rd6fmQ;HS8&UnYW1#X>%OjHR}&~ZIXe{K-;sydhw(GASe z2pS0Y0fc4Wk;+ghMl#n6Pq$kMn(J_%r%zq!Guy;*H!mBbF1Cbu>PU}z46=u{8JBZ2 zlwEz8s8ilg@kur}I1roPU#6IOQA;NQ&0^~l|3NwFSh||yi~R++Y193>9G0Z(h!=B8 z8yArtbf#msv#E+@joOTi6TTiIhif5I(LFOljz@5*@WmWvr=&Vh2zkp6idzZr!#d&- zn@uTVdlhpGMYT)i4F}TUZjI6~0^c;94Wde-V|?~A=nrga-z&DSUI|(dNJo{KU56Hki1^|v2yJPPW7TI;*tg6%mVTflg`_<7mLlkR46sw3z%s!Jrf=Vp($}Zv%x#X4r2u4Bv5XmfkEXpSn z5v)mS4!aL4d?m?|(H<-hy)XROKNCXZuG{VL0Mpc^1#Jn94Ndsf*Wb&X%^t}LLaQZ& zB?aN`w&|@yM^;zAvCwmB_{DZoOjLE z7cv)Ze*L`AN;)4sus6APIgGw?OQ3?1j^`XL5Xt?`q~@){{4+Fm^B$*7$PW!Mdh6b3 zuRQf`i(4$Zp&T)Kv!qW$XNMmnO$p9j2uSK-5`s55iB@0x33drB`3a2X9qP{O^V~lu zYnbwCnr7CM=+Gt87rbH;vBHpCAQ|c3(#6g!7&CT%&rtu|dWq{GR^5G?EOhlV3XNY< zWbSTT3dxowBhQRZ+}Rk!Bjn%v3A!z#y^g2;9Q5>eg!O;yCw{bcRFhMpEW{8Ox@?y`lVq z{pG@-pF>o!OB|p@16q~{ew*83uO=;V*o=ORVvu81hYgRvvd~3`GFTI@p= zod(NM&ttXtMMdC?RLi@jGjLy6CYdUm9qVS&)aMT@(z8?y1;G@&UWaduhwThYx zJ0g!vJ}?q3hs55qTyFb?WDj$_%|_9+*}K4SQU6}%8X-J&s8|e*mvH8EC)~$qdI#T$ zd4`MK*?+pYTNd(ZTzrU~7anAJqBbVczos)N>mOj8d7BZ4G&nh&cU?VDbBq`JR& zt*S1D-P)=y#}3TvzHHOBfX=Gd?KDPG1Nvv2*uI0-2_<~d#%FO$AW}22JCOmwvz8EF z<}%+$J0{fv>yit)Fo!`Z#u}ltLd7+IUeh*zPU>ekG!hMR$S*55qqN3qsJCJF=-cFM zsJioID^EA{q}>PUFHY2st?Cdfh$gJTA*Q7}q+-0^Vr-Sv2XX5sYrXsTKoTP}Nj8{6 zl`gipvtv6b+LFOZDk|q7a}9Xtv7Fu0sP9MVE+Rna7^4N6OR~~MWm~j(&AXIO%>9Mq zI1VhPTElpu(ou)s!%S%jN){ocU~H`fZ`+6H#qZ>P=$Im_yRZ`$KwV=C`$ zIn?7~J&>=gh39p0@DHn!{a0> zG

%S*s>_8YK-=6_%RC(q9MK@yz9;Bp9OMU}!t$0GQ$k7BZ>>%+B7b_9w1?5y`RI zD9W@XbbV74{e?2)vYPGg5yDpg3|S;q?r>88x@6;~*swq9TXi5%Ws}vaW*XH)AD362 zy@oG(k;kfle?{=|*|2FxBuuiJ5F;FRTx_5Pf3)TXn7#n_Wh? zl60~>@Gi#emVoqgn6>G1X^&;Ff3(e#rCa)j?TgmT@vqh%l;?SG$1ZXgq9~5~gAbQ` zE~##ct&Pk9Eseqk!N@HH1&w5D&@I6{j6z(4{ho)*qt92sC@sSk5CUQ7Ylp^g_hkJE zwHH%3Ik!n)Em|VFX33#Qb3NGH=!Ma%AVRbDr&yxxp}A$<3`k=^`v>?80m0*0F!muj zs{yT{?q~vgu>=K=F_DJyhJE>90VUJy@}dt^b#Y7M;W4iq-o748VK>E8W8s{ij93*- zhVp7kWk}ygaZuCEsGpt3oSKKyAfH6jS_t|U-ozd#r5|dbfXiVYi^OhRvvuz&?~2f1 zNK1jzkJqs6akLS8AR5E19MyN|NG9(UYoL&S%_UYwK@sdBJJ6PbPVB(yaL!p%{T+U} z2#{QDS!zwts3$ylt;)nKfU(@>H@1zixK+yo*EgxxPYv8dA4FO0 zmq!xb$;gYCQBOuYTWat-sQ-SU*ygHn7Mk>3l-XawUSNtPyI3%rZJ+h<9OZ;aV2rG) z?;3QqJ;NW3Pmo>O7OF?zIBcnyB?nchI0?CrLZ~llj(i({8{nU%FtU_)FoeF-Xc=mb8N2eXDShI1(BVb`lHSA@JZ8B+- zYSe}@cYq9fw-;3aH~fNCxKvvyBf@tZK)tIao+=@)T4kQOILp3fYQS)yWY zs3@z~6KUct_S!>T@}7e&k*s4(0C+Os?liKpd^N-Zf^dH7k1=c_YW%b9c+bDJpLEa| z31iD{ATv}ej~s1n3m~VKx@rZ)6iX$cbDm+xMICkcU2`+2O#vk|aU}T0-;RnG`9A{w z-VSJFVSPG-fq;lde466@dpjU(>F8`BV)$dKkf?s|hCYY=hT@jljWfRK1z8LfJ60L4 zq^4B$vfnaU7$QYrOFs^}*UCq|v}aW>lk=eR=N3aFqN=F?A3xheJEGp3 zqIF&tYLK(ogWC-brsPoO^SJecEUQREnPQ9z|~5UblAU%_N;o`pE;6vWe=ndCp^eyHbb}FK2j4~x*6{CyYoiB8bt(B90|uejG29h4 zeEiXP1SZdNqvCOTdgrq$yn!Nf4M4=|y7X_}yz$lEgJU!|TQ)xV^9;1H)itD{1=(&j zq+h5Tx`%ikjBx;G^FoN-1a6D-_8Qso^_;H;f{yN3=M{s{YbWG%QiW(wKYE2?UAS>& z1>N3GpJ*C6b1^44%<#_e(ov@8_z2n+-itQIU%6dqVlTsgZ`iM#t73RV>z{>szQe%# zWhA_PMW4}!^~eJq(fU*qj=$=hblo*I-`10nanz4}53@$K*k(HC6{9l?8ySAGzsAQj z#b}yxcBxO&r$>#BG?Y9XRu+rW7~?7Y2ktK|^_I%MeBhZ}E?v1yGYinNj%Sr3V|EgK8967WU6z~&H&V+Ym(p(=KC}} zVs2nq12}@8$J_kDnGMG+MUL16(4|hIcQ&8?$)}fz5C#OYst>< z331dJX4Sx%5y=M)d^+`kA`fq934E-mk#^TsdNvt8!by1mnOG^Y$)sfOvH zUR8yKV)7R0@irX@ZpzbS zR0l&E;j{4t(y$FXY%a*;XJBQaOgBrwa)OgKO3q%Crv-2b6~ITM24PHf8N<`S@I?`x z%}&0vbyU*yO7d2k7SQrRQNy`ec?jL;(||2levi!78$Zd}_?+iGF~Q4*=X2P$NG{G{ zFoxpSi`d-32O7ola@|bU6iPaTWk|g7O(PL!(?qZo)fT9Gd=35QkylKEOeGEd#=Dl&(nAwzgW!j21;h8i+SM*dk5&KC$g^}TBA8dvEXl(-j;5X-D zRjHm(b&oxh%zpH3YAV|b*PU}BaW8be3IpylhD+T!*fV=;1~$NH@x|Q1Fh=-A#ANf# zz^H1?0oPqOAEg&>uS?Eb;U-XK5^V6*Toeu@r%;n^ho;Hsq1|ombPLSoNkAM?XiLbf z9cJ$!%~V)0*pew#h`*kg(16zCWe@k-hZ305<4ZIbb%l!4uTbD?-!U0gkVT|jp{b{T zlDTYT=Rj;6+u8HbnV^8I&10ohas+&#t)(r&WG{p~}Z@$5VIitcgVfCs2V`N_2hE z7J|8)q>0m;5Hoyq3U9KZ1Bj(*q5&ImBWo#qccU}Yjd~BLCWkCB0G++2LH~d&`EFM& zIVEHcsmiaqFt8;+xLXp0ZK%3Ax5FK6TAgM@%SWU`%%GF2*3d(<1pmR5wys3oLZiG& zyk1zizUOTz#(b&z0TEmA79S2p!ahqwaad6hq>2nkw7*RRF(_jB*#nZI%rgKwCwLg@b^|xQ3m>{!-Rl9c>3@>xrq>XzdijQS*s Date: Mon, 1 Jul 2019 16:45:31 +0800 Subject: [PATCH 04/11] Fixed the bug where abnormal transaction processing was not reported; --- source/base/src/main/resources/log4j2.xml | 62 ++++++++ source/ledger/ledger-core/pom.xml | 66 ++++---- .../blockchain/ledger/core/LedgerEditor.java | 18 ++- .../core/impl/LedgerRepositoryImpl.java | 14 +- .../core/impl/LedgerTransactionalEditor.java | 46 +++++- .../core/impl/TransactionBatchProcessor.java | 145 +++++++++++++++--- .../ledger/ContractInvokingTest.java | 2 +- .../blockchain/ledger/LedgerEditerTest.java | 18 ++- .../blockchain/ledger/LedgerManagerTest.java | 11 +- .../jd/blockchain/ledger/LedgerTestUtils.java | 63 ++++++-- .../ledger/TransactionBatchProcessorTest.java | 139 ++++++++++++++++- .../blockchain/ledger/TransactionSetTest.java | 3 +- .../blockchain/ledger/TransactionState.java | 15 +- .../jd/blockchain/transaction/TxBuilder.java | 14 +- .../transaction/TxRequestBuilder.java | 10 +- source/pom.xml | 47 +++--- .../jd/blockchain/utils/io/BytesUtils.java | 3 + 17 files changed, 550 insertions(+), 126 deletions(-) create mode 100644 source/base/src/main/resources/log4j2.xml diff --git a/source/base/src/main/resources/log4j2.xml b/source/base/src/main/resources/log4j2.xml new file mode 100644 index 00000000..c889aa69 --- /dev/null +++ b/source/base/src/main/resources/log4j2.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/ledger/ledger-core/pom.xml b/source/ledger/ledger-core/pom.xml index 34497874..f246b6d2 100644 --- a/source/ledger/ledger-core/pom.xml +++ b/source/ledger/ledger-core/pom.xml @@ -63,7 +63,7 @@ test - + @@ -78,42 +78,32 @@ - + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java index efa3e750..ced98b45 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java @@ -1,5 +1,6 @@ package com.jd.blockchain.ledger.core; +import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.LedgerTransaction; @@ -18,6 +19,20 @@ import com.jd.blockchain.ledger.TransactionRequest; */ public interface LedgerEditor { + /** + * 账本Hash; + * + * @return + */ + HashDigest getLedgerHash(); + + /** + * 新区块的高度; + * + * @return + */ + long getBlockHeight(); + /** * 开始新事务;
* @@ -32,7 +47,8 @@ public interface LedgerEditor { * 或者全部回滚(通过方法 {@link LedgerTransactionContext#rollback()}),以此实现原子性写入; *

* - * 每一次事务性的账本写入操作在提交后,都会记录该事务相关的系统全局快照,以交易对象 {@link LedgerTransaction} 进行保存;

+ * 每一次事务性的账本写入操作在提交后,都会记录该事务相关的系统全局快照,以交易对象 {@link LedgerTransaction} 进行保存; + *

* * 注:方法不解析、不执行交易中的操作; * diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java index 69e3223f..7b9b4a9a 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java @@ -401,7 +401,7 @@ public class LedgerRepositoryImpl implements LedgerRepository { "A new block is in process, cann't create another one until it finish by committing or canceling."); } LedgerBlock previousBlock = getLatestBlock(); - LedgerTransactionalEditor editor = LedgerTransactionalEditor.createEditor( + LedgerTransactionalEditor editor = LedgerTransactionalEditor.createEditor(ledgerHash, getAdminInfo().getMetadata().getSetting(), previousBlock, keyPrefix, exPolicyStorage, versioningStorage); NewBlockCommittingMonitor committingMonitor = new NewBlockCommittingMonitor(editor, this); @@ -479,7 +479,7 @@ public class LedgerRepositoryImpl implements LedgerRepository { } static TransactionSet newTransactionSet(LedgerSetting ledgerSetting, String keyPrefix, - ExPolicyKVStorage ledgerExStorage, VersioningKVStorage ledgerVerStorage) { + ExPolicyKVStorage ledgerExStorage, VersioningKVStorage ledgerVerStorage) { // TransactionSet transactionSet = new // TransactionSet(ledgerSetting.getCryptoSetting(), // PrefixAppender.prefix(TRANSACTION_SET_PREFIX, ledgerExStorage), @@ -576,6 +576,16 @@ public class LedgerRepositoryImpl implements LedgerRepository { this.ledgerRepo = ledgerRepo; } + @Override + public HashDigest getLedgerHash() { + return editor.getLedgerHash(); + } + + @Override + public long getBlockHeight() { + return editor.getBlockHeight(); + } + @Override public LedgerTransactionContext newTransaction(TransactionRequest txRequest) { return editor.newTransaction(txRequest); diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java index d939c865..a84d7692 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java @@ -26,6 +26,11 @@ public class LedgerTransactionalEditor implements LedgerEditor { System.out.println("------ [[ parallel-dbwrite=" + PARALLEL_DB_WRITE + " ]] ------"); } + /** + * 账本Hash,创世区块的编辑器则返回 null; + */ + private HashDigest ledgerHash; + private final String ledgerKeyPrefix; private CryptoSetting cryptoSetting; @@ -49,8 +54,9 @@ public class LedgerTransactionalEditor implements LedgerEditor { private LedgerDataContext newTxCtx; - private LedgerTransactionalEditor(CryptoSetting cryptoSetting, LedgerBlockData newlyBlock, + private LedgerTransactionalEditor(HashDigest ledgerHash, CryptoSetting cryptoSetting, LedgerBlockData newlyBlock, StagedSnapshot startingPoint, String ledgerKeyPrefix, BufferedKVStorage bufferedStorage) { + this.ledgerHash = ledgerHash; this.ledgerKeyPrefix = ledgerKeyPrefix; this.cryptoSetting = cryptoSetting; this.newlyBlock = newlyBlock; @@ -59,8 +65,9 @@ public class LedgerTransactionalEditor implements LedgerEditor { this.stagedSnapshots.push(startingPoint); } - public static LedgerTransactionalEditor createEditor(LedgerSetting ledgerSetting, LedgerBlock previousBlock, - String ledgerKeyPrefix, ExPolicyKVStorage ledgerExStorage, VersioningKVStorage ledgerVerStorage) { + public static LedgerTransactionalEditor createEditor(HashDigest ledgerHash, LedgerSetting ledgerSetting, + LedgerBlock previousBlock, String ledgerKeyPrefix, ExPolicyKVStorage ledgerExStorage, + VersioningKVStorage ledgerVerStorage) { // new block; LedgerBlockData currBlock = new LedgerBlockData(previousBlock.getHeight() + 1, previousBlock.getLedgerHash(), previousBlock.getHash()); @@ -71,7 +78,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { StagedSnapshot startingPoint = new TxSnapshot(previousBlock, previousBlock.getTransactionSetHash()); // instantiate editor; - return new LedgerTransactionalEditor(ledgerSetting.getCryptoSetting(), currBlock, startingPoint, + return new LedgerTransactionalEditor(ledgerHash, ledgerSetting.getCryptoSetting(), currBlock, startingPoint, ledgerKeyPrefix, txStagedStorage); } @@ -81,7 +88,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { StagedSnapshot startingPoint = new GenesisSnapshot(initSetting); // init storage; BufferedKVStorage txStagedStorage = new BufferedKVStorage(ledgerExStorage, ledgerVerStorage, false); - return new LedgerTransactionalEditor(initSetting.getCryptoSetting(), genesisBlock, startingPoint, + return new LedgerTransactionalEditor(null, initSetting.getCryptoSetting(), genesisBlock, startingPoint, ledgerKeyPrefix, txStagedStorage); } @@ -102,12 +109,39 @@ public class LedgerTransactionalEditor implements LedgerEditor { // return lastTxCtx.getDataSet(); // } - public LedgerBlock getNewlyBlock() { + LedgerBlock getNewlyBlock() { return newlyBlock; } + @Override + public long getBlockHeight() { + return newlyBlock.getHeight(); + } + + @Override + public HashDigest getLedgerHash() { + return ledgerHash; + } + + private boolean isRequestedLedger(TransactionRequest txRequest) { + HashDigest reqLedgerHash = txRequest.getTransactionContent().getLedgerHash(); + if (ledgerHash == reqLedgerHash) { + return true; + } + if (ledgerHash == null || reqLedgerHash == null) { + return false; + } + return ledgerHash.equals(reqLedgerHash); + } + @Override public LedgerTransactionContext newTransaction(TransactionRequest txRequest) { + // 验证账本是否; + if (!isRequestedLedger(txRequest)) { + throw new LedgerException("This ledger is not the target ledger of transaction request[" + + txRequest.getTransactionContent().getHash() + "]!"); + } + checkState(); // TODO:验证交易签名; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java index b4795c01..b14b3678 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java @@ -9,11 +9,13 @@ import org.slf4j.LoggerFactory; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.DigitalSignature; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.ledger.OperationResult; import com.jd.blockchain.ledger.OperationResultData; +import com.jd.blockchain.ledger.TransactionContent; import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionResponse; import com.jd.blockchain.ledger.TransactionState; @@ -26,6 +28,9 @@ import com.jd.blockchain.ledger.core.TransactionRequestContext; import com.jd.blockchain.service.TransactionBatchProcess; import com.jd.blockchain.service.TransactionBatchResult; import com.jd.blockchain.service.TransactionBatchResultHandle; +import com.jd.blockchain.transaction.TxBuilder; +import com.jd.blockchain.transaction.TxRequestBuilder; +import com.jd.blockchain.transaction.TxResponseMessage; import com.jd.blockchain.utils.Bytes; public class TransactionBatchProcessor implements TransactionBatchProcess { @@ -50,12 +55,9 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { private TransactionBatchResult batchResult; /** - * @param newBlockEditor - * 新区块的数据编辑器; - * @param previousBlockDataset - * 新区块的前一个区块的数据集;即未提交新区块之前的经过共识的账本最新数据集; - * @param opHandles - * 操作处理对象注册表; + * @param newBlockEditor 新区块的数据编辑器; + * @param previousBlockDataset 新区块的前一个区块的数据集;即未提交新区块之前的经过共识的账本最新数据集; + * @param opHandles 操作处理对象注册表; */ public TransactionBatchProcessor(LedgerEditor newBlockEditor, LedgerDataSet previousBlockDataset, OperationHandleRegisteration opHandles, LedgerService ledgerService) { @@ -65,6 +67,18 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { this.ledgerService = ledgerService; } + private boolean isRequestedLedger(TransactionRequest txRequest) { + HashDigest currLedgerHash = newBlockEditor.getLedgerHash(); + HashDigest reqLedgerHash = txRequest.getTransactionContent().getLedgerHash(); + if (currLedgerHash == reqLedgerHash) { + return true; + } + if (currLedgerHash == null || reqLedgerHash == null) { + return false; + } + return currLedgerHash.equals(reqLedgerHash); + } + /* * (non-Javadoc) * @@ -74,14 +88,61 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { */ @Override public TransactionResponse schedule(TransactionRequest request) { - // 此调用将会验证交易签名,验签失败将会抛出异常,同时,不记录签名错误的交易到链上; - LedgerTransactionContext txCtx = newBlockEditor.newTransaction(request); - TransactionState result; + TransactionResponse resp; + try { + if (!isRequestedLedger(request)) { + // 抛弃不属于当前账本的交易请求; + resp = discard(request, TransactionState.DISCARD_BY_WRONG_LEDGER); + responseList.add(resp); + return resp; + } + if (!verifyTxContent(request)) { + // 抛弃哈希和签名校验失败的交易请求; + resp = discard(request, TransactionState.DISCARD_BY_WRONG_CONTENT_SIGNATURE); + responseList.add(resp); + return resp; + } - List operationResults = new ArrayList<>(); + LOGGER.debug("Start handling transaction... --[BlockHeight=%s][RequestHash=%s][TxHash=%s]", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash()); + // 创建交易上下文; + // 此调用将会验证交易签名,验签失败将会抛出异常,同时,不记录签名错误的交易到链上; + LedgerTransactionContext txCtx = newBlockEditor.newTransaction(request); + + // 处理交易; + resp = handleTx(request, txCtx); + + LOGGER.debug("Complete handling transaction. --[BlockHeight=%s][RequestHash=%s][TxHash=%s]", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash()); + + responseList.add(resp); + return resp; + } catch (Exception e) { + // 抛弃发生处理异常的交易请求; + resp = discard(request, TransactionState.SYSTEM_ERROR); + LOGGER.error(String.format( + "Discard transaction rollback caused by the system exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), + e.getMessage()), e); + + responseList.add(resp); + return resp; + } + } + /** + * 处理交易;
+ * + * 此方法会处理所有的异常,以不同结果的 {@link TransactionResponse} 返回; + * + * @param request + * @param txCtx + * @return + */ + private TransactionResponse handleTx(TransactionRequest request, LedgerTransactionContext txCtx) { + TransactionState result; + List operationResults = new ArrayList<>(); try { - LedgerDataSet dataset = txCtx.getDataSet(); TransactionRequestContext reqCtx = new TransactionRequestContextImpl(request); // TODO: 验证签名者的有效性; @@ -101,7 +162,8 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { OperationHandleContext handleContext = new OperationHandleContext() { @Override public void handle(Operation operation) { - //assert; Instance of operation are one of User related operations or DataAccount related operations; + // assert; Instance of operation are one of User related operations or + // DataAccount related operations; OperationHandle hdl = opHandles.getHandle(operation.getClass()); hdl.process(operation, dataset, reqCtx, previousBlockDataset, this, ledgerService); } @@ -110,7 +172,8 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { int opIndex = 0; for (Operation op : ops) { opHandle = opHandles.getHandle(op.getClass()); - BytesValue opResult = opHandle.process(op, dataset, reqCtx, previousBlockDataset, handleContext, ledgerService); + BytesValue opResult = opHandle.process(op, dataset, reqCtx, previousBlockDataset, handleContext, + ledgerService); if (opResult != null) { operationResults.add(new OperationResultData(opIndex, opResult)); } @@ -119,19 +182,22 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { // 提交交易(事务); result = TransactionState.SUCCESS; - txCtx.commit(result, operationResults); } catch (LedgerException e) { // TODO: 识别更详细的异常类型以及执行对应的处理; result = TransactionState.LEDGER_ERROR; txCtx.discardAndCommit(TransactionState.LEDGER_ERROR, operationResults); - LOGGER.warn(String.format("Transaction rollback caused by the ledger exception! --[TxHash=%s] --%s", - request.getHash().toBase58(), e.getMessage()), e); + LOGGER.error(String.format( + "Transaction rollback caused by the ledger exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), + e.getMessage()), e); } catch (Exception e) { result = TransactionState.SYSTEM_ERROR; txCtx.discardAndCommit(TransactionState.SYSTEM_ERROR, operationResults); - LOGGER.warn(String.format("Transaction rollback caused by the system exception! --[TxHash=%s] --%s", - request.getHash().toBase58(), e.getMessage()), e); + LOGGER.error(String.format( + "Transaction rollback caused by the system exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), + e.getMessage()), e); } TxResponseHandle resp = new TxResponseHandle(request, result); @@ -139,9 +205,50 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { OperationResult[] operationResultArray = new OperationResult[operationResults.size()]; resp.setOperationResults(operationResults.toArray(operationResultArray)); } + return resp; + } - responseList.add(resp); + private boolean verifyTxContent(TransactionRequest request) { + TransactionContent txContent = request.getTransactionContent(); + if (!TxBuilder.verifyTxContentHash(txContent, txContent.getHash())) { + return false; + } + DigitalSignature[] endpointSignatures = request.getEndpointSignatures(); + if (endpointSignatures != null) { + for (DigitalSignature signature : endpointSignatures) { + if (!TxRequestBuilder.verifyHashSignature(txContent.getHash(), signature.getDigest(), + signature.getPubKey())) { + return false; + } + } + } + DigitalSignature[] nodeSignatures = request.getNodeSignatures(); + if (nodeSignatures != null) { + for (DigitalSignature signature : nodeSignatures) { + if (!TxRequestBuilder.verifyHashSignature(txContent.getHash(), signature.getDigest(), + signature.getPubKey())) { + return false; + } + } + } + return true; + } + /** + * 直接丢弃交易; + * + * @param request + * @param txState + * @return 丢弃交易的回复;只包含原始请求中的交易内容哈希和交易被丢弃的原因,而不包含区块信息; + */ + private TransactionResponse discard(TransactionRequest request, TransactionState txState) { + // 丢弃交易的回复;只返回请求的交易内容哈希和交易被丢弃的原因, + TxResponseMessage resp = new TxResponseMessage(request.getTransactionContent().getHash()); + resp.setExecutionState(txState); + + LOGGER.error("Discard transaction request! --[BlockHeight=%s][RequestHash=%s][TxHash=%s][ResponseState=%s]", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), + resp.getExecutionState()); return resp; } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java index eab81350..daffa40b 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java @@ -184,7 +184,7 @@ public class ContractInvokingTest { // 创建账本; LedgerEditor ldgEdt = LedgerTransactionalEditor.createEditor(initSetting, LEDGER_KEY_PREFIX, storage, storage); - TransactionRequest genesisTxReq = LedgerTestUtils.createTxRequest_UserReg(null); + TransactionRequest genesisTxReq = LedgerTestUtils.createLedgerInitTxRequest(partiKeys); LedgerTransactionContext genisisTxCtx = ldgEdt.newTransaction(genesisTxReq); LedgerDataSet ldgDS = genisisTxCtx.getDataSet(); 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 c7f3d6e6..dfab92c9 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 @@ -16,6 +16,7 @@ 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.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; @@ -52,6 +53,13 @@ public class LedgerEditerTest { private static final String LEDGER_KEY_PREFIX = "LDG://"; private SignatureFunction signatureFunction; + private BlockchainKeypair parti0 = BlockchainKeyGenerator.getInstance().generate(); + private BlockchainKeypair parti1 = BlockchainKeyGenerator.getInstance().generate(); + private BlockchainKeypair parti2 = BlockchainKeyGenerator.getInstance().generate(); + private BlockchainKeypair parti3 = BlockchainKeyGenerator.getInstance().generate(); + + private BlockchainKeypair[] participants = { parti0, parti1, parti2, parti3 }; + /** * 初始化一个; */ @@ -74,8 +82,8 @@ public class LedgerEditerTest { return LedgerTransactionalEditor.createEditor(initSetting, LEDGER_KEY_PREFIX, storage, storage); } - private LedgerTransactionContext createGenisisTx(LedgerEditor ldgEdt) { - TransactionRequest genesisTxReq = LedgerTestUtils.createTxRequest_UserReg(null); + private LedgerTransactionContext createGenisisTx(LedgerEditor ldgEdt, BlockchainKeypair[] partis) { + TransactionRequest genesisTxReq = LedgerTestUtils.createLedgerInitTxRequest(partis); LedgerTransactionContext txCtx = ldgEdt.newTransaction(genesisTxReq); @@ -86,7 +94,7 @@ public class LedgerEditerTest { @Test public void testWriteDataAccoutKvOp() { LedgerEditor ldgEdt = createLedgerInitEditor(); - LedgerTransactionContext genisisTxCtx = createGenisisTx(ldgEdt); + LedgerTransactionContext genisisTxCtx = createGenisisTx(ldgEdt, participants); LedgerDataSet ldgDS = genisisTxCtx.getDataSet(); AsymmetricKeypair cryptoKeyPair = signatureFunction.generateKeypair(); @@ -119,7 +127,7 @@ public class LedgerEditerTest { @Test public void testGennesisBlockCreation() { LedgerEditor ldgEdt = createLedgerInitEditor(); - LedgerTransactionContext genisisTxCtx = createGenisisTx(ldgEdt); + LedgerTransactionContext genisisTxCtx = createGenisisTx(ldgEdt, participants); LedgerDataSet ldgDS = genisisTxCtx.getDataSet(); AsymmetricKeypair cryptoKeyPair = signatureFunction.generateKeypair(); @@ -146,5 +154,5 @@ public class LedgerEditerTest { ldgEdt.commit(); } - + } 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 9639602c..73e4a8c1 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 @@ -63,6 +63,13 @@ public class LedgerManagerTest { public static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), SMCryptoService.class.getName() }; + private BlockchainKeypair parti0 = BlockchainKeyGenerator.getInstance().generate(); + private BlockchainKeypair parti1 = BlockchainKeyGenerator.getInstance().generate(); + private BlockchainKeypair parti2 = BlockchainKeyGenerator.getInstance().generate(); + private BlockchainKeypair parti3 = BlockchainKeyGenerator.getInstance().generate(); + + private BlockchainKeypair[] participants = { parti0, parti1, parti2, parti3 }; + private SignatureFunction signatureFunction; @Before @@ -83,13 +90,13 @@ public class LedgerManagerTest { LedgerEditor ldgEdt = ledgerManager.newLedger(initSetting, storage); // 创建一个模拟的创世交易; - TransactionRequest genesisTxReq = LedgerTestUtils.createTxRequest_UserReg(null); + TransactionRequest genesisTxReq = LedgerTestUtils.createLedgerInitTxRequest(participants); // 记录交易,注册用户; LedgerTransactionContext txCtx = ldgEdt.newTransaction(genesisTxReq); LedgerDataSet ldgDS = txCtx.getDataSet(); BlockchainKeypair userKP = BlockchainKeyGenerator.getInstance().generate(); - + UserAccount userAccount = ldgDS.getUserAccountSet().register(userKP.getAddress(), userKP.getPubKey()); userAccount.setProperty("Name", "孙悟空", -1); userAccount.setProperty("Age", "10000", -1); 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 3a631ad3..ca405b35 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 @@ -38,10 +38,10 @@ public class LedgerTestUtils { private static Random rand = new Random(); - public static TransactionRequest createTxRequest_UserReg(HashDigest ledgerHash) { - BlockchainKeypair key = BlockchainKeyGenerator.getInstance().generate(ED25519); - return createTxRequest_UserReg(ledgerHash, key); - } +// public static TransactionRequest createTxRequest_UserReg(HashDigest ledgerHash) { +// BlockchainKeypair key = BlockchainKeyGenerator.getInstance().generate(ED25519); +// return createTxRequest_UserReg(ledgerHash, key); +// } public static LedgerInitSetting createLedgerInitSetting() { BlockchainKeypair[] partiKeys = new BlockchainKeypair[2]; @@ -81,22 +81,61 @@ public class LedgerTestUtils { return initSetting; } - public static TransactionRequest createTxRequest_UserReg(HashDigest ledgerHash, BlockchainKeypair userKeypair) { - return createTxRequest_UserReg(ledgerHash, userKeypair, null); +// public static TransactionRequest createTxRequest_UserReg(BlockchainKeypair userKeypair, HashDigest ledgerHash, BlockchainKeypair... partiKeys) { +// return createTxRequest_UserReg(userKeypair, ledgerHash, null, null); +// } + + public static TransactionRequest createLedgerInitTxRequest(BlockchainKeypair... participants) { + TxBuilder txBuilder = new TxBuilder(null); + + for (BlockchainKeypair parti : participants) { + txBuilder.users().register(parti.getIdentity()); + } + + TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); + for (BlockchainKeypair parti : participants) { + txReqBuilder.signAsNode(parti); + } + + return txReqBuilder.buildRequest(); + } + + public static TransactionRequest createTxRequest_UserReg(HashDigest ledgerHash, + BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { + return createTxRequest_UserReg(BlockchainKeyGenerator.getInstance().generate(), ledgerHash, nodeKeypair, + signers); } - public static TransactionRequest createTxRequest_UserReg(HashDigest ledgerHash, BlockchainKeypair userKeypair, - BlockchainKeypair gatewayKeypair) { + public static TransactionRequest createTxRequest_UserReg(BlockchainKeypair userKeypair, HashDigest ledgerHash, + BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { TxBuilder txBuilder = new TxBuilder(ledgerHash); txBuilder.users().register(userKeypair.getIdentity()); TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); - txReqBuilder.signAsEndpoint(userKeypair); - if (gatewayKeypair != null) { - txReqBuilder.signAsNode(gatewayKeypair); + txReqBuilder.signAsEndpoint(nodeKeypair); + if (nodeKeypair != null) { + txReqBuilder.signAsNode(nodeKeypair); } - + + return txReqBuilder.buildRequest(); + } + + public static TransactionRequest createTxRequest_MultiOPs_WithError(HashDigest ledgerHash, + BlockchainKeypair userKeypair, BlockchainKeypair nodeKeypair) { + TxBuilder txBuilder = new TxBuilder(ledgerHash); + + txBuilder.users().register(userKeypair.getIdentity()); + + BlockchainKeypair testKey = BlockchainKeyGenerator.getInstance().generate(); + txBuilder.dataAccount(testKey.getAddress()).setBytes("AA", "Value".getBytes(), 1); + + TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); + txReqBuilder.signAsEndpoint(nodeKeypair); + if (nodeKeypair != null) { + txReqBuilder.signAsNode(nodeKeypair); + } + return txReqBuilder.buildRequest(); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java index 72c8a848..1172b3c4 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java @@ -1,6 +1,7 @@ package test.com.jd.blockchain.ledger; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -54,19 +55,22 @@ public class TransactionBatchProcessorTest { private BlockchainKeypair parti2 = BlockchainKeyGenerator.getInstance().generate(); private BlockchainKeypair parti3 = BlockchainKeyGenerator.getInstance().generate(); + private BlockchainKeypair[] participants = { parti0, parti1, parti2, parti3 }; + private TransactionRequest transactionRequest; - // 采用基于内存的 Storage; - private MemoryKVStorage storage = new MemoryKVStorage(); + // TODO: 验证无效签名会被拒绝; @Test - public void testTxReqProcess() { + public void testSingleTxProcess() { + final MemoryKVStorage STORAGE = new MemoryKVStorage(); + // 初始化账本到指定的存储库; - ledgerHash = initLedger(storage, parti0, parti1, parti2, parti3); + ledgerHash = initLedger(STORAGE, parti0, parti1, parti2, parti3); // 加载账本; LedgerManager ledgerManager = new LedgerManager(); - LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, storage); + LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); // 验证参与方账户的存在; LedgerDataSet previousBlockDataset = ledgerRepo.getDataSet(ledgerRepo.getLatestBlock()); @@ -85,18 +89,137 @@ public class TransactionBatchProcessorTest { // 注册新用户; BlockchainKeypair userKeypair = BlockchainKeyGenerator.getInstance().generate(); transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair, parti0); - txbatchProcessor.schedule(transactionRequest); + TransactionResponse txResp = txbatchProcessor.schedule(transactionRequest); + + LedgerBlock newBlock = newBlockEditor.prepare(); + newBlockEditor.commit(); + + // 验证正确性; + ledgerManager = new LedgerManager(); + ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); + + LedgerBlock latestBlock = ledgerRepo.getLatestBlock(); + assertEquals(newBlock.getHash(), latestBlock.getHash()); + assertEquals(1, newBlock.getHeight()); + + assertEquals(TransactionState.SUCCESS, txResp.getExecutionState()); + } + + @Test + public void testMultiTxsProcess() { + final MemoryKVStorage STORAGE = new MemoryKVStorage(); + + // 初始化账本到指定的存储库; + ledgerHash = initLedger(STORAGE, parti0, parti1, parti2, parti3); + + // 加载账本; + LedgerManager ledgerManager = new LedgerManager(); + LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); + + // 验证参与方账户的存在; + LedgerDataSet previousBlockDataset = ledgerRepo.getDataSet(ledgerRepo.getLatestBlock()); + UserAccount user0 = previousBlockDataset.getUserAccountSet().getUser(parti0.getAddress()); + assertNotNull(user0); + boolean partiRegistered = previousBlockDataset.getUserAccountSet().contains(parti0.getAddress()); + assertTrue(partiRegistered); + + // 生成新区块; + LedgerEditor newBlockEditor = ledgerRepo.createNextBlock(); + + OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration(); + TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(newBlockEditor, previousBlockDataset, + opReg, ledgerManager); + + // 注册新用户; + BlockchainKeypair userKeypair1 = BlockchainKeyGenerator.getInstance().generate(); + transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair1, parti0); + TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest); + +// BlockchainKeypair userKeypair2 = BlockchainKeyGenerator.getInstance().generate(); +// transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair2, parti0); +// TransactionResponse txResp2 = txbatchProcessor.schedule(transactionRequest); + + LedgerBlock newBlock = newBlockEditor.prepare(); + newBlockEditor.commit(); + + assertEquals(TransactionState.SUCCESS, txResp1.getExecutionState()); +// assertEquals(TransactionState.SUCCESS, txResp2.getExecutionState()); + + // 验证正确性; + ledgerManager = new LedgerManager(); + ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); + + LedgerBlock latestBlock = ledgerRepo.getLatestBlock(); + assertEquals(newBlock.getHash(), latestBlock.getHash()); + assertEquals(1, newBlock.getHeight()); + + LedgerDataSet ledgerDS = ledgerRepo.getDataSet(latestBlock); + boolean existUser1 = ledgerDS.getUserAccountSet().contains(userKeypair1.getAddress()); +// boolean existUser2 = ledgerDS.getUserAccountSet().contains(userKeypair2.getAddress()); + assertTrue(existUser1); +// assertTrue(existUser2); + } + + @Test + public void testTxRollback() { + final MemoryKVStorage STORAGE = new MemoryKVStorage(); + + // 初始化账本到指定的存储库; + ledgerHash = initLedger(STORAGE, parti0, parti1, parti2, parti3); + + // 加载账本; + LedgerManager ledgerManager = new LedgerManager(); + LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); + + // 验证参与方账户的存在; + LedgerDataSet previousBlockDataset = ledgerRepo.getDataSet(ledgerRepo.getLatestBlock()); + UserAccount user0 = previousBlockDataset.getUserAccountSet().getUser(parti0.getAddress()); + assertNotNull(user0); + boolean partiRegistered = previousBlockDataset.getUserAccountSet().contains(parti0.getAddress()); + assertTrue(partiRegistered); + + // 生成新区块; + LedgerEditor newBlockEditor = ledgerRepo.createNextBlock(); + + OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration(); + TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(newBlockEditor, previousBlockDataset, + opReg, ledgerManager); + + // 注册新用户; + BlockchainKeypair userKeypair1 = BlockchainKeyGenerator.getInstance().generate(); + transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair1, parti0); + TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest); + + BlockchainKeypair userKeypair2 = BlockchainKeyGenerator.getInstance().generate(); + transactionRequest = LedgerTestUtils.createTxRequest_MultiOPs_WithError(ledgerHash, userKeypair2, parti0); + TransactionResponse txResp2 = txbatchProcessor.schedule(transactionRequest); + + BlockchainKeypair userKeypair3 = BlockchainKeyGenerator.getInstance().generate(); + transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair3, parti0); + TransactionResponse txResp3 = txbatchProcessor.schedule(transactionRequest); LedgerBlock newBlock = newBlockEditor.prepare(); newBlockEditor.commit(); + assertEquals(TransactionState.SUCCESS, txResp1.getExecutionState()); + assertEquals(TransactionState.LEDGER_ERROR, txResp2.getExecutionState()); + assertEquals(TransactionState.SUCCESS, txResp3.getExecutionState()); + // 验证正确性; ledgerManager = new LedgerManager(); - ledgerRepo = ledgerManager.register(ledgerHash, storage); + ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); LedgerBlock latestBlock = ledgerRepo.getLatestBlock(); assertEquals(newBlock.getHash(), latestBlock.getHash()); assertEquals(1, newBlock.getHeight()); + + LedgerDataSet ledgerDS = ledgerRepo.getDataSet(latestBlock); + boolean existUser1 = ledgerDS.getUserAccountSet().contains(userKeypair1.getAddress()); + boolean existUser2 = ledgerDS.getUserAccountSet().contains(userKeypair2.getAddress()); + boolean existUser3 = ledgerDS.getUserAccountSet().contains(userKeypair3.getAddress()); + assertTrue(existUser1); + assertFalse(existUser2); + assertTrue(existUser3); } private HashDigest initLedger(MemoryKVStorage storage, BlockchainKeypair... partiKeys) { @@ -106,7 +229,7 @@ public class TransactionBatchProcessorTest { // 创建账本; LedgerEditor ldgEdt = LedgerTransactionalEditor.createEditor(initSetting, LEDGER_KEY_PREFIX, storage, storage); - TransactionRequest genesisTxReq = LedgerTestUtils.createTxRequest_UserReg(null); + TransactionRequest genesisTxReq = LedgerTestUtils.createLedgerInitTxRequest(partiKeys); LedgerTransactionContext genisisTxCtx = ldgEdt.newTransaction(genesisTxReq); LedgerDataSet ldgDS = genisisTxCtx.getDataSet(); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java index a4b719a7..f023a987 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java @@ -102,8 +102,7 @@ public class TransactionSetTest { txSnapshot.setContractAccountSetHash(contractAccountSetHash); long blockHeight = 8922L; - LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txReq, TransactionState.SUCCESS, txSnapshot, - null); + LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txReq, TransactionState.SUCCESS, txSnapshot); txset.add(tx); assertTrue(txset.isUpdated()); 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 e89d41b6..9d9b1691 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 @@ -11,7 +11,7 @@ import com.jd.blockchain.consts.DataCodes; * @author huanghaiquan * */ -@EnumContract(code= DataCodes.ENUM_TYPE_TRANSACTION_STATE) +@EnumContract(code = DataCodes.ENUM_TYPE_TRANSACTION_STATE) public enum TransactionState { /** @@ -23,16 +23,21 @@ public enum TransactionState { * 共识错误; */ CONSENSUS_ERROR((byte) 1), - + /** * 账本错误; */ LEDGER_ERROR((byte) 2), /** - * 数据序列更新错误; + * 由于在错误的账本上执行交易而被丢弃; + */ + DISCARD_BY_WRONG_LEDGER((byte) 3), + + /** + * 由于交易内容的验签失败而丢弃; */ - DATA_SEQUENCE_UPDATE_ERROR((byte) 3), + DISCARD_BY_WRONG_CONTENT_SIGNATURE((byte) 4), /** * 系统错误; @@ -44,7 +49,7 @@ public enum TransactionState { */ TIMEOUT((byte) 0x81); - @EnumField(type= PrimitiveType.INT8) + @EnumField(type = PrimitiveType.INT8) public final byte CODE; private TransactionState(byte code) { 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 35e09d78..1ff23a2f 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 @@ -55,12 +55,22 @@ public class TxBuilder implements TransactionBuilder { txContent.addOperations(opFactory.getOperations()); txContent.setTime(time); - byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); - HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); + HashDigest contentHash = computeTxContentHash(txContent); txContent.setHash(contentHash); return txContent; } + + public static HashDigest computeTxContentHash(TransactionContent txContent) { + byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); + HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); + return contentHash; + } + + public static boolean verifyTxContentHash(TransactionContent txContent, HashDigest verifiedHash) { + HashDigest hash = computeTxContentHash(txContent); + return hash.equals(verifiedHash); + } public Collection getReturnValuehandlers() { return opFactory.getReturnValuetHandlers(); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java index 7d6701a5..87326bb1 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java @@ -75,8 +75,14 @@ public class TxRequestBuilder implements TransactionRequestBuilder { } public static boolean verifySignature(TransactionContent txContent, SignatureDigest signDigest, PubKey pubKey) { - return Crypto.getSignatureFunction(pubKey.getAlgorithm()).verify(signDigest, pubKey, - txContent.getHash().toBytes()); + if (!TxBuilder.verifyTxContentHash(txContent, txContent.getHash())) { + return false; + } + return verifyHashSignature(txContent.getHash(), signDigest, pubKey); + } + + public static boolean verifyHashSignature(HashDigest hash, SignatureDigest signDigest, PubKey pubKey) { + return Crypto.getSignatureFunction(pubKey.getAlgorithm()).verify(signDigest, pubKey, hash.toBytes()); } @Override diff --git a/source/pom.xml b/source/pom.xml index f2a8ac32..4dca787c 100644 --- a/source/pom.xml +++ b/source/pom.xml @@ -8,11 +8,11 @@ spring-boot-starter-parent 2.0.6.RELEASE - - - - - + + + + + com.jd.blockchain jdchain-root @@ -92,6 +92,11 @@ mockito-core test + + org.springframework.boot + spring-boot-starter-log4j2 + test + @@ -446,22 +451,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java index 93520e0e..3f0a7256 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java @@ -46,6 +46,9 @@ public class BytesUtils { if (bytes1 == bytes2) { return true; } + if (bytes1 == null || bytes2 == null) { + return false; + } if (bytes1.length != bytes2.length) { return false; } From 87ac6f8c9ce61f17353ce0580337c0cbd4e654bf Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Mon, 1 Jul 2019 17:59:33 +0800 Subject: [PATCH 05/11] Fixed error of testcase; --- .../core/impl/TransactionBatchProcessor.java | 6 ++--- .../jd/blockchain/ledger/LedgerTestUtils.java | 26 +++++++++++-------- .../ledger/TransactionBatchProcessorTest.java | 10 +++---- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java index b14b3678..4416c3c2 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java @@ -103,7 +103,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { return resp; } - LOGGER.debug("Start handling transaction... --[BlockHeight=%s][RequestHash=%s][TxHash=%s]", + LOGGER.debug("Start handling transaction... --[BlockHeight={}][RequestHash={}][TxHash={}]", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash()); // 创建交易上下文; // 此调用将会验证交易签名,验签失败将会抛出异常,同时,不记录签名错误的交易到链上; @@ -112,7 +112,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { // 处理交易; resp = handleTx(request, txCtx); - LOGGER.debug("Complete handling transaction. --[BlockHeight=%s][RequestHash=%s][TxHash=%s]", + LOGGER.debug("Complete handling transaction. --[BlockHeight={}][RequestHash={}][TxHash={}]", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash()); responseList.add(resp); @@ -246,7 +246,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { TxResponseMessage resp = new TxResponseMessage(request.getTransactionContent().getHash()); resp.setExecutionState(txState); - LOGGER.error("Discard transaction request! --[BlockHeight=%s][RequestHash=%s][TxHash=%s][ResponseState=%s]", + LOGGER.error("Discard transaction request! --[BlockHeight={}][RequestHash={}][TxHash={}][ResponseState={}]", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), resp.getExecutionState()); return resp; 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 ca405b35..16d8b525 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 @@ -84,14 +84,14 @@ public class LedgerTestUtils { // public static TransactionRequest createTxRequest_UserReg(BlockchainKeypair userKeypair, HashDigest ledgerHash, BlockchainKeypair... partiKeys) { // return createTxRequest_UserReg(userKeypair, ledgerHash, null, null); // } - + public static TransactionRequest createLedgerInitTxRequest(BlockchainKeypair... participants) { TxBuilder txBuilder = new TxBuilder(null); - + for (BlockchainKeypair parti : participants) { txBuilder.users().register(parti.getIdentity()); } - + TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); for (BlockchainKeypair parti : participants) { txReqBuilder.signAsNode(parti); @@ -100,11 +100,11 @@ public class LedgerTestUtils { return txReqBuilder.buildRequest(); } - public static TransactionRequest createTxRequest_UserReg(HashDigest ledgerHash, - BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { - return createTxRequest_UserReg(BlockchainKeyGenerator.getInstance().generate(), ledgerHash, nodeKeypair, - signers); - } +// public static TransactionRequest createTxRequest_UserReg(HashDigest ledgerHash, BlockchainKeypair nodeKeypair, +// BlockchainKeypair... signers) { +// return createTxRequest_UserReg(BlockchainKeyGenerator.getInstance().generate(), ledgerHash, nodeKeypair, +// signers); +// } public static TransactionRequest createTxRequest_UserReg(BlockchainKeypair userKeypair, HashDigest ledgerHash, BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { @@ -113,7 +113,11 @@ public class LedgerTestUtils { txBuilder.users().register(userKeypair.getIdentity()); TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); - txReqBuilder.signAsEndpoint(nodeKeypair); + if (signers != null) { + for (BlockchainKeypair signer : signers) { + txReqBuilder.signAsEndpoint(signer); + } + } if (nodeKeypair != null) { txReqBuilder.signAsNode(nodeKeypair); } @@ -121,8 +125,8 @@ public class LedgerTestUtils { return txReqBuilder.buildRequest(); } - public static TransactionRequest createTxRequest_MultiOPs_WithError(HashDigest ledgerHash, - BlockchainKeypair userKeypair, BlockchainKeypair nodeKeypair) { + public static TransactionRequest createTxRequest_MultiOPs_WithError(BlockchainKeypair userKeypair, HashDigest ledgerHash, + BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { TxBuilder txBuilder = new TxBuilder(ledgerHash); txBuilder.users().register(userKeypair.getIdentity()); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java index 1172b3c4..02cba7fc 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java @@ -88,7 +88,7 @@ public class TransactionBatchProcessorTest { // 注册新用户; BlockchainKeypair userKeypair = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair, parti0); + transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair, ledgerHash, parti0, parti0); TransactionResponse txResp = txbatchProcessor.schedule(transactionRequest); LedgerBlock newBlock = newBlockEditor.prepare(); @@ -132,7 +132,7 @@ public class TransactionBatchProcessorTest { // 注册新用户; BlockchainKeypair userKeypair1 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair1, parti0); + transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, parti0, parti0); TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest); // BlockchainKeypair userKeypair2 = BlockchainKeyGenerator.getInstance().generate(); @@ -187,15 +187,15 @@ public class TransactionBatchProcessorTest { // 注册新用户; BlockchainKeypair userKeypair1 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair1, parti0); + transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, parti0, parti0); TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest); BlockchainKeypair userKeypair2 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_MultiOPs_WithError(ledgerHash, userKeypair2, parti0); + transactionRequest = LedgerTestUtils.createTxRequest_MultiOPs_WithError(userKeypair2, ledgerHash, parti0, parti0); TransactionResponse txResp2 = txbatchProcessor.schedule(transactionRequest); BlockchainKeypair userKeypair3 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair3, parti0); + transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair3, ledgerHash, parti0, parti0); TransactionResponse txResp3 = txbatchProcessor.schedule(transactionRequest); LedgerBlock newBlock = newBlockEditor.prepare(); From 6f13f269174945c0d3100bb4f6accb3fcc3c3b4f Mon Sep 17 00:00:00 2001 From: shaozhuguang Date: Tue, 2 Jul 2019 14:01:13 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9BFTSMART=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E8=8A=82=E7=82=B9=E5=85=B3=E8=81=94=E7=BD=91=E5=8D=A1?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E5=BC=82=E5=B8=B8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bftsmart/service/BftsmartNodeServer.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java index 162ff130..7b7dcdf5 100644 --- a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java +++ b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java @@ -6,6 +6,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import bftsmart.tom.*; +import com.jd.blockchain.utils.serialize.binary.BinarySerializeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jd.blockchain.consensus.ConsensusManageService; @@ -49,12 +50,12 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer private BftsmartConsensusManageService manageService; - private volatile BftsmartTopology topology; private volatile BftsmartConsensusSettings setting; private TOMConfiguration tomConfig; + private TOMConfiguration outerTomConfig; private HostsConfig hostsConfig; private Properties systemConfig; @@ -123,14 +124,11 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer return; } - protected void initConfig(int id, String systemConfig, String hostsConfig) { - - this.tomConfig = new TOMConfiguration(id, systemConfig, hostsConfig); - - } - protected void initConfig(int id, Properties systemsConfig, HostsConfig hostConfig) { + byte[] serialHostConf = BinarySerializeUtils.serialize(hostConfig); + Properties sysConfClone = (Properties)systemsConfig.clone(); this.tomConfig = new TOMConfiguration(id, systemsConfig, hostConfig); + this.outerTomConfig = new TOMConfiguration(id, sysConfClone, BinarySerializeUtils.deserialize(serialHostConf)); } @Override @@ -149,7 +147,7 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer } public TOMConfiguration getTomConfig() { - return tomConfig; + return outerTomConfig; } public int getId() { @@ -161,7 +159,7 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer throw new IllegalArgumentException("ReplicaID is negative!"); } this.tomConfig.setProcessId(id); - + this.outerTomConfig.setProcessId(id); } public BftsmartConsensusSettings getConsensusSetting() { From c72b3397ad3faa3c0d91c404b794a65b7130b270 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Tue, 2 Jul 2019 23:40:15 +0800 Subject: [PATCH 07/11] Fixed the bug that did not correctly handle transaction state when the writing DataAccount did not exist; --- .../ledger/core/DataAccountSet.java | 16 +++- .../core/impl/LedgerTransactionalEditor.java | 8 +- .../core/impl/TransactionBatchProcessor.java | 18 +++- .../DataAccountKVSetOperationHandle.java | 5 +- .../jd/blockchain/ledger/LedgerTestUtils.java | 12 ++- .../ledger/TransactionBatchProcessorTest.java | 54 ++++++++---- .../ledger/ContractDoesNotExistException.java | 16 ++++ .../DataAccountDoesNotExistException.java | 16 ++++ .../jd/blockchain/ledger/LedgerException.java | 2 + .../blockchain/ledger/TransactionState.java | 17 +++- .../ledger/UserDoesNotExistException.java | 15 ++++ .../service/utils/BufferedKVStorageTest.java | 85 +------------------ 12 files changed, 151 insertions(+), 113 deletions(-) create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractDoesNotExistException.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountDoesNotExistException.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserDoesNotExistException.java diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java index 799a8570..d44e9dbf 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java @@ -14,9 +14,9 @@ public class DataAccountSet implements MerkleProvable, Transactional { private AccountSet accountSet; - public DataAccountSet(CryptoSetting cryptoSetting, String prefix,ExPolicyKVStorage exStorage, + public DataAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { - accountSet = new AccountSet(cryptoSetting,prefix, exStorage, verStorage, accessPolicy); + accountSet = new AccountSet(cryptoSetting, prefix, exStorage, verStorage, accessPolicy); } public DataAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix, @@ -26,7 +26,7 @@ public class DataAccountSet implements MerkleProvable, Transactional { } public AccountHeader[] getAccounts(int fromIndex, int count) { - return accountSet.getAccounts(fromIndex,count); + return accountSet.getAccounts(fromIndex, count); } public boolean isReadonly() { @@ -56,8 +56,18 @@ public class DataAccountSet implements MerkleProvable, Transactional { return new DataAccount(accBase); } + /** + * 返回数据账户;
+ * 如果不存在,则返回 null; + * + * @param address + * @return + */ public DataAccount getDataAccount(Bytes address) { BaseAccount accBase = accountSet.getAccount(address); + if (accBase == null) { + return null; + } return new DataAccount(accBase); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java index a84d7692..4330d8dc 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java @@ -123,6 +123,12 @@ public class LedgerTransactionalEditor implements LedgerEditor { return ledgerHash; } + /** + * 检查当前账本是否是指定交易请求的账本; + * + * @param txRequest + * @return + */ private boolean isRequestedLedger(TransactionRequest txRequest) { HashDigest reqLedgerHash = txRequest.getTransactionContent().getLedgerHash(); if (ledgerHash == reqLedgerHash) { @@ -142,8 +148,8 @@ public class LedgerTransactionalEditor implements LedgerEditor { + txRequest.getTransactionContent().getHash() + "]!"); } + // 检查状态是否允许创建新的交易请求;; checkState(); - // TODO:验证交易签名; BufferedKVStorage txBuffStorage = null; LedgerDataSetImpl txDataset = null; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java index 4416c3c2..78b099ae 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java @@ -9,6 +9,8 @@ import org.slf4j.LoggerFactory; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.ContractDoesNotExistException; +import com.jd.blockchain.ledger.DataAccountDoesNotExistException; import com.jd.blockchain.ledger.DigitalSignature; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerException; @@ -19,6 +21,7 @@ import com.jd.blockchain.ledger.TransactionContent; import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionResponse; import com.jd.blockchain.ledger.TransactionState; +import com.jd.blockchain.ledger.UserDoesNotExistException; import com.jd.blockchain.ledger.core.LedgerDataSet; import com.jd.blockchain.ledger.core.LedgerEditor; import com.jd.blockchain.ledger.core.LedgerService; @@ -111,10 +114,10 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { // 处理交易; resp = handleTx(request, txCtx); - + LOGGER.debug("Complete handling transaction. --[BlockHeight={}][RequestHash={}][TxHash={}]", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash()); - + responseList.add(resp); return resp; } catch (Exception e) { @@ -124,7 +127,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { "Discard transaction rollback caused by the system exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), e.getMessage()), e); - + responseList.add(resp); return resp; } @@ -186,7 +189,14 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { } catch (LedgerException e) { // TODO: 识别更详细的异常类型以及执行对应的处理; result = TransactionState.LEDGER_ERROR; - txCtx.discardAndCommit(TransactionState.LEDGER_ERROR, operationResults); + if (e instanceof DataAccountDoesNotExistException) { + result = TransactionState.DATA_ACCOUNT_DOES_NOT_EXIST; + } else if (e instanceof UserDoesNotExistException) { + result = TransactionState.USER_DOES_NOT_EXIST; + } else if (e instanceof ContractDoesNotExistException) { + result = TransactionState.CONTRACT_DOES_NOT_EXIST; + } + txCtx.discardAndCommit(result, operationResults); LOGGER.error(String.format( "Transaction rollback caused by the ledger exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/DataAccountKVSetOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/DataAccountKVSetOperationHandle.java index c07dd628..2745a377 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/DataAccountKVSetOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/DataAccountKVSetOperationHandle.java @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.DataAccountDoesNotExistException; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.ledger.DataAccountKVSetOperation.KVWriteEntry; import com.jd.blockchain.ledger.Operation; @@ -26,9 +27,11 @@ public class DataAccountKVSetOperationHandle implements OperationHandle { LedgerDataSet previousBlockDataset, OperationHandleContext handleContext, LedgerService ledgerService) { DataAccountKVSetOperation kvWriteOp = (DataAccountKVSetOperation) op; DataAccount account = dataset.getDataAccountSet().getDataAccount(kvWriteOp.getAccountAddress()); + if (account == null) { + throw new DataAccountDoesNotExistException("DataAccount doesn't exist!"); + } KVWriteEntry[] writeSet = kvWriteOp.getWriteSet(); for (KVWriteEntry kvw : writeSet) { -// byte[] value = BinaryProtocol.encode(kvw.getValue(), BytesValue.class); account.setBytes(Bytes.fromString(kvw.getKey()), kvw.getValue(), kvw.getExpectedVersion()); } return null; 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 16d8b525..9fae875a 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 @@ -125,12 +125,20 @@ public class LedgerTestUtils { return txReqBuilder.buildRequest(); } - public static TransactionRequest createTxRequest_MultiOPs_WithError(BlockchainKeypair userKeypair, HashDigest ledgerHash, - BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { + /** + * @param userKeypair 要注册的用户key; + * @param ledgerHash 账本哈希; + * @param nodeKeypair 节点key; + * @param signers 签名者列表; + * @return + */ + public static TransactionRequest createTxRequest_MultiOPs_WithNotExistedDataAccount(BlockchainKeypair userKeypair, + HashDigest ledgerHash, BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { TxBuilder txBuilder = new TxBuilder(ledgerHash); txBuilder.users().register(userKeypair.getIdentity()); + // 故意构建一个错误的 BlockchainKeypair testKey = BlockchainKeyGenerator.getInstance().generate(); txBuilder.dataAccount(testKey.getAddress()).setBytes("AA", "Value".getBytes(), 1); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java index 02cba7fc..ea20f8b1 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java @@ -57,8 +57,6 @@ public class TransactionBatchProcessorTest { private BlockchainKeypair[] participants = { parti0, parti1, parti2, parti3 }; - private TransactionRequest transactionRequest; - // TODO: 验证无效签名会被拒绝; @Test @@ -88,7 +86,8 @@ public class TransactionBatchProcessorTest { // 注册新用户; BlockchainKeypair userKeypair = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair, ledgerHash, parti0, parti0); + TransactionRequest transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair, ledgerHash, parti0, + parti0); TransactionResponse txResp = txbatchProcessor.schedule(transactionRequest); LedgerBlock newBlock = newBlockEditor.prepare(); @@ -132,18 +131,20 @@ public class TransactionBatchProcessorTest { // 注册新用户; BlockchainKeypair userKeypair1 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, parti0, parti0); - TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest); + TransactionRequest transactionRequest1 = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, + parti0, parti0); + TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest1); -// BlockchainKeypair userKeypair2 = BlockchainKeyGenerator.getInstance().generate(); -// transactionRequest = LedgerTestUtils.createTxRequest_UserReg(ledgerHash, userKeypair2, parti0); -// TransactionResponse txResp2 = txbatchProcessor.schedule(transactionRequest); + BlockchainKeypair userKeypair2 = BlockchainKeyGenerator.getInstance().generate(); + TransactionRequest transactionRequest2 = LedgerTestUtils.createTxRequest_UserReg(userKeypair2, ledgerHash, + parti0, parti0); + TransactionResponse txResp2 = txbatchProcessor.schedule(transactionRequest2); LedgerBlock newBlock = newBlockEditor.prepare(); newBlockEditor.commit(); assertEquals(TransactionState.SUCCESS, txResp1.getExecutionState()); -// assertEquals(TransactionState.SUCCESS, txResp2.getExecutionState()); + assertEquals(TransactionState.SUCCESS, txResp2.getExecutionState()); // 验证正确性; ledgerManager = new LedgerManager(); @@ -155,9 +156,9 @@ public class TransactionBatchProcessorTest { LedgerDataSet ledgerDS = ledgerRepo.getDataSet(latestBlock); boolean existUser1 = ledgerDS.getUserAccountSet().contains(userKeypair1.getAddress()); -// boolean existUser2 = ledgerDS.getUserAccountSet().contains(userKeypair2.getAddress()); + boolean existUser2 = ledgerDS.getUserAccountSet().contains(userKeypair2.getAddress()); assertTrue(existUser1); -// assertTrue(existUser2); + assertTrue(existUser2); } @Test @@ -187,22 +188,25 @@ public class TransactionBatchProcessorTest { // 注册新用户; BlockchainKeypair userKeypair1 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, parti0, parti0); - TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest); + TransactionRequest transactionRequest1 = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, + parti0, parti0); + TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest1); BlockchainKeypair userKeypair2 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_MultiOPs_WithError(userKeypair2, ledgerHash, parti0, parti0); - TransactionResponse txResp2 = txbatchProcessor.schedule(transactionRequest); + TransactionRequest transactionRequest2 = LedgerTestUtils + .createTxRequest_MultiOPs_WithNotExistedDataAccount(userKeypair2, ledgerHash, parti0, parti0); + TransactionResponse txResp2 = txbatchProcessor.schedule(transactionRequest2); BlockchainKeypair userKeypair3 = BlockchainKeyGenerator.getInstance().generate(); - transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair3, ledgerHash, parti0, parti0); - TransactionResponse txResp3 = txbatchProcessor.schedule(transactionRequest); + TransactionRequest transactionRequest3 = LedgerTestUtils.createTxRequest_UserReg(userKeypair3, ledgerHash, + parti0, parti0); + TransactionResponse txResp3 = txbatchProcessor.schedule(transactionRequest3); LedgerBlock newBlock = newBlockEditor.prepare(); newBlockEditor.commit(); assertEquals(TransactionState.SUCCESS, txResp1.getExecutionState()); - assertEquals(TransactionState.LEDGER_ERROR, txResp2.getExecutionState()); + assertEquals(TransactionState.DATA_ACCOUNT_DOES_NOT_EXIST, txResp2.getExecutionState()); assertEquals(TransactionState.SUCCESS, txResp3.getExecutionState()); // 验证正确性; @@ -213,6 +217,20 @@ public class TransactionBatchProcessorTest { assertEquals(newBlock.getHash(), latestBlock.getHash()); assertEquals(1, newBlock.getHeight()); + LedgerTransaction tx1 = ledgerRepo.getTransactionSet() + .get(transactionRequest1.getTransactionContent().getHash()); + LedgerTransaction tx2 = ledgerRepo.getTransactionSet() + .get(transactionRequest2.getTransactionContent().getHash()); + LedgerTransaction tx3 = ledgerRepo.getTransactionSet() + .get(transactionRequest3.getTransactionContent().getHash()); + + assertNotNull(tx1); + assertEquals(TransactionState.SUCCESS, tx1.getExecutionState()); + assertNotNull(tx2); + assertEquals(TransactionState.DATA_ACCOUNT_DOES_NOT_EXIST, tx2.getExecutionState()); + assertNotNull(tx3); + assertEquals(TransactionState.SUCCESS, tx3.getExecutionState()); + LedgerDataSet ledgerDS = ledgerRepo.getDataSet(latestBlock); boolean existUser1 = ledgerDS.getUserAccountSet().contains(userKeypair1.getAddress()); boolean existUser2 = ledgerDS.getUserAccountSet().contains(userKeypair2.getAddress()); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractDoesNotExistException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractDoesNotExistException.java new file mode 100644 index 00000000..687ef762 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractDoesNotExistException.java @@ -0,0 +1,16 @@ +package com.jd.blockchain.ledger; + +public class ContractDoesNotExistException extends LedgerException { + + + private static final long serialVersionUID = 8685914012112243771L; + + public ContractDoesNotExistException(String message) { + super(message); + } + + public ContractDoesNotExistException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountDoesNotExistException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountDoesNotExistException.java new file mode 100644 index 00000000..428efffc --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountDoesNotExistException.java @@ -0,0 +1,16 @@ +package com.jd.blockchain.ledger; + +public class DataAccountDoesNotExistException extends LedgerException { + + + private static final long serialVersionUID = -1889587937401974215L; + + public DataAccountDoesNotExistException(String message) { + super(message); + } + + public DataAccountDoesNotExistException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerException.java index 9d0dd838..d0edef01 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerException.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerException.java @@ -3,6 +3,8 @@ package com.jd.blockchain.ledger; public class LedgerException extends RuntimeException { private static final long serialVersionUID = -4090881296855827888L; + + public LedgerException(String message) { super(message); 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 9d9b1691..8483f84d 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 @@ -33,12 +33,27 @@ public enum TransactionState { * 由于在错误的账本上执行交易而被丢弃; */ DISCARD_BY_WRONG_LEDGER((byte) 3), - + /** * 由于交易内容的验签失败而丢弃; */ DISCARD_BY_WRONG_CONTENT_SIGNATURE((byte) 4), + /** + * 数据账户不存在; + */ + DATA_ACCOUNT_DOES_NOT_EXIST((byte) 5), + + /** + * 用户不存在; + */ + USER_DOES_NOT_EXIST((byte) 6), + + /** + * 合约不存在; + */ + CONTRACT_DOES_NOT_EXIST((byte) 6), + /** * 系统错误; */ diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserDoesNotExistException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserDoesNotExistException.java new file mode 100644 index 00000000..1775405f --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserDoesNotExistException.java @@ -0,0 +1,15 @@ +package com.jd.blockchain.ledger; + +public class UserDoesNotExistException extends LedgerException { + + private static final long serialVersionUID = 397450363050148898L; + + public UserDoesNotExistException(String message) { + super(message); + } + + public UserDoesNotExistException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/storage/storage-service/src/test/java/test/com/jd/blockchain/storage/service/utils/BufferedKVStorageTest.java b/source/storage/storage-service/src/test/java/test/com/jd/blockchain/storage/service/utils/BufferedKVStorageTest.java index b14ad85a..4999256c 100644 --- a/source/storage/storage-service/src/test/java/test/com/jd/blockchain/storage/service/utils/BufferedKVStorageTest.java +++ b/source/storage/storage-service/src/test/java/test/com/jd/blockchain/storage/service/utils/BufferedKVStorageTest.java @@ -1,9 +1,9 @@ package test.com.jd.blockchain.storage.service.utils; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -15,14 +15,11 @@ import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.mockito.verification.VerificationMode; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.storage.service.utils.BufferedKVStorage; -import com.jd.blockchain.storage.service.utils.ExistancePolicyKVStorageMap; -import com.jd.blockchain.storage.service.utils.VersioningKVStorageMap; import com.jd.blockchain.utils.Bytes; public class BufferedKVStorageTest { @@ -77,82 +74,4 @@ public class BufferedKVStorageTest { verify(exStorage, times(1)).set(eq(Bytes.fromString("C")), any(), eq(ExPolicy.NOT_EXISTING)); verify(exStorage, times(1)).set(eq(Bytes.fromString("D")), any(), eq(ExPolicy.NOT_EXISTING)); } - - // 改变了存储结构,此测试用例不再适合; - // @Test - // public void testDataSet() { - // - // ExistancePolicyKVStorageMap memoryExStorage = new - // ExistancePolicyKVStorageMap(); - // - // VersioningKVStorageMap memoryVerStorage = new VersioningKVStorageMap(); - // - // long v = memoryVerStorage.set("A", "A1".getBytes(), -1); - // assertEquals(0, v); - // v = memoryVerStorage.set("A", "A2".getBytes(), 0); - // assertEquals(1, v); - // v = memoryVerStorage.set("A", "A3".getBytes(), 1); - // assertEquals(2, v); - // v = memoryVerStorage.set("B", "B1".getBytes(), -1); - // assertEquals(0, v); - // - // BufferedKVStorage bufferedStorage = new BufferedKVStorage(memoryExStorage, - // memoryVerStorage, false); - // - // // test versioning get; - // byte[] value = bufferedStorage.get("A", 0); - // assertEquals("A1", new String(value)); - // - // value = bufferedStorage.get("A", -1); - // assertEquals("A3", new String(value)); - // - // value = bufferedStorage.get("A", 2); - // assertEquals("A3", new String(value)); - // - // value = bufferedStorage.get("B", 0); - // assertEquals("B1", new String(value)); - // - // - // // test versioning buffered set; - // v = bufferedStorage.set("C", "C1".getBytes(), -1); - // assertEquals(v, 0); - // - // v = bufferedStorage.set("C", "C2".getBytes(), 0); - // assertEquals(v, 1); - // - // v = bufferedStorage.set("D", "D1".getBytes(), -1); - // assertEquals(v, 0); - // - // v = bufferedStorage.set("E", "E1".getBytes(), 0); - // assertEquals(v, -1); - // - // - // value = bufferedStorage.get("C", 0); - // assertEquals("C1", new String(value)); - // value = bufferedStorage.get("C", 1); - // assertEquals("C2", new String(value)); - // value = bufferedStorage.get("D", 0); - // assertEquals("D1", new String(value)); - // value = bufferedStorage.get("E", 0); - // assertNull(value); - // - // value = memoryVerStorage.get("C", 0); - // assertNull(value); - // value = memoryVerStorage.get("D", 0); - // assertNull(value); - // value = memoryVerStorage.get("E", 0); - // assertNull(value); - // - // bufferedStorage.flush(); - // - // value = memoryVerStorage.get("C", 0); - // assertEquals("C1", new String(value)); - // value = memoryVerStorage.get("C", 1); - // assertEquals("C2", new String(value)); - // value = memoryVerStorage.get("D", 0); - // assertEquals("D1", new String(value)); - // value = memoryVerStorage.get("E", 0); - // assertNull(value); - // } - } From 436022dda6390dc430e3e8b8a64420710cad87f8 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Wed, 3 Jul 2019 00:32:33 +0800 Subject: [PATCH 08/11] Set the default log level of console to error; --- source/base/src/main/resources/log4j2.xml | 128 ++++++++++-------- source/gateway/src/main/resources/log4j2.xml | 2 +- .../core/impl/LedgerTransactionalEditor.java | 21 +++ ...rEditerTest.java => LedgerEditorTest.java} | 2 +- source/peer/src/main/resources/log4j2.xml | 2 +- .../storage/service/ExPolicyKVStorage.java | 31 ----- .../storage/service/VersioningKVStorage.java | 59 -------- 7 files changed, 94 insertions(+), 151 deletions(-) rename source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/{LedgerEditerTest.java => LedgerEditorTest.java} (99%) diff --git a/source/base/src/main/resources/log4j2.xml b/source/base/src/main/resources/log4j2.xml index c889aa69..26f090d7 100644 --- a/source/base/src/main/resources/log4j2.xml +++ b/source/base/src/main/resources/log4j2.xml @@ -1,62 +1,74 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/gateway/src/main/resources/log4j2.xml b/source/gateway/src/main/resources/log4j2.xml index 3fe4b122..d81fe1dc 100644 --- a/source/gateway/src/main/resources/log4j2.xml +++ b/source/gateway/src/main/resources/log4j2.xml @@ -8,7 +8,7 @@ - + diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java index 4330d8dc..5113dde4 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java @@ -45,6 +45,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { private boolean committed = false; +// private BufferedKVStorage baseStorage; private BufferedKVStorage bufferedStorage; /** @@ -65,6 +66,17 @@ public class LedgerTransactionalEditor implements LedgerEditor { this.stagedSnapshots.push(startingPoint); } + /** + * 创建账本新区块的编辑器; + * + * @param ledgerHash + * @param ledgerSetting + * @param previousBlock + * @param ledgerKeyPrefix + * @param ledgerExStorage + * @param ledgerVerStorage + * @return + */ public static LedgerTransactionalEditor createEditor(HashDigest ledgerHash, LedgerSetting ledgerSetting, LedgerBlock previousBlock, String ledgerKeyPrefix, ExPolicyKVStorage ledgerExStorage, VersioningKVStorage ledgerVerStorage) { @@ -82,6 +94,15 @@ public class LedgerTransactionalEditor implements LedgerEditor { ledgerKeyPrefix, txStagedStorage); } + /** + * 创建创世区块的编辑器; + * + * @param initSetting + * @param ledgerKeyPrefix + * @param ledgerExStorage + * @param ledgerVerStorage + * @return + */ public static LedgerTransactionalEditor createEditor(LedgerInitSetting initSetting, String ledgerKeyPrefix, ExPolicyKVStorage ledgerExStorage, VersioningKVStorage ledgerVerStorage) { LedgerBlockData genesisBlock = new LedgerBlockData(0, null, null); 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/LedgerEditorTest.java similarity index 99% rename from source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java rename to source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java index dfab92c9..7ce6908b 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/LedgerEditorTest.java @@ -39,7 +39,7 @@ import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.io.BytesUtils; import com.jd.blockchain.utils.net.NetworkAddress; -public class LedgerEditerTest { +public class LedgerEditorTest { private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), SMCryptoService.class.getName() }; diff --git a/source/peer/src/main/resources/log4j2.xml b/source/peer/src/main/resources/log4j2.xml index c889aa69..b3630520 100644 --- a/source/peer/src/main/resources/log4j2.xml +++ b/source/peer/src/main/resources/log4j2.xml @@ -8,7 +8,7 @@ - + diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/ExPolicyKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/ExPolicyKVStorage.java index 469ea308..ac8f3af8 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/ExPolicyKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/ExPolicyKVStorage.java @@ -10,37 +10,6 @@ import com.jd.blockchain.utils.Bytes; */ public interface ExPolicyKVStorage extends BatchStorageService{ -// /** -// * 返回“键”对应的“值”;
-// * 如果“键”不存在,则返回 null; -// * -// * @param key -// * @return -// */ -// byte[] get(String key); -// -// /** -// * 如果满足指定的存在性策略,则创建/更新指定的“键-值”; -// * -// * @param key -// * 键; -// * @param value -// * 值; -// * @param ex -// * 如果指定 {@link ExPolicy#EXISTING} ,则只有键存在时才更新;
-// * 如果指定 {@link ExPolicy#NOT_EXISTING} ,则只有键不存在时才更新/创建; -// * @return 如果符合存在性策略,并执行了创建/更新操作,则返回 true,否则返回 false; -// */ -// boolean set(String key, byte[] value, ExPolicy ex); -// -// /** -// * 指定的 key 是否存在; -// * -// * @param key -// * @return -// */ -// boolean exist(String key); - /** * 返回“键”对应的“值”;
* 如果“键”不存在,则返回 null; diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java index e6a00854..f9d859ff 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java @@ -19,65 +19,6 @@ import com.jd.blockchain.utils.Bytes; */ public interface VersioningKVStorage extends BatchStorageService { -// /** -// * Return the latest version entry associated the specified key; -// * -// * If the key doesn't exist, then return -1; -// * -// * @param key -// * @return -// */ -// long getVersion(String key); -// -// /** -// * Return the specified verson's entry;
-// * -// * It will return the latest one if the version is -1;
-// * -// * It will return null if the key or version not exist. -// * -// * @param key -// * @param version -// * @return -// */ -// VersioningKVEntry getEntry(String key, long version); -// -// /** -// * Return the specified verson's value;
-// * -// * If the specified version of key doesn't exist, then return null;
-// * -// * If the version is specified to -1, then return the latest version's -// * value;
-// * -// * @param key -// * @param version -// * @return -// */ -// byte[] get(String key, long version); -// -// /** -// * Update the value of the key;
-// * -// * If key exist, and the specified version equals to latest , then the value is -// * updated and version is increased by 1;
-// * If key not exist, and the specified version is -1, then the value will be -// * created and initialized it's version by 0;
-// * -// * @param key -// * the key; -// * @param value -// * the new value to update if expected version match the actual -// * version; -// * @param version -// * the latest version expected; -// * @return The latest version entry after setting.
-// * If the version checking fail, or concurrent confliction occur, then -// * return -1 as indication.
-// */ -// long set(String key, byte[] value, long version); -// - /** * Return the latest version entry associated the specified key; * From c727a3562660a6ac3524488acefa2831ebdd3134 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Fri, 5 Jul 2019 12:17:33 +0800 Subject: [PATCH 09/11] =?UTF-8?q?Implemented=20transaction=20rollback=20me?= =?UTF-8?q?chanism=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bftsmart/service/BftsmartNodeServer.java | 1 + .../jd/blockchain/ledger/core/AccountSet.java | 4 +- .../blockchain/ledger/core/LedgerEditor.java | 6 +- .../ledger/core/LedgerTransactionContext.java | 2 +- .../ledger/core/SettingContext.java | 51 ++ .../ledger/core/impl/LedgerBlockData.java | 14 +- .../core/impl/LedgerRepositoryImpl.java | 24 +- .../core/impl/LedgerTransactionData.java | 66 +-- .../core/impl/LedgerTransactionalEditor.java | 501 +++++++++++------- .../core/impl/TransactionBatchProcessor.java | 104 ++-- .../blockchain/ledger/LedgerEditorTest.java | 2 +- .../blockchain/ledger/LedgerManagerTest.java | 6 +- .../jd/blockchain/ledger/LedgerTestUtils.java | 39 ++ .../blockchain/ledger/MerkleDataSetTest.java | 6 + .../ledger/TransactionBatchProcessorTest.java | 135 ++++- .../com/jd/blockchain/ledger/BlockBody.java | 3 + .../ledger/BlockRollbackException.java | 33 ++ .../ledger/IllegalTransactionException.java | 35 ++ .../ledger/TransactionContentBody.java | 2 +- .../ledger/TransactionException.java | 22 - .../ledger/TransactionRollbackException.java | 16 + .../blockchain/ledger/TransactionState.java | 54 +- .../blockchain/transaction/TxContentBlob.java | 2 +- .../storage/service/VersioningKVStorage.java | 4 +- 24 files changed, 782 insertions(+), 350 deletions(-) create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SettingContext.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockRollbackException.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/IllegalTransactionException.java delete mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionException.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRollbackException.java diff --git a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java index 162ff130..ba330e04 100644 --- a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java +++ b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java @@ -243,6 +243,7 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer messageHandle.commitBatch(realmName, batchId); } catch (Exception e) { // todo 需要处理应答码 404 + LOGGER.error("Error occurred while processing ordered messages! --" + e.getMessage(), e); messageHandle.rollbackBatch(realmName, batchId, TransactionState.CONSENSUS_ERROR.CODE); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountSet.java index a28a5fb5..bb57cd3c 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountSet.java @@ -333,9 +333,9 @@ public class AccountSet implements Transactional, MerkleProvable { if (!updated) { return; } - String[] addresses = new String[latestAccountsCache.size()]; + Bytes[] addresses = new Bytes[latestAccountsCache.size()]; latestAccountsCache.keySet().toArray(addresses); - for (String address : addresses) { + for (Bytes address : addresses) { VersioningAccount acc = latestAccountsCache.remove(address); // cancel; if (acc.isUpdated()) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java index ced98b45..46c21655 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerEditor.java @@ -50,9 +50,11 @@ public interface LedgerEditor { * 每一次事务性的账本写入操作在提交后,都会记录该事务相关的系统全局快照,以交易对象 {@link LedgerTransaction} 进行保存; *

* - * 注:方法不解析、不执行交易中的操作; * - * @param txRequest + * + * 注:方法不解析、不执行交易中的操作;

+ * + * @param txRequest 交易请求; * @return */ LedgerTransactionContext newTransaction(TransactionRequest txRequest); diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java index 33f589c5..a4feb79e 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java @@ -24,7 +24,7 @@ public interface LedgerTransactionContext { * * @return */ - TransactionRequest getRequestTX(); + TransactionRequest getTransactionRequest(); /** * 提交对账本数据的修改,以指定的交易状态提交交易; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SettingContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SettingContext.java new file mode 100644 index 00000000..516b2acf --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SettingContext.java @@ -0,0 +1,51 @@ +package com.jd.blockchain.ledger.core; + +public class SettingContext { + + private static final TxSettingContext txSettings = new TxSettingContext(); + + private static final QueryingSettingContext queryingSettings = new QueryingSettingContext(); + + public static TxSettingContext txSettings() { + return txSettings; + } + + public static QueryingSettingContext queryingSettings() { + return queryingSettings; + } + + /** + * 与交易处理相关的设置; + * @author huanghaiquan + * + */ + public static class TxSettingContext { + + public boolean verifyLedger() { + return true; + } + + public boolean verifySignature() { + return true; + } + + } + + /** + * 与账本查询相关的设置; + * @author huanghaiquan + * + */ + public static class QueryingSettingContext { + + /** + * 查询区块等具有 hash 标识符的对象时是否重新校验哈希; + * @return + */ + public boolean verifyHash() { + return false; + } + + } + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerBlockData.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerBlockData.java index 24b20401..1e8865b7 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerBlockData.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerBlockData.java @@ -33,7 +33,9 @@ public class LedgerBlockData implements LedgerBlock { // private HashDigest contractPrivilegeHash; private HashDigest transactionSetHash; - + + private long timestamp; + public LedgerBlockData() { } @@ -155,4 +157,14 @@ public class LedgerBlockData implements LedgerBlock { this.ledgerHash = ledgerHash; } + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + + } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java index 7b9b4a9a..1fe559b7 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerRepositoryImpl.java @@ -15,6 +15,7 @@ import com.jd.blockchain.ledger.core.LedgerDataSet; import com.jd.blockchain.ledger.core.LedgerEditor; import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.ledger.core.LedgerTransactionContext; +import com.jd.blockchain.ledger.core.SettingContext; import com.jd.blockchain.ledger.core.TransactionSet; import com.jd.blockchain.ledger.core.UserAccountSet; import com.jd.blockchain.storage.service.ExPolicyKVStorage; @@ -77,7 +78,7 @@ public class LedgerRepositoryImpl implements LedgerRepository { this.ledgerIndexKey = encodeLedgerIndexKey(ledgerHash); if (getLatestBlockHeight() < 0) { - throw new LedgerException("Ledger doesn't exist!"); + throw new RuntimeException("Ledger doesn't exist!"); } } @@ -205,15 +206,14 @@ public class LedgerRepositoryImpl implements LedgerRepository { LedgerBlockData block = new LedgerBlockData(deserialize(blockBytes)); if (!blockHash.equals(block.getHash())) { - throw new LedgerException("Block hash not equals to it's storage key!"); + throw new RuntimeException("Block hash not equals to it's storage key!"); } // verify hash; // boolean requiredVerifyHash = // adminAccount.getMetadata().getSetting().getCryptoSetting().getAutoVerifyHash(); // TODO: 未实现从配置中加载是否校验 Hash 的设置; - boolean requiredVerifyHash = false; - if (requiredVerifyHash) { + if (SettingContext.queryingSettings().verifyHash()) { byte[] blockBodyBytes = null; if (block.getHeight() == 0) { // 计算创世区块的 hash 时,不包括 ledgerHash 字段; @@ -227,14 +227,14 @@ public class LedgerRepositoryImpl implements LedgerRepository { HashFunction hashFunc = Crypto.getHashFunction(blockHash.getAlgorithm()); boolean pass = hashFunc.verify(blockHash, blockBodyBytes); if (!pass) { - throw new LedgerException("Block hash verification fail!"); + throw new RuntimeException("Block hash verification fail!"); } } // verify height; HashDigest indexedHash = getBlockHash(block.getHeight()); if (indexedHash == null || !indexedHash.equals(blockHash)) { - throw new LedgerException( + throw new RuntimeException( "Illegal ledger state in storage that ledger height index doesn't match it's block data in height[" + block.getHeight() + "] and block hash[" + Base58Utils.encode(blockHash.toBytes()) + "] !"); @@ -394,15 +394,15 @@ public class LedgerRepositoryImpl implements LedgerRepository { @Override public synchronized LedgerEditor createNextBlock() { if (closed) { - throw new LedgerException("Ledger repository has been closed!"); + throw new RuntimeException("Ledger repository has been closed!"); } if (this.nextBlockEditor != null) { - throw new LedgerException( + throw new RuntimeException( "A new block is in process, cann't create another one until it finish by committing or canceling."); } LedgerBlock previousBlock = getLatestBlock(); - LedgerTransactionalEditor editor = LedgerTransactionalEditor.createEditor(ledgerHash, - getAdminInfo().getMetadata().getSetting(), previousBlock, keyPrefix, exPolicyStorage, + LedgerTransactionalEditor editor = LedgerTransactionalEditor.createEditor(previousBlock, + getAdminInfo().getMetadata().getSetting(), keyPrefix, exPolicyStorage, versioningStorage); NewBlockCommittingMonitor committingMonitor = new NewBlockCommittingMonitor(editor, this); this.nextBlockEditor = committingMonitor; @@ -420,7 +420,7 @@ public class LedgerRepositoryImpl implements LedgerRepository { return; } if (this.nextBlockEditor != null) { - throw new LedgerException("A new block is in process, cann't close the ledger repository!"); + throw new RuntimeException("A new block is in process, cann't close the ledger repository!"); } closed = true; } @@ -600,7 +600,7 @@ public class LedgerRepositoryImpl implements LedgerRepository { public void commit() { try { editor.commit(); - LedgerBlock latestBlock = editor.getNewlyBlock(); + LedgerBlock latestBlock = editor.getCurrentBlock(); ledgerRepo.latestState = new LedgerState(latestBlock); } finally { ledgerRepo.nextBlockEditor = null; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java index 6e231b44..432c24e1 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java @@ -1,8 +1,5 @@ package com.jd.blockchain.ledger.core.impl; -import java.util.Arrays; -import java.util.Comparator; - import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.DigitalSignature; import com.jd.blockchain.ledger.LedgerTransaction; @@ -29,48 +26,27 @@ public class LedgerTransactionData implements LedgerTransaction { private OperationResult[] operationResults; - // private HashDigest adminAccountHash; - // - // private HashDigest userAccountSetHash; - // - // private HashDigest dataAccountSetHash; - // - // private HashDigest contractAccountSetHash; - /** * Declare a private no-arguments constructor for deserializing purpose; */ + @SuppressWarnings("unused") private LedgerTransactionData() { -// this.txSnapshot = new TransactionStagedSnapshot(); } /** - * @param blockHeight - * 区块链高度; - * @param txReq - * 交易请求; - * @param execState - * 执行状态; - * @param txSnapshot - * 交易级的系统快照; + * @param blockHeight 区块链高度; + * @param txReq 交易请求; + * @param execState 执行状态; + * @param txSnapshot 交易级的系统快照; */ public LedgerTransactionData(long blockHeight, TransactionRequest txReq, TransactionState execState, TransactionStagedSnapshot txSnapshot, OperationResult... opResults) { this.blockHeight = blockHeight; -// this.txSnapshot = txSnapshot == null ? new TransactionStagedSnapshot() : txSnapshot; this.txSnapshot = txSnapshot; this.transactionContent = txReq.getTransactionContent(); this.endpointSignatures = txReq.getEndpointSignatures(); this.nodeSignatures = txReq.getNodeSignatures(); this.executionState = execState; - if (opResults != null) { - Arrays.sort(opResults, new Comparator() { - @Override - public int compare(OperationResult o1, OperationResult o2) { - return o1.getIndex() - o2.getIndex(); - } - }); - } this.operationResults = opResults; } @@ -116,17 +92,17 @@ public class LedgerTransactionData implements LedgerTransaction { @Override public HashDigest getUserAccountSetHash() { - return txSnapshot == null ? null :txSnapshot.getUserAccountSetHash(); + return txSnapshot == null ? null : txSnapshot.getUserAccountSetHash(); } @Override public HashDigest getDataAccountSetHash() { - return txSnapshot == null ? null :txSnapshot.getDataAccountSetHash(); + return txSnapshot == null ? null : txSnapshot.getDataAccountSetHash(); } @Override public HashDigest getContractAccountSetHash() { - return txSnapshot == null ? null :txSnapshot.getContractAccountSetHash(); + return txSnapshot == null ? null : txSnapshot.getContractAccountSetHash(); } public void setTxSnapshot(TransactionStagedSnapshot txSnapshot) { @@ -140,20 +116,22 @@ public class LedgerTransactionData implements LedgerTransaction { this.transactionContent = content; } - public void setEndpointSignatures(Object[] participantSignatures) { - int length = participantSignatures.length; - this.endpointSignatures = new DigitalSignature[length]; - for (int i = 0; i < length; i++) { - this.endpointSignatures[i] = (DigitalSignature) participantSignatures[i]; - } + public void setEndpointSignatures(DigitalSignature[] participantSignatures) { + this.endpointSignatures = participantSignatures; +// int length = participantSignatures.length; +// this.endpointSignatures = new DigitalSignature[length]; +// for (int i = 0; i < length; i++) { +// this.endpointSignatures[i] = (DigitalSignature) participantSignatures[i]; +// } } - public void setNodeSignatures(Object[] nodeSignatures) { - int length = nodeSignatures.length; - this.nodeSignatures = new DigitalSignature[length]; - for (int i = 0; i < length; i++) { - this.nodeSignatures[i] = (DigitalSignature) nodeSignatures[i]; - } + public void setNodeSignatures(DigitalSignature[] nodeSignatures) { + this.nodeSignatures = nodeSignatures; +// int length = nodeSignatures.length; +// this.nodeSignatures = new DigitalSignature[length]; +// for (int i = 0; i < length; i++) { +// this.nodeSignatures[i] = (DigitalSignature) nodeSignatures[i]; +// } } public void setExecutionState(TransactionState executionState) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java index 5113dde4..235d08b8 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java @@ -1,19 +1,35 @@ package com.jd.blockchain.ledger.core.impl; import java.util.List; -import java.util.Stack; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.crypto.Crypto; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.*; +import com.jd.blockchain.ledger.BlockBody; +import com.jd.blockchain.ledger.BlockRollbackException; +import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.DigitalSignature; +import com.jd.blockchain.ledger.IllegalTransactionException; +import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerDataSnapshot; +import com.jd.blockchain.ledger.LedgerInitSetting; +import com.jd.blockchain.ledger.LedgerSetting; +import com.jd.blockchain.ledger.LedgerTransaction; +import com.jd.blockchain.ledger.OperationResult; +import com.jd.blockchain.ledger.TransactionContent; +import com.jd.blockchain.ledger.TransactionRequest; +import com.jd.blockchain.ledger.TransactionRollbackException; +import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.ledger.core.LedgerDataSet; import com.jd.blockchain.ledger.core.LedgerEditor; import com.jd.blockchain.ledger.core.LedgerTransactionContext; +import com.jd.blockchain.ledger.core.SettingContext; import com.jd.blockchain.ledger.core.TransactionSet; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.storage.service.utils.BufferedKVStorage; +import com.jd.blockchain.transaction.TxBuilder; +import com.jd.blockchain.transaction.TxRequestBuilder; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.codec.Base58Utils; @@ -35,9 +51,9 @@ public class LedgerTransactionalEditor implements LedgerEditor { private CryptoSetting cryptoSetting; - private LedgerBlockData newlyBlock; + private LedgerBlockData currentBlock; - private Stack stagedSnapshots = new Stack<>(); +// private Stack stagedSnapshots = new Stack<>(); private boolean prepared = false; @@ -45,43 +61,70 @@ public class LedgerTransactionalEditor implements LedgerEditor { private boolean committed = false; -// private BufferedKVStorage baseStorage; - private BufferedKVStorage bufferedStorage; + private StagedSnapshot startingPoint; /** - * 最近一个交易上下文; + * 当前区块的存储; */ - private LedgerDataContext lastTxCtx; + private BufferedKVStorage baseStorage; - private LedgerDataContext newTxCtx; + /** + * 上一个交易的上下文; + */ +// private LedgerTransactionContextImpl previousTxCtx; + + private TxSnapshot previousTxSnapshot; + + /** + * 当前交易的上下文; + */ + private volatile LedgerTransactionContextImpl currentTxCtx; - private LedgerTransactionalEditor(HashDigest ledgerHash, CryptoSetting cryptoSetting, LedgerBlockData newlyBlock, + /** + * @param ledgerHash + * @param cryptoSetting + * @param currentBlock + * @param startingPoint + * @param ledgerKeyPrefix + * @param bufferedStorage + * @param verifyTx 是否校验交易请求;当外部调用者在调用前已经实施了验证时,将次参数设置为 false 能够提升性能; + */ + private LedgerTransactionalEditor(HashDigest ledgerHash, CryptoSetting cryptoSetting, LedgerBlockData currentBlock, StagedSnapshot startingPoint, String ledgerKeyPrefix, BufferedKVStorage bufferedStorage) { this.ledgerHash = ledgerHash; this.ledgerKeyPrefix = ledgerKeyPrefix; this.cryptoSetting = cryptoSetting; - this.newlyBlock = newlyBlock; - this.bufferedStorage = bufferedStorage; + this.currentBlock = currentBlock; + this.baseStorage = bufferedStorage; + + this.startingPoint = startingPoint; - this.stagedSnapshots.push(startingPoint); +// this.stagedSnapshots.push(startingPoint); } /** * 创建账本新区块的编辑器; * - * @param ledgerHash - * @param ledgerSetting - * @param previousBlock - * @param ledgerKeyPrefix - * @param ledgerExStorage - * @param ledgerVerStorage + * @param ledgerHash 账本哈希; + * @param ledgerSetting 账本设置; + * @param previousBlock 前置区块; + * @param ledgerKeyPrefix 账本数据前缀; + * @param ledgerExStorage 账本数据存储; + * @param ledgerVerStorage 账本数据版本化存储; + * @param verifyTx 是否校验交易请求;当外部调用者在调用前已经实施了验证时,将次参数设置为 false 能够提升性能; * @return */ - public static LedgerTransactionalEditor createEditor(HashDigest ledgerHash, LedgerSetting ledgerSetting, - LedgerBlock previousBlock, String ledgerKeyPrefix, ExPolicyKVStorage ledgerExStorage, - VersioningKVStorage ledgerVerStorage) { + public static LedgerTransactionalEditor createEditor(LedgerBlock previousBlock, LedgerSetting ledgerSetting, + String ledgerKeyPrefix, ExPolicyKVStorage ledgerExStorage, VersioningKVStorage ledgerVerStorage) { // new block; - LedgerBlockData currBlock = new LedgerBlockData(previousBlock.getHeight() + 1, previousBlock.getLedgerHash(), + HashDigest ledgerHash = previousBlock.getLedgerHash(); + if (ledgerHash == null) { + ledgerHash = previousBlock.getHash(); + } + if (ledgerHash == null) { + throw new IllegalArgumentException("Illegal previous block was specified!"); + } + LedgerBlockData currBlock = new LedgerBlockData(previousBlock.getHeight() + 1, ledgerHash, previousBlock.getHash()); // init storage; @@ -101,6 +144,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { * @param ledgerKeyPrefix * @param ledgerExStorage * @param ledgerVerStorage + * @param verifyTx 是否校验交易请求;当外部调用者在调用前已经实施了验证时,将次参数设置为 false 能够提升性能; * @return */ public static LedgerTransactionalEditor createEditor(LedgerInitSetting initSetting, String ledgerKeyPrefix, @@ -114,29 +158,21 @@ public class LedgerTransactionalEditor implements LedgerEditor { } private void commitTxSnapshot(TxSnapshot snapshot) { - lastTxCtx = newTxCtx; - newTxCtx = null; - stagedSnapshots.push(snapshot); + previousTxSnapshot = snapshot; + currentTxCtx = null; } - private void rollbackNewTx() { - newTxCtx = null; + private void rollbackCurrentTx() { + currentTxCtx = null; } - // public LedgerDataSet getLatestDataSet() { - // if (lastTxCtx == null) { - // return null; - // } - // return lastTxCtx.getDataSet(); - // } - - LedgerBlock getNewlyBlock() { - return newlyBlock; + LedgerBlock getCurrentBlock() { + return currentBlock; } @Override public long getBlockHeight() { - return newlyBlock.getHeight(); + return currentBlock.getHeight(); } @Override @@ -161,134 +197,182 @@ public class LedgerTransactionalEditor implements LedgerEditor { return ledgerHash.equals(reqLedgerHash); } + private boolean verifyTxContent(TransactionRequest request) { + TransactionContent txContent = request.getTransactionContent(); + if (!TxBuilder.verifyTxContentHash(txContent, txContent.getHash())) { + return false; + } + DigitalSignature[] endpointSignatures = request.getEndpointSignatures(); + if (endpointSignatures != null) { + for (DigitalSignature signature : endpointSignatures) { + if (!TxRequestBuilder.verifyHashSignature(txContent.getHash(), signature.getDigest(), + signature.getPubKey())) { + return false; + } + } + } + DigitalSignature[] nodeSignatures = request.getNodeSignatures(); + if (nodeSignatures != null) { + for (DigitalSignature signature : nodeSignatures) { + if (!TxRequestBuilder.verifyHashSignature(txContent.getHash(), signature.getDigest(), + signature.getPubKey())) { + return false; + } + } + } + return true; + } + @Override - public LedgerTransactionContext newTransaction(TransactionRequest txRequest) { - // 验证账本是否; - if (!isRequestedLedger(txRequest)) { - throw new LedgerException("This ledger is not the target ledger of transaction request[" - + txRequest.getTransactionContent().getHash() + "]!"); + public synchronized LedgerTransactionContext newTransaction(TransactionRequest txRequest) { + if (SettingContext.txSettings().verifyLedger() && !isRequestedLedger(txRequest)) { + throw new IllegalTransactionException( + "Transaction request is dispatched to a wrong ledger! --[TxHash=" + + txRequest.getTransactionContent().getHash() + "]!", + TransactionState.IGNORED_BY_WRONG_LEDGER); + } + + // TODO: 把验签和创建交易并行化; + if (SettingContext.txSettings().verifySignature() && !verifyTxContent(txRequest)) { + // 抛弃哈希和签名校验失败的交易请求; + throw new IllegalTransactionException( + "Wrong transaction signature! --[TxHash=" + txRequest.getTransactionContent().getHash() + "]!", + TransactionState.IGNORED_BY_WRONG_CONTENT_SIGNATURE); + } + + if (currentTxCtx != null) { + throw new IllegalStateException( + "Unable to open another new transaction before the current transaction is completed! --[TxHash=" + + txRequest.getTransactionContent().getHash() + "]!"); } // 检查状态是否允许创建新的交易请求;; checkState(); - BufferedKVStorage txBuffStorage = null; + // init storage of new transaction; + BufferedKVStorage txBufferedStorage = new BufferedKVStorage(baseStorage, baseStorage, false); + LedgerDataSetImpl txDataset = null; TransactionSet txset = null; - if (lastTxCtx == null) { - // init storage of new transaction; - // txBuffStorage = new BufferedKVStorage(bufferedStorage, bufferedStorage, - // false); - txBuffStorage = bufferedStorage; - + if (previousTxSnapshot == null) { // load the starting point of the new transaction; - StagedSnapshot previousSnapshot = stagedSnapshots.peek(); - if (previousSnapshot instanceof GenesisSnapshot) { + if (startingPoint instanceof GenesisSnapshot) { // 准备生成创世区块; - GenesisSnapshot snpht = (GenesisSnapshot) previousSnapshot; - txDataset = LedgerRepositoryImpl.newDataSet(snpht.initSetting, ledgerKeyPrefix, txBuffStorage, - txBuffStorage); + GenesisSnapshot snpht = (GenesisSnapshot) startingPoint; + txDataset = LedgerRepositoryImpl.newDataSet(snpht.initSetting, ledgerKeyPrefix, txBufferedStorage, + txBufferedStorage); txset = LedgerRepositoryImpl.newTransactionSet(txDataset.getAdminAccount().getSetting(), - ledgerKeyPrefix, txBuffStorage, txBuffStorage); - } else { + ledgerKeyPrefix, txBufferedStorage, txBufferedStorage); + } else if (startingPoint instanceof TxSnapshot) { // 新的区块; // TxSnapshot; reload dataset and txset; - TxSnapshot snpht = (TxSnapshot) previousSnapshot; + TxSnapshot snpht = (TxSnapshot) startingPoint; // load dataset; - txDataset = LedgerRepositoryImpl.loadDataSet(snpht.dataSnapshot, ledgerKeyPrefix, txBuffStorage, - txBuffStorage, false); + txDataset = LedgerRepositoryImpl.loadDataSet(snpht.dataSnapshot, ledgerKeyPrefix, txBufferedStorage, + txBufferedStorage, false); - // load tx set; - txset = LedgerRepositoryImpl.loadTransactionSet(snpht.transactionSetHash, this.cryptoSetting, - ledgerKeyPrefix, txBuffStorage, txBuffStorage, false); + // load txset; + txset = LedgerRepositoryImpl.loadTransactionSet(snpht.txsetHash, this.cryptoSetting, ledgerKeyPrefix, + txBufferedStorage, txBufferedStorage, false); + } else { + // Unreachable; + throw new IllegalStateException("Unreachable code was accidentally executed!"); } - lastTxCtx = new LedgerDataContext(txDataset, txset, txBuffStorage); } else { // Reuse previous object to optimize performance; - txBuffStorage = lastTxCtx.storage; - txDataset = lastTxCtx.dataset; - txset = lastTxCtx.txset; + // load dataset; + txDataset = LedgerRepositoryImpl.loadDataSet(previousTxSnapshot.dataSnapshot, ledgerKeyPrefix, + txBufferedStorage, txBufferedStorage, false); + + // load txset; + txset = LedgerRepositoryImpl.loadTransactionSet(previousTxSnapshot.txsetHash, this.cryptoSetting, + ledgerKeyPrefix, txBufferedStorage, txBufferedStorage, false); } - // newTxCtx = new LedgerTransactionContextImpl(newlyBlock.getHeight(), - // txRequest, txDataset, txset, txBuffStorage, - // this); - // return newTxCtx; + currentTxCtx = new LedgerTransactionContextImpl(txRequest, txDataset, txset, txBufferedStorage, this); - return new LedgerTransactionContextImpl(newlyBlock.getHeight(), txRequest, txDataset, txset, txBuffStorage, - this); + return currentTxCtx; } @Override public LedgerBlock prepare() { checkState(); - if (newTxCtx != null) { - throw new IllegalStateException("There is a opening transaction which isn't committed or rollbacked!"); + if (currentTxCtx != null) { + // 有进行中的交易尚未提交或回滚; + throw new IllegalStateException( + "There is an ongoing transaction that has been not committed or rolled back!"); } - if (lastTxCtx == null) { - // Genesis; - throw new IllegalStateException("No transaction to prepare!"); + if (previousTxSnapshot == null) { + // 当前区块没有加入过交易,不允许产生空区块; + throw new IllegalStateException( + "There is no transaction in the current block, and no empty blocks is allowed!"); } // do commit when transaction isolation level is BLOCK; - lastTxCtx.dataset.commit(); - lastTxCtx.txset.commit(); + currentBlock.setAdminAccountHash(previousTxSnapshot.getAdminAccountHash()); + currentBlock.setUserAccountSetHash(previousTxSnapshot.getUserAccountSetHash()); + currentBlock.setDataAccountSetHash(previousTxSnapshot.getDataAccountSetHash()); + currentBlock.setContractAccountSetHash(previousTxSnapshot.getContractAccountSetHash()); + currentBlock.setTransactionSetHash(previousTxSnapshot.getTransactionSetHash()); - newlyBlock.setAdminAccountHash(lastTxCtx.dataset.getAdminAccount().getHash()); - newlyBlock.setContractAccountSetHash(lastTxCtx.dataset.getContractAccountSet().getRootHash()); - newlyBlock.setDataAccountSetHash(lastTxCtx.dataset.getDataAccountSet().getRootHash()); - newlyBlock.setUserAccountSetHash(lastTxCtx.dataset.getUserAccountSet().getRootHash()); - newlyBlock.setTransactionSetHash(lastTxCtx.txset.getRootHash()); + // TODO: 根据所有交易的时间戳的平均值来生成区块的时间戳; +// long timestamp = +// currentBlock.setTimestamp(timestamp); // compute block hash; - byte[] blockBodyBytes = BinaryProtocol.encode(newlyBlock, BlockBody.class); + byte[] blockBodyBytes = BinaryProtocol.encode(currentBlock, BlockBody.class); HashDigest blockHash = Crypto.getHashFunction(cryptoSetting.getHashAlgorithm()).hash(blockBodyBytes); - newlyBlock.setHash(blockHash); - if (newlyBlock.getLedgerHash() == null) { - // init GenesisBlock's ledger hash; - newlyBlock.setLedgerHash(blockHash); - } + currentBlock.setHash(blockHash); + +// if (currentBlock.getLedgerHash() == null) { +// // init GenesisBlock's ledger hash; +// currentBlock.setLedgerHash(blockHash); +// } // persist block bytes; // only one version per block; - byte[] blockBytes = BinaryProtocol.encode(newlyBlock, LedgerBlock.class); - Bytes blockStorageKey = LedgerRepositoryImpl.encodeBlockStorageKey(newlyBlock.getHash()); - long v = bufferedStorage.set(blockStorageKey, blockBytes, -1); + byte[] blockBytes = BinaryProtocol.encode(currentBlock, LedgerBlock.class); + Bytes blockStorageKey = LedgerRepositoryImpl.encodeBlockStorageKey(currentBlock.getHash()); + long v = baseStorage.set(blockStorageKey, blockBytes, -1); if (v < 0) { throw new IllegalStateException( - "Block already exist! --[BlockHash=" + Base58Utils.encode(newlyBlock.getHash().toBytes()) + "]"); + "Block already exist! --[BlockHash=" + Base58Utils.encode(currentBlock.getHash().toBytes()) + "]"); } // persist block hash to ledger index; - HashDigest ledgerHash = newlyBlock.getLedgerHash(); + HashDigest ledgerHash = currentBlock.getLedgerHash(); + if (ledgerHash == null) { + ledgerHash = blockHash; + } Bytes ledgerIndexKey = LedgerRepositoryImpl.encodeLedgerIndexKey(ledgerHash); - long expectedVersion = newlyBlock.getHeight() - 1; - v = bufferedStorage.set(ledgerIndexKey, newlyBlock.getHash().toBytes(), expectedVersion); + long expectedVersion = currentBlock.getHeight() - 1; + v = baseStorage.set(ledgerIndexKey, currentBlock.getHash().toBytes(), expectedVersion); if (v < 0) { - throw new IllegalStateException("Index of BlockHash already exist! --[BlockHash=" - + Base58Utils.encode(newlyBlock.getHash().toBytes()) + "]"); + throw new IllegalStateException( + String.format("Index of BlockHash already exist! --[BlockHeight=%s][BlockHash=%s]", + currentBlock.getHeight(), currentBlock.getHash())); } prepared = true; - return newlyBlock; + return currentBlock; } @Override public void commit() { if (committed) { - throw new IllegalStateException("LedgerEditor had been committed!"); + throw new IllegalStateException("The current block has been committed!"); } if (canceled) { - throw new IllegalStateException("LedgerEditor had been canceled!"); + throw new IllegalStateException("The current block has been canceled!"); } if (!prepared) { // 未就绪; - throw new IllegalStateException("LedgerEditor has not prepared!"); + throw new IllegalStateException("The current block is not ready yet!"); } - bufferedStorage.flush(); + baseStorage.flush(); committed = true; } @@ -296,38 +380,47 @@ public class LedgerTransactionalEditor implements LedgerEditor { @Override public void cancel() { if (committed) { - throw new IllegalStateException("LedgerEditor had been committed!"); + throw new IllegalStateException("The current block has been committed!"); } if (canceled) { return; } canceled = true; - // if (newTxCtx != null) { - // newTxCtx.rollback(); - // newTxCtx = null; - // } - bufferedStorage.cancel(); + + baseStorage.cancel(); } private void checkState() { if (prepared) { - throw new IllegalStateException("LedgerEditor has been prepared!"); + throw new IllegalStateException("The current block is ready!"); } if (committed) { - throw new IllegalStateException("LedgerEditor has been committed!"); + throw new IllegalStateException("The current block has been committed!"); } if (canceled) { - throw new IllegalStateException("LedgerEditor has been canceled!"); + throw new IllegalStateException("The current block has been canceled!"); } } // --------------------------- inner type -------------------------- + /** + * 用于暂存交易上下文数据的快照对象; + * + * @author huanghaiquan + * + */ private static interface StagedSnapshot { } + /** + * 创世区块的快照对象; + * + * @author huanghaiquan + * + */ private static class GenesisSnapshot implements StagedSnapshot { private LedgerInitSetting initSetting; @@ -337,6 +430,12 @@ public class LedgerTransactionalEditor implements LedgerEditor { } } + /** + * 交易执行完毕后的快照对象; + * + * @author huanghaiquan + * + */ private static class TxSnapshot implements StagedSnapshot { /** @@ -347,58 +446,90 @@ public class LedgerTransactionalEditor implements LedgerEditor { /** * 交易集合的快照(根哈希); */ - private HashDigest transactionSetHash; + private HashDigest txsetHash; - public TxSnapshot(LedgerDataSnapshot dataSnapshot, HashDigest txSetHash) { - this.dataSnapshot = dataSnapshot; - this.transactionSetHash = txSetHash; + public HashDigest getAdminAccountHash() { + return dataSnapshot.getAdminAccountHash(); } - } - - private static class LedgerDataContext { + public HashDigest getUserAccountSetHash() { + return dataSnapshot.getUserAccountSetHash(); + } - protected LedgerDataSetImpl dataset; + public HashDigest getDataAccountSetHash() { + return dataSnapshot.getDataAccountSetHash(); + } - protected TransactionSet txset; + public HashDigest getContractAccountSetHash() { + return dataSnapshot.getContractAccountSetHash(); + } - protected BufferedKVStorage storage; + public HashDigest getTransactionSetHash() { + return txsetHash; + } - public LedgerDataContext(LedgerDataSetImpl dataset, TransactionSet txset, BufferedKVStorage storage) { - this.dataset = dataset; - this.txset = txset; - this.storage = storage; + public TxSnapshot(LedgerDataSnapshot dataSnapshot, HashDigest txsetHash) { + this.dataSnapshot = dataSnapshot; + this.txsetHash = txsetHash; } } - private static class LedgerTransactionContextImpl extends LedgerDataContext implements LedgerTransactionContext { +// /** +// * 账本的数据上下文; +// * +// * @author huanghaiquan +// * +// */ +// private static class LedgerDataContext { +// +// protected LedgerDataSetImpl dataset; +// +// protected TransactionSet txset; +// +// protected BufferedKVStorage storage; +// +// public LedgerDataContext(LedgerDataSetImpl dataset, TransactionSet txset, BufferedKVStorage storage) { +// this.dataset = dataset; +// this.txset = txset; +// this.storage = storage; +// } +// +// } - private long blockHeight; + /** + * 交易的上下文; + * + * @author huanghaiquan + * + */ + private static class LedgerTransactionContextImpl implements LedgerTransactionContext { - private LedgerTransactionalEditor editor; + private LedgerTransactionalEditor blockEditor; private TransactionRequest txRequest; - // private LedgerDataSetImpl dataset; - // - // private TransactionSet txset; - // - // private BufferedKVStorage storage; + private LedgerDataSetImpl dataset; + + private TransactionSet txset; + + private BufferedKVStorage storage; private boolean committed = false; private boolean rollbacked = false; - private LedgerTransactionContextImpl(long blockHeight, TransactionRequest txRequest, LedgerDataSetImpl dataset, + private LedgerTransaction transaction; + + private HashDigest txRootHash; + + private LedgerTransactionContextImpl(TransactionRequest txRequest, LedgerDataSetImpl dataset, TransactionSet txset, BufferedKVStorage storage, LedgerTransactionalEditor editor) { - super(dataset, txset, storage); this.txRequest = txRequest; - // this.dataset = dataset; - // this.txset = txset; - // this.storage = storage; - this.editor = editor; - this.blockHeight = blockHeight; + this.dataset = dataset; + this.txset = txset; + this.storage = storage; + this.blockEditor = editor; } @Override @@ -407,7 +538,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { } @Override - public TransactionRequest getRequestTX() { + public TransactionRequest getTransactionRequest() { return txRequest; } @@ -421,24 +552,28 @@ public class LedgerTransactionalEditor implements LedgerEditor { checkTxState(); // capture snapshot - // this.dataset.commit(); - // TransactionStagedSnapshot txDataSnapshot = takeSnapshot(); - - // LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, - // txResult, txDataSnapshot); - - LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, txResult, null, - operationResultArray(operationResults)); - this.txset.add(tx); - // this.txset.commit(); - - // this.storage.flush(); + this.dataset.commit(); + TransactionStagedSnapshot txDataSnapshot = takeDataSnapshot(); + + LedgerTransactionData tx; + try { + tx = new LedgerTransactionData(blockEditor.getBlockHeight(), txRequest, txResult, txDataSnapshot, + operationResultArray(operationResults)); + this.txset.add(tx); + this.txset.commit(); + } catch (Exception e) { + throw new TransactionRollbackException(e.getMessage(), e); + } - // TODO: 未处理出错时 dataset 和 txset 的内部状态恢复,有可能出现不一致的情况; + try { + this.storage.flush(); + } catch (Exception e) { + throw new BlockRollbackException(e.getMessage(), e); + } // put snapshot into stack; - // TxSnapshot snapshot = new TxSnapshot(txDataSnapshot, txset.getRootHash()); - // editor.commitTxSnapshot(snapshot); + TxSnapshot snapshot = new TxSnapshot(txDataSnapshot, txset.getRootHash()); + blockEditor.commitTxSnapshot(snapshot); committed = true; return tx; @@ -454,29 +589,35 @@ public class LedgerTransactionalEditor implements LedgerEditor { checkTxState(); // 未处理 - // dataset.cancel(); - - // TransactionStagedSnapshot txDataSnapshot = takeSnapshot(); - // LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, - // txResult, txDataSnapshot); - LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, txResult, null, - operationResultArray(operationResults)); - this.txset.add(tx); - // this.txset.commit(); - - // this.storage.flush(); + dataset.cancel(); + + TransactionStagedSnapshot txDataSnapshot = takeDataSnapshot(); + + LedgerTransactionData tx; + try { + tx = new LedgerTransactionData(blockEditor.getBlockHeight(), txRequest, txResult, txDataSnapshot, + operationResultArray(operationResults)); + this.txset.add(tx); + this.txset.commit(); + } catch (Exception e) { + throw new TransactionRollbackException(e.getMessage(), e); + } - // TODO: 未处理出错时 dataset 和 txset 的内部状态恢复,有可能出现不一致的情况; + try { + this.storage.flush(); + } catch (Exception e) { + throw new BlockRollbackException(e.getMessage(), e); + } // put snapshot into stack; - // TxSnapshot snapshot = new TxSnapshot(txDataSnapshot, txset.getRootHash()); - // editor.commitTxSnapshot(snapshot); + TxSnapshot snapshot = new TxSnapshot(txDataSnapshot, txset.getRootHash()); + blockEditor.commitTxSnapshot(snapshot); committed = true; return tx; } - private TransactionStagedSnapshot takeSnapshot() { + private TransactionStagedSnapshot takeDataSnapshot() { TransactionStagedSnapshot txDataSnapshot = new TransactionStagedSnapshot(); txDataSnapshot.setAdminAccountHash(dataset.getAdminAccount().getHash()); txDataSnapshot.setContractAccountSetHash(dataset.getContractAccountSet().getRootHash()); @@ -500,22 +641,22 @@ public class LedgerTransactionalEditor implements LedgerEditor { return; } if (this.committed) { - throw new IllegalStateException("Transaction had been committed!"); + throw new IllegalStateException("This transaction had been committed!"); } - // dataset.cancel(); - // storage.cancel(); + dataset.cancel(); + storage.cancel(); - // editor.rollbackNewTx(); + blockEditor.rollbackCurrentTx(); rollbacked = true; } private void checkTxState() { if (this.committed) { - throw new IllegalStateException("Transaction had been committed!"); + throw new IllegalStateException("This transaction had been committed!"); } if (this.rollbacked) { - throw new IllegalStateException("Transaction had been rollbacked!"); + throw new IllegalStateException("This transaction had been rollbacked!"); } } } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java index 78b099ae..aa8fcf93 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java @@ -8,18 +8,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.BlockRollbackException; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.ContractDoesNotExistException; import com.jd.blockchain.ledger.DataAccountDoesNotExistException; -import com.jd.blockchain.ledger.DigitalSignature; +import com.jd.blockchain.ledger.IllegalTransactionException; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.ledger.OperationResult; import com.jd.blockchain.ledger.OperationResultData; -import com.jd.blockchain.ledger.TransactionContent; import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionResponse; +import com.jd.blockchain.ledger.TransactionRollbackException; import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.ledger.UserDoesNotExistException; import com.jd.blockchain.ledger.core.LedgerDataSet; @@ -31,8 +32,6 @@ import com.jd.blockchain.ledger.core.TransactionRequestContext; import com.jd.blockchain.service.TransactionBatchProcess; import com.jd.blockchain.service.TransactionBatchResult; import com.jd.blockchain.service.TransactionBatchResultHandle; -import com.jd.blockchain.transaction.TxBuilder; -import com.jd.blockchain.transaction.TxRequestBuilder; import com.jd.blockchain.transaction.TxResponseMessage; import com.jd.blockchain.utils.Bytes; @@ -70,18 +69,6 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { this.ledgerService = ledgerService; } - private boolean isRequestedLedger(TransactionRequest txRequest) { - HashDigest currLedgerHash = newBlockEditor.getLedgerHash(); - HashDigest reqLedgerHash = txRequest.getTransactionContent().getLedgerHash(); - if (currLedgerHash == reqLedgerHash) { - return true; - } - if (currLedgerHash == null || reqLedgerHash == null) { - return false; - } - return currLedgerHash.equals(reqLedgerHash); - } - /* * (non-Javadoc) * @@ -93,19 +80,6 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { public TransactionResponse schedule(TransactionRequest request) { TransactionResponse resp; try { - if (!isRequestedLedger(request)) { - // 抛弃不属于当前账本的交易请求; - resp = discard(request, TransactionState.DISCARD_BY_WRONG_LEDGER); - responseList.add(resp); - return resp; - } - if (!verifyTxContent(request)) { - // 抛弃哈希和签名校验失败的交易请求; - resp = discard(request, TransactionState.DISCARD_BY_WRONG_CONTENT_SIGNATURE); - responseList.add(resp); - return resp; - } - LOGGER.debug("Start handling transaction... --[BlockHeight={}][RequestHash={}][TxHash={}]", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash()); // 创建交易上下文; @@ -118,19 +92,34 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { LOGGER.debug("Complete handling transaction. --[BlockHeight={}][RequestHash={}][TxHash={}]", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash()); - responseList.add(resp); - return resp; + } catch (IllegalTransactionException e) { + // 抛弃发生处理异常的交易请求; + resp = discard(request, e.getTxState()); + LOGGER.error(String.format( + "Ignore transaction caused by IllegalTransactionException! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), + e.getMessage()), e); + + } catch (BlockRollbackException e) { + // 抛弃发生处理异常的交易请求; +// resp = discard(request, TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK); + LOGGER.error(String.format( + "Ignore transaction caused by BlockRollbackException! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), + e.getMessage()), e); + throw e; } catch (Exception e) { // 抛弃发生处理异常的交易请求; resp = discard(request, TransactionState.SYSTEM_ERROR); LOGGER.error(String.format( - "Discard transaction rollback caused by the system exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + "Ignore transaction caused by the system exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), e.getMessage()), e); - responseList.add(resp); - return resp; } + + responseList.add(resp); + return resp; } /** @@ -186,6 +175,23 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { // 提交交易(事务); result = TransactionState.SUCCESS; txCtx.commit(result, operationResults); + } catch (TransactionRollbackException e) { + result = TransactionState.IGNORED_BY_TX_FULL_ROLLBACK; + txCtx.rollback(); + LOGGER.error(String.format( + "Transaction was full rolled back! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), + e.getMessage()), e); + } catch (BlockRollbackException e) { + result = TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK; + txCtx.rollback(); + LOGGER.error( + String.format("Transaction was rolled back! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + newBlockEditor.getBlockHeight(), request.getHash(), + request.getTransactionContent().getHash(), e.getMessage()), + e); + // 重新抛出由上层错误处理; + throw e; } catch (LedgerException e) { // TODO: 识别更详细的异常类型以及执行对应的处理; result = TransactionState.LEDGER_ERROR; @@ -198,14 +204,14 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { } txCtx.discardAndCommit(result, operationResults); LOGGER.error(String.format( - "Transaction rollback caused by the ledger exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + "Due to ledger exception, the data changes resulting from the transaction will be rolled back and the results of the transaction will be committed! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), e.getMessage()), e); } catch (Exception e) { result = TransactionState.SYSTEM_ERROR; txCtx.discardAndCommit(TransactionState.SYSTEM_ERROR, operationResults); LOGGER.error(String.format( - "Transaction rollback caused by the system exception! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", + "Due to system exception, the data changes resulting from the transaction will be rolled back and the results of the transaction will be committed! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), e.getMessage()), e); } @@ -218,32 +224,6 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { return resp; } - private boolean verifyTxContent(TransactionRequest request) { - TransactionContent txContent = request.getTransactionContent(); - if (!TxBuilder.verifyTxContentHash(txContent, txContent.getHash())) { - return false; - } - DigitalSignature[] endpointSignatures = request.getEndpointSignatures(); - if (endpointSignatures != null) { - for (DigitalSignature signature : endpointSignatures) { - if (!TxRequestBuilder.verifyHashSignature(txContent.getHash(), signature.getDigest(), - signature.getPubKey())) { - return false; - } - } - } - DigitalSignature[] nodeSignatures = request.getNodeSignatures(); - if (nodeSignatures != null) { - for (DigitalSignature signature : nodeSignatures) { - if (!TxRequestBuilder.verifyHashSignature(txContent.getHash(), signature.getDigest(), - signature.getPubKey())) { - return false; - } - } - } - return true; - } - /** * 直接丢弃交易; * diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java index 7ce6908b..c75b624a 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java @@ -138,7 +138,7 @@ public class LedgerEditorTest { LedgerTransaction tx = genisisTxCtx.commit(TransactionState.SUCCESS); - TransactionRequest genesisTxReq = genisisTxCtx.getRequestTX(); + TransactionRequest genesisTxReq = genisisTxCtx.getTransactionRequest(); assertEquals(genesisTxReq.getTransactionContent().getHash(), tx.getTransactionContent().getHash()); assertEquals(0, tx.getBlockHeight()); 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 73e4a8c1..dfc17f24 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 @@ -116,7 +116,8 @@ public class LedgerManagerTest { assertEquals(0, genesisBlock.getHeight()); assertNotNull(genesisBlock.getHash()); assertNull(genesisBlock.getPreviousHash()); - assertEquals(ledgerHash, genesisBlock.getLedgerHash()); + // 创世区块的账本hash 为null;创世区块本身的哈希就代表了账本的哈希; + assertNull(genesisBlock.getLedgerHash()); // 提交数据,写入存储; ldgEdt.commit(); @@ -131,7 +132,8 @@ public class LedgerManagerTest { LedgerBlock latestBlock = reloadLedgerRepo.getLatestBlock(); assertEquals(0, latestBlock.getHeight()); assertEquals(ledgerHash, latestBlock.getHash()); - assertEquals(ledgerHash, latestBlock.getLedgerHash()); + // 创世区块的账本hash 为null;创世区块本身的哈希就代表了账本的哈希; + assertNull(latestBlock.getLedgerHash()); LedgerEditor editor1 = reloadLedgerRepo.createNextBlock(); 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 9fae875a..6101cdba 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 @@ -24,6 +24,7 @@ import com.jd.blockchain.transaction.ConsensusParticipantData; import com.jd.blockchain.transaction.LedgerInitSettingData; import com.jd.blockchain.transaction.TransactionService; import com.jd.blockchain.transaction.TxBuilder; +import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.io.BytesUtils; import com.jd.blockchain.utils.net.NetworkAddress; @@ -124,6 +125,44 @@ public class LedgerTestUtils { return txReqBuilder.buildRequest(); } + + public static TransactionRequest createTxRequest_DataAccountReg(BlockchainKeypair dataAccountID, HashDigest ledgerHash, + BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { + TxBuilder txBuilder = new TxBuilder(ledgerHash); + + txBuilder.dataAccounts().register(dataAccountID.getIdentity()); + + TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); + if (signers != null) { + for (BlockchainKeypair signer : signers) { + txReqBuilder.signAsEndpoint(signer); + } + } + if (nodeKeypair != null) { + txReqBuilder.signAsNode(nodeKeypair); + } + + return txReqBuilder.buildRequest(); + } + + public static TransactionRequest createTxRequest_DataAccountWrite(Bytes dataAccountAddress, String key, String value, long version, HashDigest ledgerHash, + BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { + TxBuilder txBuilder = new TxBuilder(ledgerHash); + + txBuilder.dataAccount(dataAccountAddress).setText(key, value, version); + + TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); + if (signers != null) { + for (BlockchainKeypair signer : signers) { + txReqBuilder.signAsEndpoint(signer); + } + } + if (nodeKeypair != null) { + txReqBuilder.signAsNode(nodeKeypair); + } + + return txReqBuilder.buildRequest(); + } /** * @param userKeypair 要注册的用户key; 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 fbb5eb09..ce571d71 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 @@ -58,6 +58,7 @@ public class MerkleDataSetTest { mds.setValue("C", "C".getBytes(), -1); mds.commit(); + HashDigest root1 = mds.getRootHash(); // 1个KV项的存储KEY的数量= 1 + 1(保存SN) + Merkle节点数量; // 所以:3 项; @@ -68,6 +69,8 @@ public class MerkleDataSetTest { mds.setValue("B", "B".getBytes(), 0); mds.setValue("C", "C".getBytes(), 0); mds.commit(); + HashDigest root2 = mds.getRootHash(); + assertNotEquals(root1, root2); // Version changed only;仅仅增加 merkle 节点,此时 Merkle 树只有 1 层路径节点,因此只更新2个数据节点和 1 // 个路径节点;(注:版本值是在同一个 key 下按序列保存的); @@ -76,6 +79,9 @@ public class MerkleDataSetTest { mds.setValue("D", "DValue".getBytes(), -1); mds.commit(); + HashDigest root3 = mds.getRootHash(); + assertNotEquals(root2, root3); + assertNotEquals(root1, root3); // New key added, include 1 versioning kv, 1 sn key, 2 merkle nodes; // String[] keys = StringUtils.toStringArray(storage.keySet()); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java index ea20f8b1..f857a6ad 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java @@ -12,6 +12,8 @@ import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.DataAccountRegisterOperation; import com.jd.blockchain.ledger.EndpointRequest; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInitSetting; @@ -23,6 +25,7 @@ import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionResponse; import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.ledger.UserRegisterOperation; +import com.jd.blockchain.ledger.core.DataAccount; import com.jd.blockchain.ledger.core.LedgerDataSet; import com.jd.blockchain.ledger.core.LedgerEditor; import com.jd.blockchain.ledger.core.LedgerRepository; @@ -44,6 +47,7 @@ public class TransactionBatchProcessorTest { DataContractRegistry.register(EndpointRequest.class); DataContractRegistry.register(TransactionResponse.class); DataContractRegistry.register(UserRegisterOperation.class); + DataContractRegistry.register(DataAccountRegisterOperation.class); } private static final String LEDGER_KEY_PREFIX = "LDG://"; @@ -223,7 +227,7 @@ public class TransactionBatchProcessorTest { .get(transactionRequest2.getTransactionContent().getHash()); LedgerTransaction tx3 = ledgerRepo.getTransactionSet() .get(transactionRequest3.getTransactionContent().getHash()); - + assertNotNull(tx1); assertEquals(TransactionState.SUCCESS, tx1.getExecutionState()); assertNotNull(tx2); @@ -240,6 +244,131 @@ public class TransactionBatchProcessorTest { assertTrue(existUser3); } + @Test + public void testTxRollbackByVersionsConfliction() { + final MemoryKVStorage STORAGE = new MemoryKVStorage(); + + // 初始化账本到指定的存储库; + ledgerHash = initLedger(STORAGE, parti0, parti1, parti2, parti3); + + // 加载账本; + LedgerManager ledgerManager = new LedgerManager(); + LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); + + // 验证参与方账户的存在; + LedgerDataSet previousBlockDataset = ledgerRepo.getDataSet(ledgerRepo.getLatestBlock()); + UserAccount user0 = previousBlockDataset.getUserAccountSet().getUser(parti0.getAddress()); + assertNotNull(user0); + boolean partiRegistered = previousBlockDataset.getUserAccountSet().contains(parti0.getAddress()); + assertTrue(partiRegistered); + + // 注册数据账户; + // 生成新区块; + LedgerEditor newBlockEditor = ledgerRepo.createNextBlock(); + + OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration(); + TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(newBlockEditor, previousBlockDataset, + opReg, ledgerManager); + + BlockchainKeypair dataAccountKeypair = BlockchainKeyGenerator.getInstance().generate(); + TransactionRequest transactionRequest1 = LedgerTestUtils.createTxRequest_DataAccountReg(dataAccountKeypair, + ledgerHash, parti0, parti0); + TransactionResponse txResp1 = txbatchProcessor.schedule(transactionRequest1); + LedgerBlock newBlock = newBlockEditor.prepare(); + newBlockEditor.commit(); + + assertEquals(TransactionState.SUCCESS, txResp1.getExecutionState()); + DataAccount dataAccount = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()); + assertNotNull(dataAccount); + + // 正确写入 KV 数据; + TransactionRequest txreq1 = LedgerTestUtils.createTxRequest_DataAccountWrite(dataAccountKeypair.getAddress(), + "K1", "V-1-1", -1, ledgerHash, parti0, parti0); + TransactionRequest txreq2 = LedgerTestUtils.createTxRequest_DataAccountWrite(dataAccountKeypair.getAddress(), + "K2", "V-2-1", -1, ledgerHash, parti0, parti0); + TransactionRequest txreq3 = LedgerTestUtils.createTxRequest_DataAccountWrite(dataAccountKeypair.getAddress(), + "K3", "V-3-1", -1, ledgerHash, parti0, parti0); + TransactionRequest txreq4 = LedgerTestUtils.createTxRequest_DataAccountWrite(dataAccountKeypair.getAddress(), + "K1", "V-1-2", 0, ledgerHash, parti0, parti0); + + newBlockEditor = ledgerRepo.createNextBlock(); + previousBlockDataset = ledgerRepo.getDataSet(ledgerRepo.getLatestBlock()); + txbatchProcessor = new TransactionBatchProcessor(newBlockEditor, previousBlockDataset, opReg, ledgerManager); + + txbatchProcessor.schedule(txreq1); + txbatchProcessor.schedule(txreq2); + txbatchProcessor.schedule(txreq3); + txbatchProcessor.schedule(txreq4); + + newBlock = newBlockEditor.prepare(); + newBlockEditor.commit(); + + BytesValue v1_0 = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getBytes("K1", + 0); + BytesValue v1_1 = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getBytes("K1", + 1); + BytesValue v2 = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getBytes("K2", + 0); + BytesValue v3 = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getBytes("K3", + 0); + + assertNotNull(v1_0); + assertNotNull(v1_1); + assertNotNull(v2); + assertNotNull(v3); + + assertEquals("V-1-1", v1_0.getValue().toUTF8String()); + assertEquals("V-1-2", v1_1.getValue().toUTF8String()); + assertEquals("V-2-1", v2.getValue().toUTF8String()); + assertEquals("V-3-1", v3.getValue().toUTF8String()); + + // 提交多笔数据写入的交易,包含存在数据版本冲突的交易,验证交易是否正确回滚; + + TransactionRequest txreq5 = LedgerTestUtils.createTxRequest_DataAccountWrite(dataAccountKeypair.getAddress(), + "K3", "V-3-2", 0, ledgerHash, parti0, parti0); + // 指定冲突的版本号,正确的应该是版本1; + TransactionRequest txreq6 = LedgerTestUtils.createTxRequest_DataAccountWrite(dataAccountKeypair.getAddress(), + "K1", "V-1-3", 0, ledgerHash, parti0, parti0); + + newBlockEditor = ledgerRepo.createNextBlock(); + previousBlockDataset = ledgerRepo.getDataSet(ledgerRepo.getLatestBlock()); + txbatchProcessor = new TransactionBatchProcessor(newBlockEditor, previousBlockDataset, opReg, ledgerManager); + + txbatchProcessor.schedule(txreq5); + txbatchProcessor.schedule(txreq6); + + newBlock = newBlockEditor.prepare(); + newBlockEditor.commit(); + + BytesValue v1 = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getBytes("K1"); + v3 = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getBytes("K3"); + + long k1_version = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getDataVersion("K1"); + assertEquals(1, k1_version); + long k3_version = ledgerRepo.getDataAccountSet().getDataAccount(dataAccountKeypair.getAddress()).getDataVersion("K3"); + assertEquals(1, k3_version); + + assertNotNull(v1); + assertNotNull(v3); + assertEquals("V-1-2", v1.getValue().toUTF8String()); + assertEquals("V-3-2", v3.getValue().toUTF8String()); + +// // 验证正确性; +// ledgerManager = new LedgerManager(); +// ledgerRepo = ledgerManager.register(ledgerHash, STORAGE); +// +// LedgerBlock latestBlock = ledgerRepo.getLatestBlock(); +// assertEquals(newBlock.getHash(), latestBlock.getHash()); +// assertEquals(1, newBlock.getHeight()); +// +// LedgerTransaction tx1 = ledgerRepo.getTransactionSet() +// .get(transactionRequest1.getTransactionContent().getHash()); +// +// assertNotNull(tx1); +// assertEquals(TransactionState.SUCCESS, tx1.getExecutionState()); + + } + private HashDigest initLedger(MemoryKVStorage storage, BlockchainKeypair... partiKeys) { // 创建初始化配置; LedgerInitSetting initSetting = LedgerTestUtils.createLedgerInitSetting(partiKeys); @@ -269,7 +398,9 @@ public class TransactionBatchProcessorTest { assertNotNull(block.getHash()); assertNull(block.getPreviousHash()); - assertEquals(block.getHash(), block.getLedgerHash()); + // 创世区块的账本哈希为 null; + assertNull(block.getLedgerHash()); + assertNotNull(block.getHash()); // 提交数据,写入存储; ldgEdt.commit(); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockBody.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockBody.java index ff8f3705..7c82b214 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockBody.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockBody.java @@ -20,4 +20,7 @@ public interface BlockBody extends LedgerDataSnapshot{ @DataField(order=5, primitiveType = PrimitiveType.BYTES) HashDigest getTransactionSetHash(); + + @DataField(order=6, primitiveType = PrimitiveType.INT64) + long getTimestamp(); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockRollbackException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockRollbackException.java new file mode 100644 index 00000000..c64f9e42 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockRollbackException.java @@ -0,0 +1,33 @@ +package com.jd.blockchain.ledger; + +public class BlockRollbackException extends LedgerException { + + private static final long serialVersionUID = 3583192000738807503L; + + private TransactionState state; + + public BlockRollbackException(String message) { + this(TransactionState.SYSTEM_ERROR, message); + } + + public BlockRollbackException(TransactionState state, String message) { + super(message); + assert TransactionState.SUCCESS != state; + this.state = state; + } + + public BlockRollbackException(String message, Throwable cause) { + this(TransactionState.SYSTEM_ERROR, message, cause); + } + + public BlockRollbackException(TransactionState state, String message, Throwable cause) { + super(message, cause); + assert TransactionState.SUCCESS != state; + this.state = state; + } + + public TransactionState getState() { + return state; + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/IllegalTransactionException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/IllegalTransactionException.java new file mode 100644 index 00000000..5a2bb5a1 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/IllegalTransactionException.java @@ -0,0 +1,35 @@ +package com.jd.blockchain.ledger; + +public class IllegalTransactionException extends RuntimeException { + + private static final long serialVersionUID = 6348921847690512944L; + + private TransactionState txState; + + public IllegalTransactionException(String message) { + super(message); + this.txState = TransactionState.SYSTEM_ERROR; + } + + public IllegalTransactionException(String message, TransactionState txState) { + super(message); + assert TransactionState.SUCCESS != txState; + this.txState = txState; + } + + public IllegalTransactionException(String message, Throwable cause) { + super(message, cause); + this.txState = TransactionState.SYSTEM_ERROR; + } + + public IllegalTransactionException(String message, Throwable cause, TransactionState txState) { + super(message, cause); + assert TransactionState.SUCCESS != txState; + this.txState = txState; + } + + public TransactionState getTxState() { + return txState; + } + +} 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 5ffa8739..0c227ab5 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 @@ -40,6 +40,6 @@ public interface TransactionContentBody { * @return */ @DataField(order = 3, primitiveType = PrimitiveType.INT64) - long getTime(); + long getTimestamp(); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionException.java deleted file mode 100644 index c88f0792..00000000 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionException.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.jd.blockchain.ledger; - -public class TransactionException extends Exception { - - private static final long serialVersionUID = 3583192000738807503L; - - private TransactionState state; - - public TransactionException(TransactionState state) { - this.state = state; - } - - public TransactionException(TransactionState state, String message) { - super(message); - this.state = state; - } - - public TransactionState getState() { - return state; - } - -} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRollbackException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRollbackException.java new file mode 100644 index 00000000..7694d898 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRollbackException.java @@ -0,0 +1,16 @@ +package com.jd.blockchain.ledger; + +public class TransactionRollbackException extends RuntimeException { + + + private static final long serialVersionUID = -1223140447229570029L; + + public TransactionRollbackException(String message) { + super(message); + } + + public TransactionRollbackException(String message, Throwable cause) { + super(message, cause); + } + +} 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 8483f84d..6955eb94 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 @@ -20,39 +20,58 @@ public enum TransactionState { SUCCESS((byte) 0), /** - * 共识错误; + * 账本错误; */ - CONSENSUS_ERROR((byte) 1), + LEDGER_ERROR((byte) 0x01), /** - * 账本错误; + * 数据账户不存在; + */ + DATA_ACCOUNT_DOES_NOT_EXIST((byte) 0x02), + + /** + * 用户不存在; + */ + USER_DOES_NOT_EXIST((byte) 0x03), + + /** + * 合约不存在; */ - LEDGER_ERROR((byte) 2), + CONTRACT_DOES_NOT_EXIST((byte) 0x04), /** * 由于在错误的账本上执行交易而被丢弃; */ - DISCARD_BY_WRONG_LEDGER((byte) 3), + IGNORED_BY_WRONG_LEDGER((byte) 0x40), /** * 由于交易内容的验签失败而丢弃; */ - DISCARD_BY_WRONG_CONTENT_SIGNATURE((byte) 4), + IGNORED_BY_WRONG_CONTENT_SIGNATURE((byte) 0x41), /** - * 数据账户不存在; + * 由于交易内容的验签失败而丢弃; */ - DATA_ACCOUNT_DOES_NOT_EXIST((byte) 5), - + IGNORED_BY_CONFLICTING_STATE((byte) 0x42), + /** - * 用户不存在; + * 由于交易的整体回滚而丢弃; + *

+ * + * 注: “整体回滚”是指把交易引入的数据更改以及交易记录本身全部都回滚;
+ * “部分回滚”是指把交易引入的数据更改回滚了,但是交易记录本身以及相应的“交易结果({@link TransactionState})”都会提交;
*/ - USER_DOES_NOT_EXIST((byte) 6), - + IGNORED_BY_TX_FULL_ROLLBACK((byte) 0x43), + /** - * 合约不存在; + * 由于区块的整体回滚而丢弃; + *

+ * + * 注: “整体回滚”是指把交易引入的数据更改以及交易记录本身全部都回滚;
+ * + * “部分回滚”是指把交易引入的数据更改回滚了,但是交易记录本身以及相应的“交易结果({@link TransactionState})”都会提交;
*/ - CONTRACT_DOES_NOT_EXIST((byte) 6), + IGNORED_BY_BLOCK_FULL_ROLLBACK((byte) 0x44), /** * 系统错误; @@ -62,7 +81,12 @@ public enum TransactionState { /** * 超时; */ - TIMEOUT((byte) 0x81); + TIMEOUT((byte) 0x81), + + /** + * 共识错误; + */ + CONSENSUS_ERROR((byte) 0x82); @EnumField(type = PrimitiveType.INT8) public final byte CODE; 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 c03f1cc7..7413a5ff 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 @@ -84,7 +84,7 @@ public class TxContentBlob implements TransactionContent { } @Override - public long getTime() { + public long getTimestamp() { return time; } diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java index f9d859ff..711606d3 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java @@ -59,8 +59,8 @@ public interface VersioningKVStorage extends BatchStorageService { /** * Update the value of the key;
* - * If key exist, and the specified version equals to latest , then the value is - * updated and version is increased by 1;
+ * If key exist, and the specified version equals to it's latest version, then the value will be + * updated and version will be increased by 1;
* If key not exist, and the specified version is -1, then the value will be * created and initialized it's version by 0;
* From 53fd891acbe93f0c2a69f9de6fcf6b188ba3dead Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Fri, 5 Jul 2019 12:24:52 +0800 Subject: [PATCH 10/11] Fixed bugs of testcases; --- .../test/com/jd/blockchain/ledger/ContractInvokingTest.java | 3 +-- .../java/test/com/jd/blockchain/ledger/LedgerEditorTest.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java index daffa40b..bec1eee8 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java @@ -204,10 +204,9 @@ public class ContractInvokingTest { assertEquals(0, block.getHeight()); assertNotNull(block.getHash()); + assertNull(block.getLedgerHash()); assertNull(block.getPreviousHash()); - assertEquals(block.getHash(), block.getLedgerHash()); - // 提交数据,写入存储; ldgEdt.commit(); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java index c75b624a..0779204e 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditorTest.java @@ -146,10 +146,9 @@ public class LedgerEditorTest { assertEquals(0, block.getHeight()); assertNotNull(block.getHash()); + assertNull(block.getLedgerHash()); assertNull(block.getPreviousHash()); - assertEquals(block.getHash(), block.getLedgerHash()); - // 提交数据,写入存储; ldgEdt.commit(); From fb771ef65632eee8ae590d65baa38245f90adc1b Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Fri, 5 Jul 2019 18:03:42 +0800 Subject: [PATCH 11/11] Upgraded the version of fastjson lib to avoid security issues; --- source/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/pom.xml b/source/pom.xml index 24589405..fc4c77d9 100644 --- a/source/pom.xml +++ b/source/pom.xml @@ -175,7 +175,7 @@ com.alibaba fastjson - 1.2.32 + 1.2.58