From 5076b5ff7e29a77a1f96f0c0f9299860d541ef04 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Thu, 30 May 2019 00:29:02 +0800 Subject: [PATCH 1/2] Completed marking the data type of the value of KV Entry; --- .../blockchain/binaryproto/PrimitiveType.java | 4 +- .../ledger/core/AccountAccessPolicy.java | 2 +- .../jd/blockchain/ledger/core/AccountSet.java | 26 ++-- .../blockchain/ledger/core/BaseAccount.java | 38 ++--- .../blockchain/ledger/core/DataAccount.java | 19 ++- .../ledger/core/PermissionService.java | 9 ++ .../jd/blockchain/ledger/core/Privilege.java | 11 -- .../ledger/core/PrivilegeModelSetting.java | 2 +- .../ledger/core/impl/OpeningAccessPolicy.java | 2 +- .../impl/handles/ContractLedgerContext.java | 116 ++++++++++---- .../DataAccountKVSetOperationHandle.java | 3 +- .../jd/blockchain/ledger/BaseAccountTest.java | 6 +- .../com/jd/blockchain/ledger/BytesValue.java | 4 +- .../jd/blockchain/ledger/BytesValueEntry.java | 75 ++++++++- .../jd/blockchain/ledger/BytesValueType.java | 5 +- .../jd/blockchain/ledger/KVDataObject.java | 6 +- .../blockchain/ledger}/LedgerException.java | 0 .../ledger/LedgerPermissionException.java | 15 ++ .../jd/blockchain/ledger/PermissionType.java | 68 +++++++++ .../jd/blockchain/ledger/PrivilegeType.java | 42 ----- .../BlockchainOperationFactory.java | 83 +++++++--- .../DataAccountKVSetOperationBuilder.java | 99 +++++++++++- .../DataAccountKVSetOperationBuilderImpl.java | 67 +++++--- .../transaction/DataAccountOperator.java | 6 +- .../PrivilegeSettingOperationBuilder.java | 8 +- .../data/DataAccountKVSetOpTemplateTest.java | 19 ++- .../jd/blockchain/ledger/data/KVDataTest.java | 57 ++++--- .../jd/blockchain/sdk/PrivilegeSetting.java | 4 +- .../intgr/IntegrationTestDataAccount.java | 2 +- .../jd/blockchain/utils/io/BytesUtils.java | 144 +++++++----------- 30 files changed, 600 insertions(+), 342 deletions(-) create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java delete mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Privilege.java rename source/ledger/{ledger-core/src/main/java/com/jd/blockchain/ledger/core => ledger-model/src/main/java/com/jd/blockchain/ledger}/LedgerException.java (100%) create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PermissionType.java delete mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PrivilegeType.java diff --git a/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/PrimitiveType.java b/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/PrimitiveType.java index cf791421..c183d8df 100644 --- a/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/PrimitiveType.java +++ b/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/PrimitiveType.java @@ -30,9 +30,9 @@ public enum PrimitiveType { INT64((byte) (DataType.NUMERIC | 0x04)), /** - * 日期时间; + * 时间戳; */ - DATETIME((byte) (DataType.NUMERIC | 0x08)), + TIMESTAMP((byte) (DataType.NUMERIC | 0x08)), /** * 文本数据; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountAccessPolicy.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountAccessPolicy.java index 2a0202c4..2e025bf2 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountAccessPolicy.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountAccessPolicy.java @@ -19,7 +19,7 @@ public interface AccountAccessPolicy { * @param account * @return Return true if it satisfies this policy, or false if it doesn't; */ - boolean checkCommitting(AccountHeader account); + boolean checkDataWriting(AccountHeader account); boolean checkRegistering(Bytes address, PubKey pubKey); 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 19b195f1..b9ee4324 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 @@ -160,10 +160,8 @@ public class AccountSet implements Transactional, MerkleProvable { * * 只有最新版本的账户才能可写的,其它都是只读; * - * @param address - * 账户地址; - * @param version - * 账户版本;如果指定为 -1,则返回最新版本; + * @param address 账户地址; + * @param version 账户版本;如果指定为 -1,则返回最新版本; * @return */ public BaseAccount getAccount(Bytes address, long version) { @@ -226,10 +224,8 @@ public class AccountSet implements Transactional, MerkleProvable { * * 如果指定的地址和公钥不匹配,则会引发 {@link LedgerException} 异常; * - * @param address - * 区块链地址; - * @param pubKey - * 公钥; + * @param address 区块链地址; + * @param pubKey 公钥; * @return 注册成功的账户对象; */ public BaseAccount register(Bytes address, PubKey pubKey) { @@ -283,15 +279,14 @@ public class AccountSet implements Transactional, MerkleProvable { private VersioningAccount createInstance(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { - return new VersioningAccount(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage, accessPolicy, - version); + return new VersioningAccount(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage, version); } private VersioningAccount deserialize(byte[] bytes, CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, long version) { AccountHeader accInfo = BinaryProtocol.decode(bytes); return new VersioningAccount(accInfo.getAddress(), accInfo.getPubKey(), accInfo.getRootHash(), cryptoSetting, - keyPrefix, exStorage, verStorage, readonly, accessPolicy, version); + keyPrefix, exStorage, verStorage, readonly, version); } private byte[] serialize(AccountHeader account) { @@ -388,15 +383,14 @@ public class AccountSet implements Transactional, MerkleProvable { public VersioningAccount(Bytes address, PubKey pubKey, HashDigest rootHash, CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, - AccountAccessPolicy accessPolicy, long version) { - super(address, pubKey, rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly, accessPolicy); + long version) { + super(address, pubKey, rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); this.version = version; } public VersioningAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy, - long version) { - super(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage, accessPolicy); + ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { + super(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage); this.version = version; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java index 6af10149..501f64c3 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java @@ -23,8 +23,6 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional protected MerkleDataSet dataset; - private AccountAccessPolicy accessPolicy; - /** * Create a new Account with the specified address and pubkey;
* @@ -38,8 +36,8 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * @param pubKey */ public BaseAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { - this(address, pubKey, null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy); + ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { + this(address, pubKey, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); } /** @@ -58,8 +56,8 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * @param accessPolicy */ public BaseAccount(BlockchainIdentity bcid, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { - this(bcid, null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy); + ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { + this(bcid, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); } /** @@ -69,9 +67,8 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * * @param address * @param pubKey - * @param dataRootHash - * merkle root hash of account's data; if null be set, create a new - * empty merkle dataset; + * @param dataRootHash merkle root hash of account's data; if null be set, + * create a new empty merkle dataset; * @param cryptoSetting * @param exStorage * @param verStorage @@ -79,18 +76,15 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * @param accessPolicy */ public BaseAccount(Bytes address, PubKey pubKey, HashDigest dataRootHash, CryptoSetting cryptoSetting, - String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, - AccountAccessPolicy accessPolicy) { + String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { this(new BlockchainIdentityData(address, pubKey), dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, - readonly, accessPolicy); + readonly); } public BaseAccount(BlockchainIdentity bcid, HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, - AccountAccessPolicy accessPolicy) { + ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { this.bcid = bcid; this.dataset = new MerkleDataSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); - this.accessPolicy = accessPolicy; } /* @@ -151,12 +145,9 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * If updating is performed, the version of the key increase by 1.
* If creating is performed, the version of the key initialize by 0.
* - * @param key - * The key of data; - * @param value - * The value of data; - * @param version - * The expected version of the key. + * @param key The key of data; + * @param value The value of data; + * @param version The expected version of the key. * @return The new version of the key.
* If the key is new created success, then return 0;
* If the key is updated success, then return the new version;
@@ -164,7 +155,6 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * return -1; */ public long setBytes(Bytes key, byte[] value, long version) { - // TODO: 支持多种数据类型; return dataset.setValue(key, value, version); } @@ -207,10 +197,6 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional @Override public void commit() { - if (!accessPolicy.checkCommitting(this)) { - throw new LedgerException("Account Committing was rejected for the access policy!"); - } - dataset.commit(); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java index 0655cb24..08b5c23a 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java @@ -6,10 +6,10 @@ import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.AccountHeader; import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.BytesValueEntry; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.KVDataObject; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.serialize.binary.BinarySerializeUtils; public class DataAccount implements AccountHeader, MerkleProvable { @@ -41,9 +41,22 @@ public class DataAccount implements AccountHeader, MerkleProvable { public MerkleProof getProof(Bytes key) { return baseAccount.getProof(key); } + + + public long setBytes(Bytes key, BytesValue value, long version) { + byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); + return baseAccount.setBytes(key, bytesValue, version); + } + + + public long setBytes(Bytes key, String value, long version) { + BytesValue bv = BytesValueEntry.fromText(value); + return setBytes(key, bv, version); + } public long setBytes(Bytes key, byte[] value, long version) { - return baseAccount.setBytes(key, value, version); + BytesValue bv = BytesValueEntry.fromBytes(value); + return setBytes(key, bv, version); } /** @@ -119,7 +132,6 @@ public class DataAccount implements AccountHeader, MerkleProvable { */ public KVDataEntry[] getDataEntries(int fromIndex, int count) { - if (getDataEntriesTotalCount() == 0 || count == 0) { return null; } @@ -162,5 +174,4 @@ public class DataAccount implements AccountHeader, MerkleProvable { } return baseAccount.dataset.getDataCount(); } - } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java new file mode 100644 index 00000000..b3b9a7c2 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PermissionService.java @@ -0,0 +1,9 @@ +package com.jd.blockchain.ledger.core; + +import java.util.SortedSet; + +public interface PermissionService { + + boolean checkLedgerPermission(); + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Privilege.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Privilege.java deleted file mode 100644 index d5a71455..00000000 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Privilege.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.jd.blockchain.ledger.core; - -import java.util.SortedSet; - -public interface Privilege { - - SortedSet getOpCodes(); - - long getVersion(); - -} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeModelSetting.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeModelSetting.java index d5017e83..1687c989 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeModelSetting.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeModelSetting.java @@ -4,6 +4,6 @@ public interface PrivilegeModelSetting { long getLatestVersion(); - Privilege getPrivilege(long version); + PermissionService getPrivilege(long version); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/OpeningAccessPolicy.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/OpeningAccessPolicy.java index 3af84a5a..14c5b9b4 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/OpeningAccessPolicy.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/OpeningAccessPolicy.java @@ -16,7 +16,7 @@ import com.jd.blockchain.utils.Bytes; public class OpeningAccessPolicy implements AccountAccessPolicy { @Override - public boolean checkCommitting(AccountHeader account) { + public boolean checkDataWriting(AccountHeader account) { return true; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java index 43595152..c631f044 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java @@ -3,10 +3,25 @@ package com.jd.blockchain.ledger.core.impl.handles; import java.util.ArrayList; import java.util.List; -import com.alibaba.fastjson.JSON; import com.jd.blockchain.contract.LedgerContext; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.*; +import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.BytesValueEntry; +import com.jd.blockchain.ledger.DataAccountKVSetOperation; +import com.jd.blockchain.ledger.DataAccountRegisterOperation; +import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.KVInfoVO; +import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerInfo; +import com.jd.blockchain.ledger.LedgerMetadata; +import com.jd.blockchain.ledger.LedgerTransaction; +import com.jd.blockchain.ledger.Operation; +import com.jd.blockchain.ledger.ParticipantNode; +import com.jd.blockchain.ledger.TransactionState; +import com.jd.blockchain.ledger.UserInfo; +import com.jd.blockchain.ledger.UserRegisterOperation; import com.jd.blockchain.ledger.core.impl.OperationHandleContext; import com.jd.blockchain.transaction.BlockchainQueryService; import com.jd.blockchain.transaction.DataAccountKVSetOperationBuilder; @@ -16,7 +31,6 @@ import com.jd.blockchain.transaction.KVData; import com.jd.blockchain.transaction.UserRegisterOperationBuilder; import com.jd.blockchain.transaction.UserRegisterOperationBuilderImpl; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; public class ContractLedgerContext implements LedgerContext { @@ -250,17 +264,6 @@ public class ContractLedgerContext implements LedgerContext { this.accountAddress = accountAddress; } - public boolean isJson(String str) { - boolean result = false; - try { - Object obj=JSON.parse(str); - result = true; - } catch (Exception e) { - result=false; - } - return result; - } - @Override public DataAccountKVSetOperation getOperation() { return op; @@ -268,41 +271,88 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { - BytesValue bytesValue = new BytesValueEntry(BytesValueType.BYTES, value); + BytesValue bytesValue = BytesValueEntry.fromBytes(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); - generatedOpList.add(op); - opHandleContext.handle(op); + handle(op); return this; } + + @Override + public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromText(value); + this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); + handle(op); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromBytes(value); + this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); + handle(op); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromInt64(value); + this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); + handle(op); + return this; + } + + @Deprecated @Override public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { - BytesValue bytesValue; - if (isJson(value)) { - bytesValue = new BytesValueEntry(BytesValueType.JSON, value.getBytes()); - } - else { - bytesValue = new BytesValueEntry(BytesValueType.TEXT, value.getBytes()); - } + BytesValue bytesValue = BytesValueEntry.fromText(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); - generatedOpList.add(op); - opHandleContext.handle(op); + handle(op); return this; } + @Override - public DataAccountKVSetOperationBuilder set(String key, Bytes value, long expVersion) { - BytesValue bytesValue = new BytesValueEntry(BytesValueType.BYTES, value.toBytes()); + public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromJSON(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); - generatedOpList.add(op); - opHandleContext.handle(op); + handle(op); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromXML(value); + this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); + handle(op); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromBytes(value); + this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); + handle(op); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromImage(value); + this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); + handle(op); return this; } + @Override - public DataAccountKVSetOperationBuilder set(String key, long value, long expVersion) { - BytesValue bytesValue = new BytesValueEntry(BytesValueType.INT64, BytesUtils.toBytes(value)); + public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromTimestamp(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); + handle(op); + return this; + } + + private void handle(Operation op) { generatedOpList.add(op); opHandleContext.handle(op); - return this; } /** 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 2d7735d4..4331c29c 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 @@ -24,8 +24,7 @@ public class DataAccountKVSetOperationHandle implements OperationHandle{ DataAccount account = dataset.getDataAccountSet().getDataAccount(kvWriteOp.getAccountAddress()); KVWriteEntry[] writeset = kvWriteOp.getWriteSet(); for (KVWriteEntry kvw : writeset) { - byte[] value = BinaryProtocol.encode(kvw.getValue(), BytesValue.class); - account.setBytes(Bytes.fromString(kvw.getKey()), value, kvw.getExpectedVersion()); + account.setBytes(Bytes.fromString(kvw.getKey()), kvw.getValue(), kvw.getExpectedVersion()); } } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java index 23b3445a..644b2863 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java @@ -14,7 +14,6 @@ import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.core.BaseAccount; import com.jd.blockchain.ledger.core.CryptoConfig; -import com.jd.blockchain.ledger.core.impl.OpeningAccessPolicy; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.io.BytesUtils; @@ -44,13 +43,12 @@ public class BaseAccountTest { cryptoConf.setAutoVerifyHash(true); cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); - OpeningAccessPolicy accPlc = new OpeningAccessPolicy(); +// OpeningAccessPolicy accPlc = new OpeningAccessPolicy(); BlockchainKeypair bck = BlockchainKeyGenerator.getInstance().generate(); // 新建账户; - BaseAccount baseAccount = new BaseAccount(bck.getIdentity(), cryptoConf, keyPrefix, testStorage, testStorage, - accPlc); + BaseAccount baseAccount = new BaseAccount(bck.getIdentity(), cryptoConf, keyPrefix, testStorage, testStorage); assertFalse(baseAccount.isUpdated());// 空的账户; assertFalse(baseAccount.isReadonly()); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValue.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValue.java index 864484f3..ae340106 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValue.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValue.java @@ -4,7 +4,7 @@ import com.jd.blockchain.binaryproto.DataContract; import com.jd.blockchain.binaryproto.DataField; import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.consts.DataCodes; -import com.jd.blockchain.utils.io.BytesSlice; +import com.jd.blockchain.utils.Bytes; /** * BytesValue is the base structure of Value in Blockchain Account; @@ -29,6 +29,6 @@ public interface BytesValue { * @return */ @DataField(order = 1, primitiveType = PrimitiveType.BYTES) - BytesSlice getValue(); + Bytes getValue(); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java index 753f5f3d..b5ce137b 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java @@ -1,18 +1,79 @@ package com.jd.blockchain.ledger; -import com.jd.blockchain.utils.io.BytesSlice; +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.io.BytesUtils; /** - * Created by zhangshuang3 on 2018/12/3. + * + * @author huanghaiquan + * */ public class BytesValueEntry implements BytesValue{ BytesValueType type; - BytesSlice slice; + Bytes value; - public BytesValueEntry(BytesValueType type, byte[] bytes) { + private BytesValueEntry(BytesValueType type, byte[] bytes) { this.type = type; - this.slice = new BytesSlice(bytes); + this.value = new Bytes(bytes); } + + private BytesValueEntry(BytesValueType type, Bytes bytes) { + this.type = type; + this.value = bytes; + } + + public static BytesValue fromBytes(byte[] value) { + return new BytesValueEntry(BytesValueType.BYTES, value); + } + + public static BytesValue fromBytes(Bytes value) { + return new BytesValueEntry(BytesValueType.BYTES, value); + } + + public static BytesValue fromImage(byte[] value) { + return new BytesValueEntry(BytesValueType.IMG, value); + } + + public static BytesValue fromImage(Bytes value) { + return new BytesValueEntry(BytesValueType.IMG, value); + } + + public static BytesValue fromText(String value) { + return new BytesValueEntry(BytesValueType.TEXT, BytesUtils.toBytes(value)); + } + + public static BytesValue fromJSON(String value) { + return new BytesValueEntry(BytesValueType.JSON, BytesUtils.toBytes(value)); + } + + public static BytesValue fromXML(String value) { + return new BytesValueEntry(BytesValueType.XML, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt32(int value) { + return new BytesValueEntry(BytesValueType.INT32, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt64(long value) { + return new BytesValueEntry(BytesValueType.INT64, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt16(short value) { + return new BytesValueEntry(BytesValueType.INT16, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt8(byte value) { + return new BytesValueEntry(BytesValueType.INT8, BytesUtils.toBytes(value)); + } + + public static BytesValue fromTimestamp(long value) { + return new BytesValueEntry(BytesValueType.TIMESTAMP, BytesUtils.toBytes(value)); + } + + public static BytesValue fromBoolean(boolean value) { + return new BytesValueEntry(BytesValueType.BOOLEAN, BytesUtils.toBytes(value)); + } + @Override public BytesValueType getType() { @@ -24,8 +85,8 @@ public class BytesValueEntry implements BytesValue{ } @Override - public BytesSlice getValue() { - return this.slice; + public Bytes getValue() { + return this.value; } } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueType.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueType.java index 306b2b89..11049ea9 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueType.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueType.java @@ -37,9 +37,9 @@ public enum BytesValueType { INT64(PrimitiveType.INT64.CODE), /** - * 日期时间; + * 时间戳; */ - DATETIME(PrimitiveType.DATETIME.CODE), + TIMESTAMP(PrimitiveType.TIMESTAMP.CODE), /** * 文本数据; @@ -81,7 +81,6 @@ public enum BytesValueType { */ LOCATION(PrimitiveType.LOCATION.CODE); - @EnumField(type = PrimitiveType.INT8) public final byte CODE; diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java index 26467e85..b39d9a1c 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java @@ -228,7 +228,7 @@ public class KVDataObject implements KVDataEntry { * 返回日期时间值; *

* - * 仅当数据类型 {@link #getType()} 为 {@link PrimitiveType#DATETIME} 有效; + * 仅当数据类型 {@link #getType()} 为 {@link PrimitiveType#TIMESTAMP} 有效; *

* * 无效类型将引发 {@link IllegalStateException} 异常; @@ -236,11 +236,11 @@ public class KVDataObject implements KVDataEntry { * @return */ public Date datetimeValue() { - if (PrimitiveType.DATETIME == type) { + if (PrimitiveType.TIMESTAMP == type) { long ts = BytesUtils.toLong(bytesValue); return new Date(ts); } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.DATETIME, type)); + throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.TIMESTAMP, type)); } /** diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerException.java similarity index 100% rename from source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerException.java rename to source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerException.java diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java new file mode 100644 index 00000000..6c1a3b5c --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java @@ -0,0 +1,15 @@ +package com.jd.blockchain.ledger.core; + +public class LedgerPermissionException extends LedgerException { + + private static final long serialVersionUID = 6077975401474519117L; + + public LedgerPermissionException(String message) { + super(message); + } + + public LedgerPermissionException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PermissionType.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PermissionType.java new file mode 100644 index 00000000..3f6a4634 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PermissionType.java @@ -0,0 +1,68 @@ +package com.jd.blockchain.ledger; + +/** + * 权限类型; + * + * @author huanghaiquan + * + */ +public enum PermissionType { + + /** + * 账户权限配置; + */ + SET_PRIVILEGE(1), + + /** + * 注册参与方; + */ + REG_PARTICIPANT(2), + + /** + * 配置账本;包括除了{@link #SET_PRIVILEGE}、 {@link #REG_PARTICIPANT} 之外的其它账本设置,例如:设置密码参数、共识参数等; + */ + CONFIG_LEDGER(4), + + /** + * 用户注册; + */ + REG_USER(8), + + /** + * 注册数据账户; + */ + REG_DATA_ACCOUNT(16), + + /** + * 部署新的合约代码; + */ + DEPLOY_CONTRACT(32), + + /** + * 写入用户信息; + */ + SET_USER(1024), + + /** + * 写入数据; + */ + SET_DATA(2048), + + /** + * 写入数据; + */ + INVOKE_CONTRACT(4096), + + /** + * 升级合约代码; + */ + UPDATE_CONTRACT(8192); + + + public final int CODE; + + private PermissionType(int code) { + this.CODE = code; + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PrivilegeType.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PrivilegeType.java deleted file mode 100644 index 63e1383d..00000000 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PrivilegeType.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jd.blockchain.ledger; - -/** - * 权限类型; - * - * @author huanghaiquan - * - */ -public enum PrivilegeType { - - /** - * 账户注册; - */ - ACCOUNT_REGISTER(1), - - /** - * 账户权限配置; - */ - PRIVILEGE_CONFIG(2), - - /** - * 状态数据写入; - */ - STATE_WRITE(4), - - /** - * 合约应用部署; - */ - CONTRACT_APP_DEPLOY(8), - - /** - * 合约应用调用; - */ - CONTRACT_APP_INVOKE(16); - - public final int CODE; - - private PrivilegeType(int code) { - this.CODE = code; - } - -} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java index bd1bfd5b..107bcbf7 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java @@ -31,7 +31,6 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe private static final ContractEventSendOperationBuilderImpl CONTRACT_EVENT_SEND_OP_BUILDER = new ContractEventSendOperationBuilderImpl(); - private LedgerInitOperationBuilder ledgerInitOpBuilder = new LedgerInitOperationBuilderFilter(); private UserRegisterOperationBuilder userRegOpBuilder = new UserRegisterOperationBuilderFilter(); @@ -78,7 +77,7 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe public ContractEventSendOperationBuilder contractEvents() { return contractEventSendOpBuilder; } - + @Override public T contract(String address, Class contractIntf) { // TODO Auto-generated method stub @@ -144,40 +143,80 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe return innerBuilder.getOperation(); } - @Override - public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { - innerBuilder.set(key, value, expVersion); + private void addOperation() { if (op == null) { op = innerBuilder.getOperation(); operationList.add(op); } + } + + @Override + public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { + innerBuilder.set(key, value, expVersion); + addOperation(); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { + innerBuilder.setText(key, value, expVersion); + addOperation(); return this; } + + @Override + public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) { + innerBuilder.setInt64(key, value, expVersion); + addOperation(); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) { + innerBuilder.setBytes(key, value, expVersion); + addOperation(); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { + innerBuilder.setBytes(key, value, expVersion); + addOperation(); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) { + innerBuilder.setImage(key, value, expVersion); + addOperation(); + return this; + } + @Override public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { - innerBuilder.set(key, value, expVersion); - if (op == null) { - op = innerBuilder.getOperation(); - operationList.add(op); - } + innerBuilder.setText(key, value, expVersion); + addOperation(); return this; } + @Override - public DataAccountKVSetOperationBuilder set(String key, long value, long expVersion) { - innerBuilder.set(key, value, expVersion); - if (op == null) { - op = innerBuilder.getOperation(); - operationList.add(op); - } + public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { + innerBuilder.setJSON(key, value, expVersion); + addOperation(); return this; } + @Override - public DataAccountKVSetOperationBuilder set(String key, Bytes value, long expVersion) { - innerBuilder.set(key, value, expVersion); - if (op == null) { - op = innerBuilder.getOperation(); - operationList.add(op); - } + public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) { + innerBuilder.setXML(key, value, expVersion); + addOperation(); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) { + innerBuilder.setTimestamp(key, value, expVersion); + addOperation(); return this; } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java index 4e0a903c..11971efc 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java @@ -3,6 +3,10 @@ package com.jd.blockchain.transaction; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.utils.Bytes; +/** + * @author huanghaiquan + * + */ public interface DataAccountKVSetOperationBuilder { /** @@ -13,7 +17,7 @@ public interface DataAccountKVSetOperationBuilder { DataAccountKVSetOperation getOperation(); /** - * 写入键值; + * 写入字节数组; * * @param key * 键; @@ -23,7 +27,35 @@ public interface DataAccountKVSetOperationBuilder { * 预期的当前版本;如果版本不匹配,则写入失败; * @return */ + @Deprecated DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion); + + /** + * 写入字节数组; + * + * @param key + * 键; + * @param value + * 值;byte[]格式 + * @param expVersion + * 预期的当前版本;如果版本不匹配,则写入失败; + * @return + */ + DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion); + + /** + * 写入字节数组; + * + * @param key + * 键; + * @param value + * 值;Bytes格式 + * @param expVersion + * 预期的当前版本;如果版本不匹配,则写入失败; + * @return + */ + DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion); + /** * 写入键值; * @@ -35,21 +67,76 @@ public interface DataAccountKVSetOperationBuilder { * 预期的当前版本;如果版本不匹配,则写入失败; * @return */ + DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion); + + /** + * 写入文本键值; + * + * @param key + * 键; + * @param value + * 值;String格式 + * @param expVersion + * 预期的当前版本;如果版本不匹配,则写入失败; + * @return + */ + @Deprecated DataAccountKVSetOperationBuilder set(String key, String value, long expVersion); + /** - * 写入键值; + * 写入文本键值; * * @param key * 键; * @param value - * 值;Bytes格式 + * 值;String格式 * @param expVersion * 预期的当前版本;如果版本不匹配,则写入失败; * @return */ - DataAccountKVSetOperationBuilder set(String key, Bytes value, long expVersion); + DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion); + /** - * 写入键值; + * 写入JSON键值; + * + * @param key + * 键; + * @param value + * 值;String格式 + * @param expVersion + * 预期的当前版本;如果版本不匹配,则写入失败; + * @return + */ + DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion); + + /** + * 写入XML键值; + * + * @param key + * 键; + * @param value + * 值;String格式 + * @param expVersion + * 预期的当前版本;如果版本不匹配,则写入失败; + * @return + */ + DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion); + + /** + * 写入64位整数; + * + * @param key + * 键; + * @param value + * 值;long格式 + * @param expVersion + * 预期的当前版本;如果版本不匹配,则写入失败; + * @return + */ + DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion); + + /** + * 写入时间戳; * * @param key * 键; @@ -59,6 +146,6 @@ public interface DataAccountKVSetOperationBuilder { * 预期的当前版本;如果版本不匹配,则写入失败; * @return */ - DataAccountKVSetOperationBuilder set(String key, long value, long expVersion); + DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java index c0511e55..ce056eb4 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java @@ -3,15 +3,12 @@ package com.jd.blockchain.transaction; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.BytesValueEntry; import com.jd.blockchain.ledger.DataAccountKVSetOperation; -import com.jd.blockchain.ledger.BytesValueType; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; -import com.jd.blockchain.utils.serialize.json.JSONSerializeUtils; -public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOperationBuilder{ - +public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOperationBuilder { + private DataAccountKVSetOpTemplate operation; - + public DataAccountKVSetOperationBuilderImpl(Bytes accountAddress) { operation = new DataAccountKVSetOpTemplate(accountAddress); } @@ -21,35 +18,69 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe return operation; } + @Deprecated @Override public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { - BytesValue bytesValue = new BytesValueEntry(BytesValueType.BYTES, value); + return setBytes(key, value, expVersion); + } + + @Override + public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromBytes(value); + operation.set(key, bytesValue, expVersion); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromImage(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { - BytesValue bytesValue; - if (JSONSerializeUtils.isJSON(value)) { - bytesValue = new BytesValueEntry(BytesValueType.JSON, value.getBytes()); - } - else { - bytesValue = new BytesValueEntry(BytesValueType.TEXT, value.getBytes()); - } + return setText(key, value, expVersion); + } + + @Override + public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromText(value); operation.set(key, bytesValue, expVersion); return this; } @Override - public DataAccountKVSetOperationBuilder set(String key, Bytes value, long expVersion) { - BytesValue bytesValue = new BytesValueEntry(BytesValueType.BYTES, value.toBytes()); + public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromBytes(value); operation.set(key, bytesValue, expVersion); return this; } + + @Override + public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromInt64(value); + operation.set(key, bytesValue, expVersion); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromJSON(value); + operation.set(key, bytesValue, expVersion); + return this; + } + + @Override + public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromXML(value); + operation.set(key, bytesValue, expVersion); + return this; + } + @Override - public DataAccountKVSetOperationBuilder set(String key, long value, long expVersion) { - BytesValue bytesValue = new BytesValueEntry(BytesValueType.INT64, BytesUtils.toBytes(value)); + public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) { + BytesValue bytesValue = BytesValueEntry.fromTimestamp(value); operation.set(key, bytesValue, expVersion); return this; } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountOperator.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountOperator.java index 7964e7ef..89ea895e 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountOperator.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountOperator.java @@ -13,14 +13,16 @@ public interface DataAccountOperator { DataAccountRegisterOperationBuilder dataAccounts(); /** - * 写入数据; + * 写入数据;
+ * * @param accountAddress * @return */ DataAccountKVSetOperationBuilder dataAccount(String accountAddress); - + /** * 写入数据; + * * @param accountAddress * @return */ diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PrivilegeSettingOperationBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PrivilegeSettingOperationBuilder.java index f2cbab74..f10d77e1 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PrivilegeSettingOperationBuilder.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PrivilegeSettingOperationBuilder.java @@ -1,6 +1,6 @@ package com.jd.blockchain.transaction; -import com.jd.blockchain.ledger.PrivilegeType; +import com.jd.blockchain.ledger.PermissionType; /** * 账户权限设置操作; @@ -16,10 +16,10 @@ import com.jd.blockchain.ledger.PrivilegeType; */ public interface PrivilegeSettingOperationBuilder { - PrivilegeSettingOperationBuilder setThreshhold(PrivilegeType privilege, long threshhold); + PrivilegeSettingOperationBuilder setThreshhold(PermissionType privilege, long threshhold); - PrivilegeSettingOperationBuilder enable(PrivilegeType privilege, String address, int weight); + PrivilegeSettingOperationBuilder enable(PermissionType privilege, String address, int weight); - PrivilegeSettingOperationBuilder disable(PrivilegeType privilege, String address); + PrivilegeSettingOperationBuilder disable(PermissionType privilege, String address); } diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java index c5ccd7f6..005af7c6 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java @@ -8,22 +8,21 @@ */ package test.com.jd.blockchain.ledger.data; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.ledger.BytesValueEntry; import com.jd.blockchain.ledger.DataAccountKVSetOperation; -import com.jd.blockchain.ledger.BytesValueType; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; import com.jd.blockchain.transaction.KVData; import com.jd.blockchain.utils.Bytes; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - /** * * @author shaozhuguang @@ -43,11 +42,11 @@ public class DataAccountKVSetOpTemplateTest { String accountAddress = "zhangsandhakhdkah"; data = new DataAccountKVSetOpTemplate(Bytes.fromString(accountAddress)); KVData kvData1 = - new KVData("test1", new BytesValueEntry(BytesValueType.TEXT, "zhangsan".getBytes()), 9999L); + new KVData("test1", BytesValueEntry.fromText("zhangsan"), 9999L); KVData kvData2 = - new KVData("test2", new BytesValueEntry(BytesValueType.TEXT, "lisi".getBytes()), 9990L); + new KVData("test2", BytesValueEntry.fromText("lisi"), 9990L); KVData kvData3 = - new KVData("test3", new BytesValueEntry(BytesValueType.TEXT, "wangwu".getBytes()), 1990L); + new KVData("test3", BytesValueEntry.fromText("wangwu"), 1990L); data.set(kvData1); data.set(kvData2); data.set(kvData3); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/KVDataTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/KVDataTest.java index 86314a6f..39824505 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/KVDataTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/KVDataTest.java @@ -8,20 +8,19 @@ */ package test.com.jd.blockchain.ledger.data; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.ledger.BytesValueEntry; import com.jd.blockchain.ledger.DataAccountKVSetOperation; -import com.jd.blockchain.ledger.BytesValueType; import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; import com.jd.blockchain.transaction.KVData; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - /** * * @author shaozhuguang @@ -30,26 +29,26 @@ import static org.junit.Assert.assertEquals; */ public class KVDataTest { - private KVData kvData; - - @Before - public void initKVData() throws Exception { - DataContractRegistry.register(DataAccountKVSetOperation.KVWriteEntry.class); - String key = "test-key"; - byte[] value = "test-value".getBytes(); - long expectedVersion = 9999L; - - kvData = new KVData(key, new BytesValueEntry(BytesValueType.BYTES, value), expectedVersion); - } - - @Test - public void testSerialize_KVEntry() throws Exception { - byte[] serialBytes = BinaryProtocol.encode(kvData, DataAccountKVSetOperation.KVWriteEntry.class); - DataAccountKVSetOpTemplate.KVWriteEntry resolvedKvData = BinaryProtocol.decode(serialBytes); - System.out.println("------Assert start ------"); - assertEquals(resolvedKvData.getKey(), kvData.getKey()); - assertEquals(resolvedKvData.getExpectedVersion(), kvData.getExpectedVersion()); - assertArrayEquals(resolvedKvData.getValue().getValue().toBytes(), kvData.getValue().getValue().toBytes()); - System.out.println("------Assert OK ------"); - } + private KVData kvData; + + @Before + public void initKVData() throws Exception { + DataContractRegistry.register(DataAccountKVSetOperation.KVWriteEntry.class); + String key = "test-key"; + byte[] value = "test-value".getBytes(); + long expectedVersion = 9999L; + + kvData = new KVData(key, BytesValueEntry.fromBytes(value), expectedVersion); + } + + @Test + public void testSerialize_KVEntry() throws Exception { + byte[] serialBytes = BinaryProtocol.encode(kvData, DataAccountKVSetOperation.KVWriteEntry.class); + DataAccountKVSetOpTemplate.KVWriteEntry resolvedKvData = BinaryProtocol.decode(serialBytes); + System.out.println("------Assert start ------"); + assertEquals(resolvedKvData.getKey(), kvData.getKey()); + assertEquals(resolvedKvData.getExpectedVersion(), kvData.getExpectedVersion()); + assertArrayEquals(resolvedKvData.getValue().getValue().toBytes(), kvData.getValue().getValue().toBytes()); + System.out.println("------Assert OK ------"); + } } \ No newline at end of file diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/PrivilegeSetting.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/PrivilegeSetting.java index c78ee579..deafc113 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/PrivilegeSetting.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/PrivilegeSetting.java @@ -1,6 +1,6 @@ package com.jd.blockchain.sdk; -import com.jd.blockchain.ledger.PrivilegeType; +import com.jd.blockchain.ledger.PermissionType; /** * 权限设置;
@@ -16,6 +16,6 @@ public interface PrivilegeSetting { long getMask(String address); - boolean isEnable(String address, PrivilegeType privilege); + boolean isEnable(String address, PermissionType privilege); } diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java index 5b1b5457..e7bf18c5 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java @@ -197,7 +197,7 @@ public class IntegrationTestDataAccount { // // //add kv ops for data account: Bytes, string, long, json string DataAccountKVSetOperation dataKvsetOP = txTpl.dataAccount(dataAddr).set("A", "Value_A_0".getBytes(), -1) - .set("B", "Value_B_0", -1).set("C", currentTime, -1).set("D", JSON.toJSONString(jsonTest), -1) + .setText("B", "Value_B_0", -1).setInt64("C", currentTime, -1).setText("D", JSON.toJSONString(jsonTest), -1) .getOperation(); // 签名; 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 62d152bd..c6b0bccf 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 @@ -19,6 +19,10 @@ public class BytesUtils { public static final int MAX_BUFFER_SIZE = 1024 * 1024 * 1024; public static final int BUFFER_SIZE = 64; + public static final byte TRUE_BYTE = 1; + + public static final byte FALSE_BYTE = 0; + private BytesUtils() { } @@ -28,10 +32,8 @@ public class BytesUtils { * * 此方法不处理两者其中之一为 null 的情形,因为无法定义相等性,所以将引发 {@link NullPointerException} 异常; * - * @param bytes1 - * bytes1 - * @param bytes2 - * bytes2 + * @param bytes1 bytes1 + * @param bytes2 bytes2 * @return boolean */ public static boolean equals(byte[] bytes1, byte[] bytes2) { @@ -64,8 +66,7 @@ public class BytesUtils { * 将输入流的所有内容都读入到字节数组返回; 如果输入流的长度超出 MAX_BUFFER_SIZE 定义的值,则抛出 * IllegalArgumentException ; * - * @param in - * in + * @param in in * @return byte[] */ public static byte[] copyToBytes(InputStream in) { @@ -95,15 +96,11 @@ public class BytesUtils { /** * 将输入流复制到输出流; * - * @param in - * 输入流; - * @param out - * 输出流; - * @param maxSize - * 最大字节大小; + * @param in 输入流; + * @param out 输出流; + * @param maxSize 最大字节大小; * @return 返回实际复制的字节数; - * @throws IOException - * exception + * @throws IOException exception */ public static int copy(InputStream in, OutputStream out, int maxSize) throws IOException { byte[] buffer = new byte[BUFFER_SIZE]; @@ -126,8 +123,7 @@ public class BytesUtils { /** * 将 int 值转为4字节的二进制数组; * - * @param value - * value + * @param value value * @return 转换后的二进制数组,高位在前,低位在后; */ public static byte[] toBytes(int value) { @@ -142,11 +138,14 @@ public class BytesUtils { return bytes; } + public static byte[] toBytes(boolean value) { + return new byte[] { value ? TRUE_BYTE : FALSE_BYTE }; + } + /** * 将 long 值转为8字节的二进制数组; * - * @param value - * value + * @param value value * @return 转换后的二进制数组,高位在前,低位在后; */ public static byte[] toBytes(long value) { @@ -158,10 +157,8 @@ public class BytesUtils { /** * 将 int 值转为4字节的二进制数组; * - * @param value - * 要转换的int整数; - * @param bytes - * 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 0 开始的4个元素; + * @param value 要转换的int整数; + * @param bytes 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 0 开始的4个元素; */ public static void toBytes(short value, byte[] bytes) { toBytes(value, bytes, 0); @@ -176,12 +173,9 @@ public class BytesUtils { *

* 以“高位在前”的方式转换,即:数值的高位保存在数组地址的低位; * - * @param value - * 要转换的int整数; - * @param bytes - * 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的4个元素; - * @param offset - * 写入转换结果的起始位置; + * @param value 要转换的int整数; + * @param bytes 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的4个元素; + * @param offset 写入转换结果的起始位置; * @return 返回写入的长度; */ public static int toBytes(int value, byte[] bytes, int offset) { @@ -197,12 +191,9 @@ public class BytesUtils { *

* 以“高位在后”的方式转换,即:数值的高位保存在数组地址的高位; * - * @param value - * 要转换的int整数; - * @param bytes - * 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的4个元素; - * @param offset - * 写入转换结果的起始位置; + * @param value 要转换的int整数; + * @param bytes 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的4个元素; + * @param offset 写入转换结果的起始位置; * @return 返回写入的长度; */ public static int toBytesInReverse(int value, byte[] bytes, int offset) { @@ -218,14 +209,10 @@ public class BytesUtils { *

* 以“高位在后”的方式转换,即:数值的高位保存在数组地址的高位; * - * @param value - * 要转换的int整数; - * @param bytes - * 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的4个元素; - * @param offset - * 写入转换结果的起始位置; - * @param len - * 写入长度;必须大于 0 ,小于等于 4; + * @param value 要转换的int整数; + * @param bytes 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的4个元素; + * @param offset 写入转换结果的起始位置; + * @param len 写入长度;必须大于 0 ,小于等于 4; * @return 返回写入的长度; */ public static int toBytesInReverse(int value, byte[] bytes, int offset, int len) { @@ -263,12 +250,9 @@ public class BytesUtils { /** * 将 long 值转为8字节的二进制数组; * - * @param value - * 要转换的long整数; - * @param bytes - * 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的8个元素; - * @param offset - * 写入转换结果的起始位置; + * @param value 要转换的long整数; + * @param bytes 要保存转换结果的二进制数组;转换结果将从高位至低位的顺序写入数组从 offset 指定位置开始的8个元素; + * @param offset 写入转换结果的起始位置; * @return 返回写入的长度; */ public static int toBytes(long value, byte[] bytes, int offset) { @@ -345,8 +329,7 @@ public class BytesUtils { /** * 按从高位到低位的顺序将指定二进制数组从位置 0 开始的 4 个字节转换为 int 整数; * - * @param bytes - * 要转换的二进制数组; + * @param bytes 要转换的二进制数组; * @return 转换后的 int 整数; */ public static int toInt(byte[] bytes) { @@ -362,10 +345,8 @@ public class BytesUtils { /** * 按从高位到低位的顺序将指定二进制数组从 offset 参数指定的位置开始的 2 个字节转换为 short 整数; * - * @param bytes - * 要转换的二进制数组; - * @param offset - * 要读取数据的开始位置 + * @param bytes 要转换的二进制数组; + * @param offset 要读取数据的开始位置 * @return 转换后的 short 整数; */ public static short toShort(byte[] bytes, int offset) { @@ -387,10 +368,8 @@ public class BytesUtils { /** * 按从高位到低位的顺序将指定二进制数组从 offset 参数指定的位置开始的 4 个字节转换为 int 整数; * - * @param bytes - * 要转换的二进制数组; - * @param offset - * 要读取数据的开始位置 + * @param bytes 要转换的二进制数组; + * @param offset 要读取数据的开始位置 * @return 转换后的 int 整数; */ public static int toInt(byte[] bytes, int offset) { @@ -407,14 +386,11 @@ public class BytesUtils { /** * 按从高位到低位的顺序将指定二进制数组从 offset 参数指定的位置开始的 4 个字节转换为 int 整数; * - * @param bytes - * 要转换的二进制数组; - * @param offset - * 要读取数据的开始位置 + * @param bytes 要转换的二进制数组; + * @param offset 要读取数据的开始位置 * @return 转换后的 int 整数; * - * @param len - * 长度;len 必须满足: len 大于等于 1 且小于等于4; + * @param len 长度;len 必须满足: len 大于等于 1 且小于等于4; * @return 转换后的 int 整数; */ public static int toInt(byte[] bytes, int offset, int len) { @@ -433,18 +409,14 @@ public class BytesUtils { /** * 按从高位到低位的顺序将指定二进制数组从 offset 参数指定的位置开始的 4 个字节转换为 int 整数; * - * @param bytes - * 要转换的二进制数组; - * @param offset - * 要读取数据的开始位置 + * @param bytes 要转换的二进制数组; + * @param offset 要读取数据的开始位置 * @return 转换后的 int 整数; * - * @param len - * 长度;len 必须满足: len 大于等于 1 且小于等于4; - * @param highAlign - * 是否高位对齐;
- * true 表示参数 bytes 的首个字节对应为整数的最高8位;
- * false 表示参数 bytes 的最后字节对应为整数的最低8位; + * @param len 长度;len 必须满足: len 大于等于 1 且小于等于4; + * @param highAlign 是否高位对齐;
+ * true 表示参数 bytes 的首个字节对应为整数的最高8位;
+ * false 表示参数 bytes 的最后字节对应为整数的最低8位; * @return 转换后的 int 整数; */ public static int toInt(byte[] bytes, int offset, int len, boolean highAlign) { @@ -472,10 +444,8 @@ public class BytesUtils { /** * 按从高位到低位的顺序将指定二进制数组从 offset 参数指定的位置开始的 8个字节转换为 long 整数; * - * @param bytes - * 要转换的二进制数组; - * @param offset - * 要读取数据的开始位置 + * @param bytes 要转换的二进制数组; + * @param offset 要读取数据的开始位置 * @return 转换后的 long 整数; */ public static long toLong(byte[] bytes, int offset) { @@ -495,8 +465,7 @@ public class BytesUtils { /** * 从指定的输入流中读入2个字节,由前到后按由高位到低位的方式转为 short 整数; * - * @param in - * in + * @param in in * @return short */ public static short readShort(InputStream in) { @@ -531,8 +500,7 @@ public class BytesUtils { /** * 从指定的输入流中读入4个字节,由前到后按由高位到低位的方式转为 int 整数; * - * @param in - * in + * @param in in * @return int */ public static int readInt(InputStream in) { @@ -658,11 +626,9 @@ public class BytesUtils { /** * 从字节数组获取对象 * - * @param objBytes - * objBytes + * @param objBytes objBytes * @return object - * @throws Exception - * exception + * @throws Exception exception */ // public static Object getObjectFromBytes(byte[] objBytes) throws Exception { // if (objBytes == null || objBytes.length == 0) { @@ -676,11 +642,9 @@ public class BytesUtils { /** * 从对象获取一个字节数组; * - * @param obj - * obj + * @param obj obj * @return byte array - * @throws Exception - * exception + * @throws Exception exception */ public static byte[] getBytesFromObject(Object obj) throws Exception { if (obj == null) { From f550c6d51822ec3fa4cac0f6357dabf80a825525 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Mon, 10 Jun 2019 19:31:40 +0800 Subject: [PATCH 2/2] Refactored the Value structure of BaseAccount; --- .../contract/engine/ContractEngine.java | 1 + .../contract/jvm/JVMContractEngine.java | 1 + .../jd/blockchain/ledger/core/AccountSet.java | 4 +- .../blockchain/ledger/core/BaseAccount.java | 23 +- .../ledger/core/ContractAccount.java | 19 +- .../blockchain/ledger/core/CryptoConfig.java | 1 + .../blockchain/ledger/core/DataAccount.java | 21 +- .../ledger/core/LedgerAdminAccount.java | 1 + .../blockchain/ledger/core/LedgerEditor.java | 1 + .../blockchain/ledger/core/LedgerService.java | 1 + .../blockchain/ledger/core/MerkleDataSet.java | 1 + .../jd/blockchain/ledger/core/MerkleTree.java | 1 + .../ledger/core/ParticipantDataSet.java | 1 + .../ledger/core/TransactionSet.java | 1 + .../blockchain/ledger/core/UserAccount.java | 19 +- .../ledger/core/UserAccountSet.java | 1 + .../DefaultOperationHandleRegisteration.java | 2 +- .../ledger/core/impl/LedgerManager.java | 2 +- .../ledger/core/impl/LedgerQueryService.java | 113 ++- .../core/impl/LedgerRepositoryImpl.java | 1 - .../core/impl/TransactionBatchProcessor.java | 2 +- .../ContractEventSendOperationHandle.java | 2 +- .../impl/handles/ContractLedgerContext.java | 30 +- .../jd/blockchain/ledger/BaseAccountTest.java | 14 +- .../blockchain/ledger/LedgerEditerTest.java | 80 +- .../ledger/LedgerTransactionDataTest.java | 2 +- .../blockchain/ledger/TransactionSetTest.java | 8 +- .../jd/blockchain/ledger/BytesValueEntry.java | 182 ++-- .../com/jd/blockchain/ledger/KVDataEntry.java | 5 +- .../jd/blockchain/ledger/KVDataObject.java | 112 +-- .../jd/blockchain/ledger/LedgerException.java | 2 +- .../ledger/LedgerPermissionException.java | 2 +- .../ledger/ValueTypeCastException.java | 17 + .../BlockchainOperationFactory.java | 24 +- .../DataAccountKVSetOperationBuilder.java | 52 +- .../DataAccountKVSetOperationBuilderImpl.java | 18 +- .../ledger/data/TxContentBlobTest.java | 3 +- .../ledger/data/TxRequestMessageTest.java | 3 +- .../peer/web/LedgerQueryController.java | 236 +++-- .../contract/samples/AssetContractImpl.java | 7 +- .../sdk/samples/SDKDemo_InsertData.java | 2 +- .../SDK_GateWay_BatchInsertData_Test_.java | 8 +- .../test/SDK_GateWay_InsertData_Test_.java | 4 +- .../jd/blockchain/intgr/IntegrationTest.java | 17 +- .../intgr/perf/LedgerPerformanceTest.java | 7 +- .../jd/blockchain/intgr/IntegrationBase.java | 945 +++++++++--------- .../intgr/IntegrationTestAll4Redis.java | 57 +- .../intgr/IntegrationTestDataAccount.java | 2 +- .../service/RemoteTransactionService.java | 636 ++++++------ .../initializer/LedgerInitException.java | 2 +- .../java/com/jd/blockchain/utils/Bytes.java | 4 + .../jd/blockchain/utils/io/BytesUtils.java | 15 +- 52 files changed, 1424 insertions(+), 1291 deletions(-) create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ValueTypeCastException.java diff --git a/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java b/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java index 3f5a21c1..2e81c7f8 100644 --- a/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java +++ b/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java @@ -1,5 +1,6 @@ package com.jd.blockchain.contract.engine; +import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.utils.Bytes; /** diff --git a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JVMContractEngine.java b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JVMContractEngine.java index ea1ee9fa..0a8b0018 100644 --- a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JVMContractEngine.java +++ b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JVMContractEngine.java @@ -2,6 +2,7 @@ package com.jd.blockchain.contract.jvm; import com.jd.blockchain.contract.engine.ContractCode; import com.jd.blockchain.contract.engine.ContractEngine; +import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.runtime.Module; import com.jd.blockchain.runtime.RuntimeContext; import com.jd.blockchain.utils.Bytes; 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 b9ee4324..01ed4d2f 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 @@ -9,7 +9,9 @@ import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; @@ -420,7 +422,7 @@ public class AccountSet implements Transactional, MerkleProvable { // } @Override - public long setBytes(Bytes key, byte[] value, long version) { + public long setBytes(Bytes key, BytesValue value, long version) { long v = super.setBytes(key, value, version); if (v > -1) { updated = true; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java index 501f64c3..9a57c6d0 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BaseAccount.java @@ -1,10 +1,12 @@ package com.jd.blockchain.ledger.core; +import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.AccountHeader; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.BlockchainIdentityData; +import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; @@ -154,8 +156,9 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * If this operation fail by version checking or other reason, then * return -1; */ - public long setBytes(Bytes key, byte[] value, long version) { - return dataset.setValue(key, value, version); + public long setBytes(Bytes key, BytesValue value, long version) { + byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); + return dataset.setValue(key, bytesValue, version); } /** @@ -175,8 +178,12 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * @param key * @return return null if not exist; */ - public byte[] getBytes(Bytes key) { - return dataset.getValue(key); + public BytesValue getBytes(Bytes key) { + byte[] bytesValue = dataset.getValue(key); + if (bytesValue == null) { + return null; + } + return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); } /** @@ -186,8 +193,12 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional * @param version * @return return null if not exist; */ - public byte[] getBytes(Bytes key, long version) { - return dataset.getValue(key, version); + public BytesValue getBytes(Bytes key, long version) { + byte[] bytesValue = dataset.getValue(key, version); + if (bytesValue == null) { + return null; + } + return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); } @Override diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java index 323960f3..5a302ca8 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java @@ -3,8 +3,9 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.BytesValueEntry; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; public class ContractAccount implements AccountHeader { @@ -42,15 +43,16 @@ public class ContractAccount implements AccountHeader { } public long setChaincode(byte[] chaincode, long version) { - return accBase.setBytes(CHAIN_CODE_KEY, chaincode, version); + BytesValue bytesValue = BytesValueEntry.fromBytes(chaincode); + return accBase.setBytes(CHAIN_CODE_KEY, bytesValue, version); } public byte[] getChainCode() { - return accBase.getBytes(CHAIN_CODE_KEY); + return accBase.getBytes(CHAIN_CODE_KEY).getValue().toBytes(); } public byte[] getChainCode(long version) { - return accBase.getBytes(CHAIN_CODE_KEY, version); + return accBase.getBytes(CHAIN_CODE_KEY, version).getValue().toBytes(); } public long getChaincodeVersion() { @@ -58,15 +60,18 @@ public class ContractAccount implements AccountHeader { } public long setProperty(Bytes key, String value, long version) { - return accBase.setBytes(encodePropertyKey(key), BytesUtils.toBytes(value), version); + BytesValue bytesValue = BytesValueEntry.fromText(value); + return accBase.setBytes(encodePropertyKey(key), bytesValue, version); } public String getProperty(Bytes key) { - return BytesUtils.toString(accBase.getBytes(encodePropertyKey(key))); + BytesValue bytesValue = accBase.getBytes(encodePropertyKey(key)); + return BytesValueEntry.toText(bytesValue); } public String getProperty(Bytes key, long version) { - return BytesUtils.toString(accBase.getBytes(encodePropertyKey(key), version)); + BytesValue bytesValue = accBase.getBytes(encodePropertyKey(key), version); + return BytesValueEntry.toText(bytesValue); } private Bytes encodePropertyKey(Bytes key) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java index 2b905d6b..8f5d2ea1 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CryptoConfig.java @@ -5,6 +5,7 @@ import java.util.HashMap; import com.jd.blockchain.crypto.CryptoAlgorithm; import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; public class CryptoConfig implements CryptoSetting { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java index 08b5c23a..4d23ec27 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java @@ -44,19 +44,18 @@ public class DataAccount implements AccountHeader, MerkleProvable { public long setBytes(Bytes key, BytesValue value, long version) { - byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); - return baseAccount.setBytes(key, bytesValue, version); + return baseAccount.setBytes(key, value, version); } public long setBytes(Bytes key, String value, long version) { - BytesValue bv = BytesValueEntry.fromText(value); - return setBytes(key, bv, version); + BytesValue bytesValue = BytesValueEntry.fromText(value); + return baseAccount.setBytes(key, bytesValue, version); } public long setBytes(Bytes key, byte[] value, long version) { - BytesValue bv = BytesValueEntry.fromBytes(value); - return setBytes(key, bv, version); + BytesValue bytesValue = BytesValueEntry.fromBytes(value); + return baseAccount.setBytes(key, bytesValue, version); } /** @@ -87,7 +86,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @param key * @return return null if not exist; */ - public byte[] getBytes(String key) { + public BytesValue getBytes(String key) { return baseAccount.getBytes(Bytes.fromString(key)); } @@ -97,7 +96,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @param key * @return return null if not exist; */ - public byte[] getBytes(Bytes key) { + public BytesValue getBytes(Bytes key) { return baseAccount.getBytes(key); } @@ -108,7 +107,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @param version * @return return null if not exist; */ - public byte[] getBytes(String key, long version) { + public BytesValue getBytes(String key, long version) { return baseAccount.getBytes(Bytes.fromString(key), version); } @@ -119,7 +118,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @param version * @return return null if not exist; */ - public byte[] getBytes(Bytes key, long version) { + public BytesValue getBytes(Bytes key, long version) { return baseAccount.getBytes(key, version); } @@ -154,7 +153,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { key = baseAccount.dataset.getKeyAtIndex(fromIndex); ver = baseAccount.dataset.getVersion(key); BytesValue decodeData = BinaryProtocol.decode(value); - kvDataEntries[i] = new KVDataObject(key, ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); + kvDataEntries[i] = new KVDataObject(key, ver, decodeData); fromIndex++; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java index 88ab790a..c22a4ad2 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java @@ -10,6 +10,7 @@ import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.Crypto; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.HashFunction; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.LedgerInitSetting; import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.storage.service.ExPolicyKVStorage; 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 c781ffe2..efa3e750 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,6 +1,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.LedgerTransaction; import com.jd.blockchain.ledger.TransactionRequest; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerService.java index 452f46fa..b75032d6 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerService.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerService.java @@ -1,6 +1,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.LedgerException; /** * 账本管理器; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java index 10a83b49..b8dd170b 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java @@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; import com.jd.blockchain.storage.service.VersioningKVEntry; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTree.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTree.java index f124c82d..7c3c077c 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTree.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTree.java @@ -19,6 +19,7 @@ import com.jd.blockchain.crypto.Crypto; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.HashFunction; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; import com.jd.blockchain.utils.Bytes; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantDataSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantDataSet.java index 77e94d77..bd84185d 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantDataSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantDataSet.java @@ -5,6 +5,7 @@ import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionSet.java index 09b941d1..962244e5 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionSet.java @@ -4,6 +4,7 @@ import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.LedgerTransaction; import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.storage.service.ExPolicyKVStorage; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java index 1589f8db..f6faa1e0 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java @@ -2,9 +2,10 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.BytesValueEntry; import com.jd.blockchain.ledger.UserInfo; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; /** * 用户账户; @@ -40,21 +41,21 @@ public class UserAccount implements UserInfo { } public PubKey getDataPubKey() { - byte[] pkBytes = baseAccount.getBytes(DATA_PUB_KEY); + BytesValue pkBytes = baseAccount.getBytes(DATA_PUB_KEY); if (pkBytes == null) { return null; } - return new PubKey(pkBytes); + return new PubKey(pkBytes.getValue().toBytes()); } public long setDataPubKey(PubKey pubKey) { byte[] pkBytes = pubKey.toBytes(); - return baseAccount.setBytes(DATA_PUB_KEY, pkBytes, -1); + return baseAccount.setBytes(DATA_PUB_KEY, BytesValueEntry.fromBytes(pkBytes), -1); } public long setDataPubKey(PubKey pubKey, long version) { byte[] pkBytes = pubKey.toBytes(); - return baseAccount.setBytes(DATA_PUB_KEY, pkBytes, version); + return baseAccount.setBytes(DATA_PUB_KEY, BytesValueEntry.fromBytes(pkBytes), version); } public long setProperty(String key, String value, long version) { @@ -62,15 +63,17 @@ public class UserAccount implements UserInfo { } public long setProperty(Bytes key, String value, long version) { - return baseAccount.setBytes(encodePropertyKey(key), BytesUtils.toBytes(value), version); + return baseAccount.setBytes(encodePropertyKey(key), BytesValueEntry.fromText(value), version); } public String getProperty(Bytes key) { - return BytesUtils.toString(baseAccount.getBytes(encodePropertyKey(key))); + BytesValue value = baseAccount.getBytes(encodePropertyKey(key)); + return value == null ? null : value.getValue().toUTF8String(); } public String getProperty(Bytes key, long version) { - return BytesUtils.toString(baseAccount.getBytes(encodePropertyKey(key), version)); + BytesValue value = baseAccount.getBytes(encodePropertyKey(key), version); + return value == null ? null : value.getValue().toUTF8String(); } private Bytes encodePropertyKey(Bytes key) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java index 3f3ce45e..d28c15ed 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java @@ -4,6 +4,7 @@ import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.AccountHeader; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java index c5ea9bdc..ec0504e4 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java @@ -8,8 +8,8 @@ import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.UserRegisterOperation; -import com.jd.blockchain.ledger.core.LedgerException; import com.jd.blockchain.ledger.core.OperationHandle; import com.jd.blockchain.ledger.core.impl.handles.ContractCodeDeployOperationHandle; import com.jd.blockchain.ledger.core.impl.handles.ContractEventSendOperationHandle; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java index 4525ed9d..19dfee44 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerManager.java @@ -8,10 +8,10 @@ import com.jd.blockchain.crypto.CryptoAlgorithm; import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.LedgerInitSetting; import com.jd.blockchain.ledger.core.LedgerConsts; import com.jd.blockchain.ledger.core.LedgerEditor; -import com.jd.blockchain.ledger.core.LedgerException; import com.jd.blockchain.ledger.core.LedgerManage; import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.storage.service.ExPolicyKVStorage; 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 fba47095..66fbda39 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,10 +1,23 @@ package com.jd.blockchain.ledger.core.impl; -import com.jd.blockchain.binaryproto.BinaryProtocol; -import com.jd.blockchain.binaryproto.PrimitiveType; +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.AccountHeader; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.KVDataObject; +import com.jd.blockchain.ledger.KVDataVO; +import com.jd.blockchain.ledger.KVInfoVO; +import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerInfo; +import com.jd.blockchain.ledger.LedgerMetadata; +import com.jd.blockchain.ledger.LedgerTransaction; +import com.jd.blockchain.ledger.ParticipantNode; +import com.jd.blockchain.ledger.TransactionState; +import com.jd.blockchain.ledger.UserInfo; import com.jd.blockchain.ledger.core.ContractAccountSet; import com.jd.blockchain.ledger.core.DataAccount; import com.jd.blockchain.ledger.core.DataAccountSet; @@ -16,16 +29,12 @@ import com.jd.blockchain.ledger.core.UserAccountSet; import com.jd.blockchain.transaction.BlockchainQueryService; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.QueryUtil; -import com.jd.blockchain.utils.StringUtils; - -import java.util.ArrayList; -import java.util.List; public class LedgerQueryService implements BlockchainQueryService { - - private LedgerService ledgerService; - public LedgerQueryService(LedgerService ledgerService) { + private LedgerService ledgerService; + + public LedgerQueryService(LedgerService ledgerService) { this.ledgerService = ledgerService; } @@ -37,7 +46,7 @@ public class LedgerQueryService implements BlockchainQueryService { @Override public LedgerInfo getLedger(HashDigest ledgerHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - LedgerInfo ledgerInfo =new LedgerInfo(); + LedgerInfo ledgerInfo = new LedgerInfo(); ledgerInfo.setHash(ledger.getHash()); ledgerInfo.setLatestBlockHash(ledger.getLatestBlockHash()); ledgerInfo.setLatestBlockHeight(ledger.getLatestBlockHeight()); @@ -173,8 +182,8 @@ public class LedgerQueryService implements BlockchainQueryService { lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); } - int currentHeightTxTotalNums = (int)ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); - //取当前高度的增量交易数,在增量交易里进行查找 + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); + // 取当前高度的增量交易数,在增量交易里进行查找 int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; // // if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { @@ -187,8 +196,8 @@ public class LedgerQueryService implements BlockchainQueryService { // if (count > currentHeightTxNums) { // count = currentHeightTxNums - fromIndex; // } - int indexAndCount [] = QueryUtil.calFromIndexAndCount(fromIndex,count,currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0] , indexAndCount[1]); + int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); + return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); } @Override @@ -203,8 +212,8 @@ public class LedgerQueryService implements BlockchainQueryService { lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); } - int currentHeightTxTotalNums = (int)ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); - //取当前块hash的增量交易数,在增量交易里进行查找 + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); + // 取当前块hash的增量交易数,在增量交易里进行查找 int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; // if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { @@ -217,8 +226,8 @@ public class LedgerQueryService implements BlockchainQueryService { // if (count > currentHeightTxNums) { // count = currentHeightTxNums - fromIndex; // } - int indexAndCount [] = QueryUtil.calFromIndexAndCount(fromIndex,count,currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0] , indexAndCount[1]); + int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); + return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0], indexAndCount[1]); } @Override @@ -228,7 +237,7 @@ public class LedgerQueryService implements BlockchainQueryService { TransactionSet txset = ledger.getTransactionSet(block); return txset.get(contentHash); } - + @Override public TransactionState getTransactionStateByContentHash(HashDigest ledgerHash, HashDigest contentHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); @@ -243,7 +252,7 @@ public class LedgerQueryService implements BlockchainQueryService { LedgerBlock block = ledger.getLatestBlock(); UserAccountSet userAccountSet = ledger.getUserAccountSet(block); return userAccountSet.getUser(address); - + } @Override @@ -263,33 +272,32 @@ public class LedgerQueryService implements BlockchainQueryService { 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])); - dataAccount.getBytes(Bytes.fromString(keys[i]),1); + dataAccount.getBytes(Bytes.fromString(keys[i]), 1); if (ver < 0) { - entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); - }else { - byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); - BytesValue decodeData = BinaryProtocol.decode(value); - entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); + 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; } public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { - //parse kvInfoVO; + // parse kvInfoVO; List keyList = new ArrayList<>(); List versionList = new ArrayList<>(); - if(kvInfoVO != null){ - for(KVDataVO kvDataVO : kvInfoVO.getData()){ - for(Long version : kvDataVO.getVersion()){ + if (kvInfoVO != null) { + for (KVDataVO kvDataVO : kvInfoVO.getData()) { + for (Long version : kvDataVO.getVersion()) { keyList.add(kvDataVO.getKey()); versionList.add(version); } @@ -301,12 +309,12 @@ public class LedgerQueryService implements BlockchainQueryService { 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!"); - } + 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(); @@ -314,22 +322,21 @@ public class LedgerQueryService implements BlockchainQueryService { DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); KVDataEntry[] entries = new KVDataEntry[keys.length]; - long ver = -1; + long ver = -1; for (int i = 0; i < entries.length; i++) { // ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); // dataAccount.getBytes(Bytes.fromString(keys[i]),1); ver = versions[i]; if (ver < 0) { - entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); - }else { - if(dataAccount.getDataEntriesTotalCount()==0 || - dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null){ - //is the address is not exist; the result is null; - entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); + 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 { - byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); - BytesValue decodeData = BinaryProtocol.decode(value); - entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); + BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + entries[i] = new KVDataObject(keys[i], ver, value); } } } @@ -381,8 +388,8 @@ public class LedgerQueryService implements BlockchainQueryService { 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]); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccountSet.getTotalCount()); + return dataAccountSet.getAccounts(pages[0], pages[1]); } @Override @@ -390,8 +397,8 @@ public class LedgerQueryService implements BlockchainQueryService { 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]); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) contractAccountSet.getTotalCount()); + return contractAccountSet.getAccounts(pages[0], pages[1]); } private LedgerAdministration ledgerAdministration(HashDigest ledgerHash) { 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 3182c736..69e3223f 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 @@ -13,7 +13,6 @@ import com.jd.blockchain.ledger.core.LedgerAdministration; import com.jd.blockchain.ledger.core.LedgerConsts; import com.jd.blockchain.ledger.core.LedgerDataSet; import com.jd.blockchain.ledger.core.LedgerEditor; -import com.jd.blockchain.ledger.core.LedgerException; import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.ledger.core.LedgerTransactionContext; import com.jd.blockchain.ledger.core.TransactionSet; 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 7a0670b8..2adda2f6 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,13 +9,13 @@ import org.slf4j.LoggerFactory; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionResponse; 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.LedgerException; import com.jd.blockchain.ledger.core.LedgerService; import com.jd.blockchain.ledger.core.LedgerTransactionContext; import com.jd.blockchain.ledger.core.OperationHandle; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java index e1930a35..5680846c 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java @@ -9,11 +9,11 @@ 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.ContractEventSendOperation; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.ledger.core.ContractAccount; import com.jd.blockchain.ledger.core.ContractAccountSet; import com.jd.blockchain.ledger.core.LedgerDataSet; -import com.jd.blockchain.ledger.core.LedgerException; import com.jd.blockchain.ledger.core.LedgerService; import com.jd.blockchain.ledger.core.OperationHandle; import com.jd.blockchain.ledger.core.TransactionRequestContext; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java index c631f044..162f3408 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractLedgerContext.java @@ -269,13 +269,13 @@ public class ContractLedgerContext implements LedgerContext { return op; } - @Override - public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { - BytesValue bytesValue = BytesValueEntry.fromBytes(value); - this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); - handle(op); - return this; - } +// @Override +// public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { +// BytesValue bytesValue = BytesValueEntry.fromBytes(value); +// this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); +// handle(op); +// return this; +// } @Override public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { @@ -301,14 +301,14 @@ public class ContractLedgerContext implements LedgerContext { return this; } - @Deprecated - @Override - public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { - BytesValue bytesValue = BytesValueEntry.fromText(value); - this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); - handle(op); - return this; - } +// @Deprecated +// @Override +// public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { +// BytesValue bytesValue = BytesValueEntry.fromText(value); +// this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); +// handle(op); +// return this; +// } @Override public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java index 644b2863..ac9f50b1 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/BaseAccountTest.java @@ -12,11 +12,11 @@ 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.BytesValueEntry; import com.jd.blockchain.ledger.core.BaseAccount; import com.jd.blockchain.ledger.core.CryptoConfig; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; /** * @@ -53,33 +53,33 @@ public class BaseAccountTest { assertFalse(baseAccount.isReadonly()); // 在空白状态下写入数据; - long v = baseAccount.setBytes(Bytes.fromString("A"), BytesUtils.toBytes("VALUE_A"), 0); + long v = baseAccount.setBytes(Bytes.fromString("A"), BytesValueEntry.fromText("VALUE_A"), 0); // 预期失败; assertEquals(-1, v); - v = baseAccount.setBytes(Bytes.fromString("A"), BytesUtils.toBytes("VALUE_A"), 1); + v = baseAccount.setBytes(Bytes.fromString("A"), BytesValueEntry.fromText("VALUE_A"), 1); // 预期失败; assertEquals(-1, v); - v = baseAccount.setBytes(Bytes.fromString("A"), BytesUtils.toBytes("VALUE_A"), -1); + v = baseAccount.setBytes(Bytes.fromString("A"), BytesValueEntry.fromText("VALUE_A"), -1); // 预期成功; assertEquals(0, v); - v = baseAccount.setBytes(Bytes.fromString("A"), BytesUtils.toBytes("VALUE_A-1"), -1); + v = baseAccount.setBytes(Bytes.fromString("A"), BytesValueEntry.fromText("VALUE_A-1"), -1); // 已经存在版本,指定版本号-1,预期导致失败; assertEquals(-1, v); baseAccount.commit(); v = 0; for (int i = 0; i < 10; i++) { - long s = baseAccount.setBytes(Bytes.fromString("A"), BytesUtils.toBytes("VALUE_A_" + i), v); + long s = baseAccount.setBytes(Bytes.fromString("A"), BytesValueEntry.fromText("VALUE_A_" + i), v); baseAccount.commit(); // 预期成功; assertEquals(v + 1, s); v++; } - v = baseAccount.setBytes(Bytes.fromString("A"), BytesUtils.toBytes("VALUE_A_" + v), v + 1); + v = baseAccount.setBytes(Bytes.fromString("A"), BytesValueEntry.fromText("VALUE_A_" + v), v + 1); // 预期成功; assertEquals(-1, v); 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 3ae78c32..5018ede7 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 @@ -1,10 +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 org.junit.Before; import org.junit.Test; import com.jd.blockchain.binaryproto.DataContractRegistry; @@ -17,6 +17,8 @@ import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.BytesValueType; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInitSetting; import com.jd.blockchain.ledger.LedgerTransaction; @@ -37,67 +39,99 @@ import com.jd.blockchain.utils.io.BytesUtils; import com.jd.blockchain.utils.net.NetworkAddress; public class LedgerEditerTest { - + private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), SMCryptoService.class.getName() }; - static { DataContractRegistry.register(com.jd.blockchain.ledger.TransactionContent.class); DataContractRegistry.register(com.jd.blockchain.ledger.UserRegisterOperation.class); DataContractRegistry.register(com.jd.blockchain.ledger.BlockBody.class); } - String ledgerKeyPrefix = "LDG://"; - SignatureFunction signatureFunction = Crypto.getSignatureFunction("ED25519"); + private static final String LEDGER_KEY_PREFIX = "LDG://"; + private SignatureFunction signatureFunction; - // 存储; - MemoryKVStorage storage = new MemoryKVStorage(); + /** + * 初始化一个; + */ + @Before + public void beforeTest() { + signatureFunction = Crypto.getSignatureFunction("ED25519"); + } - TransactionRequest genesisTxReq = LedgerTestUtils.createTxRequest(null, signatureFunction); + /** + * @return + */ + private LedgerEditor createLedgerInitEditor() { + // 存储; + MemoryKVStorage storage = new MemoryKVStorage(); - // 创建初始化配置; - LedgerInitSetting initSetting = createLedgerInitSetting(); + // 创建初始化配置; + LedgerInitSetting initSetting = createLedgerInitSetting(); - // 创建账本; - LedgerEditor ldgEdt = LedgerTransactionalEditor.createEditor(initSetting, ledgerKeyPrefix, storage, storage); - LedgerTransactionContext txCtx = ldgEdt.newTransaction(genesisTxReq); - LedgerDataSet ldgDS = txCtx.getDataSet(); + // 创建账本; + return LedgerTransactionalEditor.createEditor(initSetting, LEDGER_KEY_PREFIX, storage, storage); + } - AsymmetricKeypair cryptoKeyPair = signatureFunction.generateKeypair(); + private LedgerTransactionContext createGenisisTx(LedgerEditor ldgEdt) { + TransactionRequest genesisTxReq = LedgerTestUtils.createTxRequest(null, signatureFunction); + + LedgerTransactionContext txCtx = ldgEdt.newTransaction(genesisTxReq); + + return txCtx; + } @SuppressWarnings("unused") @Test public void testWriteDataAccoutKvOp() { - + LedgerEditor ldgEdt = createLedgerInitEditor(); + LedgerTransactionContext genisisTxCtx = createGenisisTx(ldgEdt); + LedgerDataSet ldgDS = genisisTxCtx.getDataSet(); + + + AsymmetricKeypair cryptoKeyPair = signatureFunction.generateKeypair(); BlockchainKeypair dataKP = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey()); DataAccount dataAccount = ldgDS.getDataAccountSet().register(dataKP.getAddress(), dataKP.getPubKey(), null); - dataAccount.setBytes(Bytes.fromString("A"), "abc".getBytes(), -1); + dataAccount.setBytes(Bytes.fromString("A"), "abc", -1); - LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS); + LedgerTransaction tx = genisisTxCtx.commit(TransactionState.SUCCESS); LedgerBlock block = ldgEdt.prepare(); // 提交数据,写入存储; ldgEdt.commit(); - byte[] bytes = dataAccount.getBytes("A"); - assertArrayEquals("abc".getBytes(), bytes); + // 预期这是第1个区块; + assertNotNull(block); + assertNotNull(block.getHash()); + assertEquals(0, block.getHeight()); + + // 验证数据读写的一致性; + BytesValue bytes = dataAccount.getBytes("A"); + assertEquals(BytesValueType.TEXT, bytes.getType()); + String textValue = bytes.getValue().toUTF8String(); + assertEquals("abc", textValue); } /** * 测试创建账本; */ @Test - public void testLedgerEditorCreation() { + public void testGennesisBlockCreation() { + LedgerEditor ldgEdt = createLedgerInitEditor(); + LedgerTransactionContext genisisTxCtx = createGenisisTx(ldgEdt); + LedgerDataSet ldgDS = genisisTxCtx.getDataSet(); + AsymmetricKeypair cryptoKeyPair = signatureFunction.generateKeypair(); BlockchainKeypair userKP = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey()); UserAccount userAccount = ldgDS.getUserAccountSet().register(userKP.getAddress(), userKP.getPubKey()); userAccount.setProperty("Name", "孙悟空", -1); userAccount.setProperty("Age", "10000", -1); - LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS); + LedgerTransaction tx = genisisTxCtx.commit(TransactionState.SUCCESS); + TransactionRequest genesisTxReq = genisisTxCtx.getRequestTX(); assertEquals(genesisTxReq.getTransactionContent().getHash(), tx.getTransactionContent().getHash()); assertEquals(0, tx.getBlockHeight()); @@ -116,7 +150,7 @@ public class LedgerEditerTest { private LedgerInitSetting createLedgerInitSetting() { SignatureFunction signFunc = Crypto.getSignatureFunction("ED25519"); - + CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java index ba533a4a..d99ed706 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java @@ -257,7 +257,7 @@ public class LedgerTransactionDataTest { // contentBlob.setSubjectAccount(id.getAddress()); // contentBlob.setSequenceNumber(1); DataAccountKVSetOperation kvsetOP = opFactory.dataAccount(id.getAddress()) - .set("Name", ByteArray.fromString("AAA", "UTF-8"), -1).getOperation(); + .setText("Name", "AAA", -1).getOperation(); contentBlob.addOperation(kvsetOP); return contentBlob; } 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 60b48975..9deda3cc 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 @@ -6,14 +6,12 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import java.security.KeyFactory; import java.util.Random; -import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.crypto.HashDigest; - import org.junit.Test; +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.ContractCodeDeployOperation; @@ -71,7 +69,7 @@ public class TransactionSetTest { DataAccountRegisterOperation dataAccRegOp = txBuilder.dataAccounts().register(dataKey.getIdentity()); DataAccountKVSetOperation kvsetOP = txBuilder.dataAccount(dataKey.getAddress()) - .set("A", "Value_A_0".getBytes(), -1).set("B", "Value_B_0".getBytes(), -1).getOperation(); + .setText("A", "Value_A_0", -1).setText("B", "Value_B_0", -1).getOperation(); byte[] chainCode = new byte[128]; rand.nextBytes(chainCode); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java index b5ce137b..bf88ff70 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEntry.java @@ -8,85 +8,107 @@ import com.jd.blockchain.utils.io.BytesUtils; * @author huanghaiquan * */ -public class BytesValueEntry implements BytesValue{ - BytesValueType type; - Bytes value; - - private BytesValueEntry(BytesValueType type, byte[] bytes) { - this.type = type; - this.value = new Bytes(bytes); - } - - private BytesValueEntry(BytesValueType type, Bytes bytes) { - this.type = type; - this.value = bytes; - } - - public static BytesValue fromBytes(byte[] value) { - return new BytesValueEntry(BytesValueType.BYTES, value); - } - - public static BytesValue fromBytes(Bytes value) { - return new BytesValueEntry(BytesValueType.BYTES, value); - } - - public static BytesValue fromImage(byte[] value) { - return new BytesValueEntry(BytesValueType.IMG, value); - } - - public static BytesValue fromImage(Bytes value) { - return new BytesValueEntry(BytesValueType.IMG, value); - } - - public static BytesValue fromText(String value) { - return new BytesValueEntry(BytesValueType.TEXT, BytesUtils.toBytes(value)); - } - - public static BytesValue fromJSON(String value) { - return new BytesValueEntry(BytesValueType.JSON, BytesUtils.toBytes(value)); - } - - public static BytesValue fromXML(String value) { - return new BytesValueEntry(BytesValueType.XML, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt32(int value) { - return new BytesValueEntry(BytesValueType.INT32, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt64(long value) { - return new BytesValueEntry(BytesValueType.INT64, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt16(short value) { - return new BytesValueEntry(BytesValueType.INT16, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt8(byte value) { - return new BytesValueEntry(BytesValueType.INT8, BytesUtils.toBytes(value)); - } - - public static BytesValue fromTimestamp(long value) { - return new BytesValueEntry(BytesValueType.TIMESTAMP, BytesUtils.toBytes(value)); - } - - public static BytesValue fromBoolean(boolean value) { - return new BytesValueEntry(BytesValueType.BOOLEAN, BytesUtils.toBytes(value)); - } - - - @Override - public BytesValueType getType() { - return this.type; - } - - public void setType(BytesValueType type) { - this.type = type; - } - - @Override - public Bytes getValue() { - return this.value; - } +public class BytesValueEntry implements BytesValue { + BytesValueType type; + Bytes value; + + private BytesValueEntry(BytesValueType type, byte[] bytes) { + this.type = type; + this.value = new Bytes(bytes); + } + + private BytesValueEntry(BytesValueType type, Bytes bytes) { + this.type = type; + this.value = bytes; + } + + public static BytesValue fromBytes(byte[] value) { + return new BytesValueEntry(BytesValueType.BYTES, value); + } + + public static BytesValue fromBytes(Bytes value) { + return new BytesValueEntry(BytesValueType.BYTES, value); + } + + public static BytesValue fromImage(byte[] value) { + return new BytesValueEntry(BytesValueType.IMG, value); + } + + public static BytesValue fromImage(Bytes value) { + return new BytesValueEntry(BytesValueType.IMG, value); + } + + /** + * 以 UTF-8 编码从字符串转换为字节数组值; + * + * @param value + * @return + */ + public static BytesValue fromText(String value) { + return new BytesValueEntry(BytesValueType.TEXT, BytesUtils.toBytes(value)); + } + + /** + * 以 UTF-8 编码把字节数组值转换为字符串; + * + * @param bytesValue + * @return + */ + public static String toText(BytesValue bytesValue) { + if (bytesValue == null) { + return null; + } + if (bytesValue.getType() != BytesValueType.TEXT) { + throw new ValueTypeCastException("The expected value type is " + BytesValueType.TEXT.toString() + + ", but it is actually " + bytesValue.getType().toString() + "!"); + } + return bytesValue.getValue().toUTF8String(); + } + + public static BytesValue fromJSON(String value) { + return new BytesValueEntry(BytesValueType.JSON, BytesUtils.toBytes(value)); + } + + public static BytesValue fromXML(String value) { + return new BytesValueEntry(BytesValueType.XML, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt32(int value) { + return new BytesValueEntry(BytesValueType.INT32, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt64(long value) { + return new BytesValueEntry(BytesValueType.INT64, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt16(short value) { + return new BytesValueEntry(BytesValueType.INT16, BytesUtils.toBytes(value)); + } + + public static BytesValue fromInt8(byte value) { + return new BytesValueEntry(BytesValueType.INT8, BytesUtils.toBytes(value)); + } + + public static BytesValue fromTimestamp(long value) { + return new BytesValueEntry(BytesValueType.TIMESTAMP, BytesUtils.toBytes(value)); + } + + public static BytesValue fromBoolean(boolean value) { + return new BytesValueEntry(BytesValueType.BOOLEAN, BytesUtils.toBytes(value)); + } + + @Override + public BytesValueType getType() { + return this.type; + } + + public void setType(BytesValueType type) { + this.type = type; + } + + @Override + public Bytes getValue() { + return this.value; + } } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataEntry.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataEntry.java index efce0703..9d4e0870 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataEntry.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataEntry.java @@ -1,7 +1,5 @@ package com.jd.blockchain.ledger; -import com.jd.blockchain.binaryproto.PrimitiveType; - public interface KVDataEntry { /** @@ -27,11 +25,12 @@ public interface KVDataEntry { * * @return */ - PrimitiveType getType(); + BytesValueType getType(); /** * 值; * @return */ Object getValue(); + } \ No newline at end of file diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java index b39d9a1c..2f081642 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java @@ -1,11 +1,10 @@ package com.jd.blockchain.ledger; -import java.io.ByteArrayInputStream; -import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.util.Date; import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.io.ByteArray; import com.jd.blockchain.utils.io.BytesUtils; @@ -25,13 +24,10 @@ public class KVDataObject implements KVDataEntry { private long version; - private PrimitiveType type; + private BytesValue bytesValue; - private byte[] bytesValue; - - public KVDataObject(String key, long version, PrimitiveType type, byte[] bytesValue) { + public KVDataObject(String key, long version, BytesValue bytesValue) { this.key = key; - this.type = type; this.version = version < 0 ? -1 : version; this.bytesValue = bytesValue; } @@ -62,8 +58,8 @@ public class KVDataObject implements KVDataEntry { * @see com.jd.blockchain.ledger.KVDataEntry#getType() */ @Override - public PrimitiveType getType() { - return type; + public BytesValueType getType() { + return bytesValue == null ? BytesValueType.NIL : bytesValue.getType(); } @Override @@ -72,24 +68,20 @@ public class KVDataObject implements KVDataEntry { return null; } - try { - switch (type) { - case NIL: - return null; - case TEXT: - return new String(bytesValue, "UTF-8"); - case BYTES: - return ByteArray.toHex(bytesValue); - case INT64: - return BytesUtils.readLong(new ByteArrayInputStream(bytesValue)); - case JSON: - return new String(bytesValue, "UTF-8"); + switch (getType()) { + case NIL: + return null; + case TEXT: + return bytesValue.getValue().toUTF8String(); + case BYTES: + return ByteArray.toHex(bytesValue.getValue().toBytes()); + case INT64: + return BytesUtils.toLong(bytesValue.getValue().toBytes()); + case JSON: + return bytesValue.getValue().toUTF8String(); - default: - throw new IllegalStateException("Unsupported value type[" + type + "] to resolve!"); - } - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e.getMessage(), e); + default: + throw new IllegalStateException("Unsupported value type[" + getType() + "] to resolve!"); } } @@ -103,7 +95,7 @@ public class KVDataObject implements KVDataEntry { * @return */ public boolean isNil() { - return PrimitiveType.NIL == type; + return bytesValue == null || BytesValueType.NIL == bytesValue.getType(); } /** @@ -111,8 +103,8 @@ public class KVDataObject implements KVDataEntry { * * @return */ - ByteArray bytesArray() { - return ByteArray.wrapReadonly(bytesValue); + Bytes bytesArray() { + return bytesValue.getValue(); } /** @@ -127,10 +119,10 @@ public class KVDataObject implements KVDataEntry { * @return */ public byte tinyValue() { - if (PrimitiveType.INT8 == type) { - return bytesValue[0]; + if (BytesValueType.INT8 == getType()) { + return bytesValue.getValue().toBytes()[0]; } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.INT8, type)); + throw new IllegalStateException(String.format("Expected type [%s], but [%s]", BytesValueType.INT8, getType())); } /** @@ -145,10 +137,10 @@ public class KVDataObject implements KVDataEntry { * @return */ public short shortValue() { - if (PrimitiveType.INT16 == type) { - return BytesUtils.toShort(bytesValue, 0); + if (BytesValueType.INT16 == getType()) { + return BytesUtils.toShort(bytesValue.getValue().toBytes(), 0); } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.INT16, type)); + throw new IllegalStateException(String.format("Expected type [%s], but [%s]", BytesValueType.INT16, getType())); } /** @@ -163,10 +155,10 @@ public class KVDataObject implements KVDataEntry { * @return */ public int intValue() { - if (PrimitiveType.INT32 == type) { - return BytesUtils.toInt(bytesValue, 0); + if (BytesValueType.INT32 == getType()) { + return BytesUtils.toInt(bytesValue.getValue().toBytes(), 0); } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.INT32, type)); + throw new IllegalStateException(String.format("Expected type [%s], but [%s]", BytesValueType.INT32, getType())); } /** @@ -181,10 +173,10 @@ public class KVDataObject implements KVDataEntry { * @return */ public long longValue() { - if (PrimitiveType.INT64 == type) { - return BytesUtils.toLong(bytesValue, 0); + if (BytesValueType.INT64 == getType()) { + return BytesUtils.toLong(bytesValue.getValue().toBytes(), 0); } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.INT64, type)); + throw new IllegalStateException(String.format("Expected type [%s], but [%s]", BytesValueType.INT64, getType())); } @@ -200,10 +192,11 @@ public class KVDataObject implements KVDataEntry { * @return */ public BigInteger bigIntValue() { - if (PrimitiveType.BIG_INT == type) { - return new BigInteger(bytesValue); + if (BytesValueType.BIG_INT == getType()) { + return new BigInteger(bytesValue.getValue().toBytes()); } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.BIG_INT, type)); + throw new IllegalStateException( + String.format("Expected type [%s], but [%s]", BytesValueType.BIG_INT, getType())); } /** @@ -218,10 +211,11 @@ public class KVDataObject implements KVDataEntry { * @return */ public boolean boolValue() { - if (PrimitiveType.BOOLEAN == type) { - return bytesValue[0] != 0; + if (BytesValueType.BOOLEAN == getType()) { + return BytesUtils.toBoolean(bytesValue.getValue().toBytes()[0]); } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.BOOLEAN, type)); + throw new IllegalStateException( + String.format("Expected type [%s], but [%s]", BytesValueType.BOOLEAN, getType())); } /** @@ -236,19 +230,20 @@ public class KVDataObject implements KVDataEntry { * @return */ public Date datetimeValue() { - if (PrimitiveType.TIMESTAMP == type) { - long ts = BytesUtils.toLong(bytesValue); + if (BytesValueType.TIMESTAMP == getType()) { + long ts = BytesUtils.toLong(bytesValue.getValue().toBytes()); return new Date(ts); } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", PrimitiveType.TIMESTAMP, type)); + throw new IllegalStateException( + String.format("Expected type [%s], but [%s]", BytesValueType.TIMESTAMP, getType())); } /** * 返回大整数值; *

* - * 仅当数据类型 {@link #getType()} 为 {@link PrimitiveType#TEXT} / {@link PrimitiveType#JSON} / - * {@link PrimitiveType#XML} 有效; + * 仅当数据类型 {@link #getType()} 为 {@link PrimitiveType#TEXT} / + * {@link PrimitiveType#JSON} / {@link PrimitiveType#XML} 有效; *

* * 无效类型将引发 {@link IllegalStateException} 异常; @@ -256,15 +251,12 @@ public class KVDataObject implements KVDataEntry { * @return */ public String stringValue() { - if (PrimitiveType.TEXT == type || PrimitiveType.JSON == type || PrimitiveType.XML == type) { - try { - return new String(bytesValue, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e.getMessage(), e); - } + BytesValueType type = getType(); + if (BytesValueType.TEXT == type || BytesValueType.JSON == type || BytesValueType.XML == type) { + return bytesValue.getValue().toUTF8String(); } - throw new IllegalStateException(String.format("Expected type [%s] or [%s] or [%s] , but [%s]", PrimitiveType.TEXT, - PrimitiveType.JSON, PrimitiveType.XML, type)); + throw new IllegalStateException(String.format("Expected type [%s] or [%s] or [%s] , but [%s]", + PrimitiveType.TEXT, BytesValueType.JSON, BytesValueType.XML, type)); } // // ---------------- 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 cca719cb..9d0dd838 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 @@ -1,4 +1,4 @@ -package com.jd.blockchain.ledger.core; +package com.jd.blockchain.ledger; public class LedgerException extends RuntimeException { diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java index 6c1a3b5c..21b3cee1 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermissionException.java @@ -1,4 +1,4 @@ -package com.jd.blockchain.ledger.core; +package com.jd.blockchain.ledger; public class LedgerPermissionException extends LedgerException { diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ValueTypeCastException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ValueTypeCastException.java new file mode 100644 index 00000000..30da88cb --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ValueTypeCastException.java @@ -0,0 +1,17 @@ +package com.jd.blockchain.ledger; + +public class ValueTypeCastException extends LedgerException { + + + private static final long serialVersionUID = 6641080037721006099L; + + + public ValueTypeCastException(String message) { + super(message); + } + + public ValueTypeCastException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java index 107bcbf7..ca0623f2 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java @@ -150,12 +150,12 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe } } - @Override - public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { - innerBuilder.set(key, value, expVersion); - addOperation(); - return this; - } +// @Override +// public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { +// innerBuilder.set(key, value, expVersion); +// addOperation(); +// return this; +// } @Override public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { @@ -192,12 +192,12 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe return this; } - @Override - public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { - innerBuilder.setText(key, value, expVersion); - addOperation(); - return this; - } +// @Override +// public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { +// innerBuilder.setText(key, value, expVersion); +// addOperation(); +// return this; +// } @Override public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java index 11971efc..f7c9ae8f 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java @@ -16,19 +16,19 @@ public interface DataAccountKVSetOperationBuilder { */ DataAccountKVSetOperation getOperation(); - /** - * 写入字节数组; - * - * @param key - * 键; - * @param value - * 值;byte[]格式 - * @param expVersion - * 预期的当前版本;如果版本不匹配,则写入失败; - * @return - */ - @Deprecated - DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion); +// /** +// * 写入字节数组; +// * +// * @param key +// * 键; +// * @param value +// * 值;byte[]格式 +// * @param expVersion +// * 预期的当前版本;如果版本不匹配,则写入失败; +// * @return +// */ +// @Deprecated +// DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion); /** * 写入字节数组; @@ -69,19 +69,19 @@ public interface DataAccountKVSetOperationBuilder { */ DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion); - /** - * 写入文本键值; - * - * @param key - * 键; - * @param value - * 值;String格式 - * @param expVersion - * 预期的当前版本;如果版本不匹配,则写入失败; - * @return - */ - @Deprecated - DataAccountKVSetOperationBuilder set(String key, String value, long expVersion); +// /** +// * 写入文本键值; +// * +// * @param key +// * 键; +// * @param value +// * 值;String格式 +// * @param expVersion +// * 预期的当前版本;如果版本不匹配,则写入失败; +// * @return +// */ +// @Deprecated +// DataAccountKVSetOperationBuilder set(String key, String value, long expVersion); /** * 写入文本键值; diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java index ce056eb4..d8125022 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java @@ -18,11 +18,11 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe return operation; } - @Deprecated - @Override - public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { - return setBytes(key, value, expVersion); - } +// @Deprecated +// @Override +// public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) { +// return setBytes(key, value, expVersion); +// } @Override public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { @@ -38,10 +38,10 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe return this; } - @Override - public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { - return setText(key, value, expVersion); - } +// @Override +// public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { +// return setText(key, value, expVersion); +// } @Override public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxContentBlobTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxContentBlobTest.java index a76e4e93..fc4120d3 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxContentBlobTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxContentBlobTest.java @@ -22,7 +22,6 @@ import com.jd.blockchain.ledger.TransactionContent; import com.jd.blockchain.ledger.TransactionContentBody; import com.jd.blockchain.transaction.BlockchainOperationFactory; import com.jd.blockchain.transaction.TxContentBlob; -import com.jd.blockchain.utils.io.ByteArray; public class TxContentBlobTest { @@ -48,7 +47,7 @@ public class TxContentBlobTest { contentBlob.setHash(contentHash); DataAccountKVSetOperation kvsetOP = opFactory.dataAccount(id.getAddress()) - .set("Name", ByteArray.fromString("AAA", "UTF-8"), -1).getOperation(); + .setText("Name", "AAA", -1).getOperation(); contentBlob.addOperation(kvsetOP); } diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxRequestMessageTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxRequestMessageTest.java index dd7366f9..6083089f 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxRequestMessageTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/TxRequestMessageTest.java @@ -37,7 +37,6 @@ import com.jd.blockchain.transaction.BlockchainOperationFactory; import com.jd.blockchain.transaction.DigitalSignatureBlob; import com.jd.blockchain.transaction.TxContentBlob; import com.jd.blockchain.transaction.TxRequestMessage; -import com.jd.blockchain.utils.io.ByteArray; /** * @@ -204,7 +203,7 @@ public class TxRequestMessageTest { // contentBlob.setSubjectAccount(id.getAddress()); // contentBlob.setSequenceNumber(1); DataAccountKVSetOperation kvsetOP = opFactory.dataAccount(id.getAddress()) - .set("Name", ByteArray.fromString("AAA", "UTF-8"), -1).getOperation(); + .setText("Name","AAA", -1).getOperation(); contentBlob.addOperation(kvsetOP); return contentBlob; } 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 222d7bf6..01c2ef61 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,14 +1,31 @@ package com.jd.blockchain.peer.web; -import com.jd.blockchain.contract.ContractException; -import com.jd.blockchain.ledger.*; -import com.jd.blockchain.utils.StringUtils; +import java.util.ArrayList; +import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +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.binaryproto.BinaryProtocol; -import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.contract.ContractException; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.KVDataObject; +import com.jd.blockchain.ledger.KVDataVO; +import com.jd.blockchain.ledger.KVInfoVO; +import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerInfo; +import com.jd.blockchain.ledger.LedgerMetadata; +import com.jd.blockchain.ledger.LedgerTransaction; +import com.jd.blockchain.ledger.ParticipantNode; +import com.jd.blockchain.ledger.TransactionState; +import com.jd.blockchain.ledger.UserInfo; import com.jd.blockchain.ledger.core.ContractAccountSet; import com.jd.blockchain.ledger.core.DataAccount; import com.jd.blockchain.ledger.core.DataAccountSet; @@ -22,15 +39,12 @@ import com.jd.blockchain.transaction.BlockchainQueryService; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.QueryUtil; -import java.util.ArrayList; -import java.util.List; - @RestController @RequestMapping(path = "/") public class LedgerQueryController implements BlockchainQueryService { - - @Autowired - private LedgerService ledgerService; + + @Autowired + private LedgerService ledgerService; @RequestMapping(method = RequestMethod.GET, path = "ledgers") @Override @@ -42,7 +56,8 @@ public class LedgerQueryController implements BlockchainQueryService { @Override public LedgerInfo getLedger(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - //TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; + // TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher + // ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; LedgerInfo ledgerInfo = new LedgerInfo(); ledgerInfo.setHash(ledgerHash); ledgerInfo.setLatestBlockHash(ledger.getLatestBlockHash()); @@ -83,25 +98,27 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks/height/{blockHeight}") @Override public LedgerBlock getBlock(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "blockHeight") long blockHeight) { + @PathVariable(name = "blockHeight") long blockHeight) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - //TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; + // 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) { + @PathVariable(name = "blockHash") HashDigest blockHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); - //TODO: 需要配置返回值的 spring MsgQueueMessageDispatcher ,对返回对象仅仅序列化声明的返回值类型的属性,而不是整个对象本身; + // 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) { + @PathVariable(name = "blockHeight") long blockHeight) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(blockHeight); TransactionSet txSet = ledger.getTransactionSet(block); @@ -111,7 +128,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "blockHash") HashDigest blockHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(blockHash); TransactionSet txSet = ledger.getTransactionSet(block); @@ -130,7 +147,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "blockHeight") long height) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(height); DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); @@ -140,7 +157,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "blockHash") HashDigest blockHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(blockHash); DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); @@ -159,7 +176,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "blockHeight") long height) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(height); UserAccountSet userAccountSet = ledger.getUserAccountSet(block); @@ -169,7 +186,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "blockHash") HashDigest blockHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(blockHash); UserAccountSet userAccountSet = ledger.getUserAccountSet(block); @@ -188,7 +205,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "blockHeight") long height) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(height); ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); @@ -198,7 +215,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "blockHash") HashDigest blockHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getBlock(blockHash); ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); @@ -217,9 +234,9 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @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); @@ -230,8 +247,8 @@ public class LedgerQueryController implements BlockchainQueryService { lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(blockHeight - 1)).getTotalCount(); } - int currentHeightTxTotalNums = (int)ledger.getTransactionSet(ledger.getBlock(blockHeight)).getTotalCount(); - //取当前高度的增量交易数,在增量交易里进行查找 + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(blockHeight)).getTotalCount(); + // 取当前高度的增量交易数,在增量交易里进行查找 int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; // if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { @@ -245,15 +262,15 @@ public class LedgerQueryController implements BlockchainQueryService { // count = currentHeightTxNums - fromIndex; // } int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0] , indexAndCount[1]); + 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) { + @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(); @@ -264,8 +281,8 @@ public class LedgerQueryController implements BlockchainQueryService { lastHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height - 1)).getTotalCount(); } - int currentHeightTxTotalNums = (int)ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); - //取当前块hash的增量交易数,在增量交易里进行查找 + int currentHeightTxTotalNums = (int) ledger.getTransactionSet(ledger.getBlock(height)).getTotalCount(); + // 取当前块hash的增量交易数,在增量交易里进行查找 int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; // if (fromIndex < 0 || fromIndex >= currentHeightTxNums) { @@ -279,13 +296,13 @@ public class LedgerQueryController implements BlockchainQueryService { // count = currentHeightTxNums - fromIndex; // } int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex, count, currentHeightTxNums); - return transactionSet.getTxs(lastHeightTxTotalNums + indexAndCount[0] , indexAndCount[1]); + 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) { + @PathVariable(name = "contentHash") HashDigest contentHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); TransactionSet txset = ledger.getTransactionSet(block); @@ -295,7 +312,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/txs/state/{contentHash}") @Override public TransactionState getTransactionStateByContentHash(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "contentHash") HashDigest contentHash) { + @PathVariable(name = "contentHash") HashDigest contentHash) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); TransactionSet txset = ledger.getTransactionSet(block); @@ -305,7 +322,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users/address/{address}") @Override public UserInfo getUser(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { + @PathVariable(name = "address") String address) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); UserAccountSet userAccountSet = ledger.getUserAccountSet(block); @@ -315,18 +332,18 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/address/{address}") @Override public AccountHeader getDataAccount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { + @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") + @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) { + @PathVariable(name = "address") String address, @RequestParam("keys") String... keys) { if (keys == null || keys.length == 0) { return null; } @@ -334,51 +351,50 @@ public class LedgerQueryController implements BlockchainQueryService { 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, PrimitiveType.NIL, null); - }else { - byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); - BytesValue decodeData = BinaryProtocol.decode(value); - entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); + 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") + @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()]); + @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; + return null; } if (versions == null || versions.length == 0) { return null; } - if(keys.length != versions.length){ - throw new ContractException("keys.length!=versions.length!"); - } + if (keys.length != versions.length) { + throw new ContractException("keys.length!=versions.length!"); + } LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); @@ -389,18 +405,17 @@ public class LedgerQueryController implements BlockchainQueryService { long ver = -1; for (int i = 0; i < entries.length; i++) { // ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); - ver = versions[i]; + ver = versions[i]; if (ver < 0) { - entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); - }else { - if(dataAccount.getDataEntriesTotalCount()==0 || - dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null){ - //is the address is not exist; the result is null; - entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); + 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 { - byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); - BytesValue decodeData = BinaryProtocol.decode(value); - entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); + BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + entries[i] = new KVDataObject(keys[i], ver, value); } } } @@ -408,12 +423,13 @@ public class LedgerQueryController implements BlockchainQueryService { return entries; } - @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/address/{address}/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) { + @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(); @@ -426,7 +442,7 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @PathVariable(name = "address") String address) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); @@ -439,7 +455,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/address/{address}") @Override public AccountHeader getContract(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { + @PathVariable(name = "address") String address) { LedgerRepository ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block); @@ -448,6 +464,7 @@ public class LedgerQueryController implements BlockchainQueryService { /** * get more users by fromIndex and count; + * * @param ledgerHash * @param fromIndex * @param count @@ -456,44 +473,45 @@ public class LedgerQueryController implements BlockchainQueryService { @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) { + @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]); + 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 + @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) { + @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]); - } + 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/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java index ab644986..770f78c4 100644 --- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java +++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java @@ -11,7 +11,6 @@ import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.KVDataObject; -import com.jd.blockchain.utils.io.BytesUtils; /** * 示例:一个“资产管理”智能合约的实现; @@ -53,14 +52,14 @@ public class AssetContractImpl implements EventProcessingAwire, AssetContract { // 计算资产的发行总数; KVDataObject currTotal = (KVDataObject) kvEntries[0]; long newTotal = currTotal.longValue() + amount; - eventContext.getLedger().dataAccount(ASSET_ADDRESS).set(KEY_TOTAL, BytesUtils.toBytes(newTotal), + eventContext.getLedger().dataAccount(ASSET_ADDRESS).setInt64(KEY_TOTAL, newTotal, currTotal.getVersion()); // 分配到持有者账户; KVDataObject holderAmount = (KVDataObject) kvEntries[1]; long newHodlerAmount = holderAmount.longValue() + amount; - eventContext.getLedger().dataAccount(ASSET_ADDRESS).set(assetHolderAddress, BytesUtils.toBytes(newHodlerAmount), - holderAmount.getVersion()).set("K2", (byte[])null, -1).set("k3", (byte[])null, 3); + eventContext.getLedger().dataAccount(ASSET_ADDRESS).setInt64(assetHolderAddress, newHodlerAmount, + holderAmount.getVersion()).setText("K2", "info2", -1).setText("k3", "info3", 3); } diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_InsertData.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_InsertData.java index abe4bc2a..59d94201 100644 --- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_InsertData.java +++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_InsertData.java @@ -59,7 +59,7 @@ public class SDKDemo_InsertData { // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; String commodityDataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; Commodity commodity1 = new Commodity(); - txTemp.dataAccount(commodityDataAccount).set("ASSET_CODE", commodity1.getCode().getBytes(), -1); + txTemp.dataAccount(commodityDataAccount).setText("ASSET_CODE", commodity1.getCode(), -1); // TX 准备就绪; PreparedTransaction prepTx = txTemp.prepare(); diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_BatchInsertData_Test_.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_BatchInsertData_Test_.java index 644bf609..747c835e 100644 --- a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_BatchInsertData_Test_.java +++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_BatchInsertData_Test_.java @@ -87,13 +87,13 @@ public class SDK_GateWay_BatchInsertData_Test_ { String dataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; String key1 = "jd_key1"; - byte[] val1 = "www.jd.com".getBytes(); + String val1 = "www.jd.com"; String key2 = "jd_key2"; - byte[] val2 = "www.jd.com".getBytes(); + String val2 = "www.jd.com"; - txTemp.dataAccount(dataAccount).set(key1, val1, -1); - txTemp.dataAccount(dataAccount).set(key2, val2, -1); + txTemp.dataAccount(dataAccount).setText(key1, val1, -1); + txTemp.dataAccount(dataAccount).setText(key2, val2, -1); // TX 准备就绪; PreparedTransaction prepTx = txTemp.prepare(); diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_InsertData_Test_.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_InsertData_Test_.java index 07dba29f..ed6567e9 100644 --- a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_InsertData_Test_.java +++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_InsertData_Test_.java @@ -84,9 +84,9 @@ public class SDK_GateWay_InsertData_Test_ { String dataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; String dataKey = "jd_code"; - byte[] dataVal = "www.jd.com".getBytes(); + String dataVal = "www.jd.com"; - txTemp.dataAccount(dataAccount).set(dataKey, dataVal, -1); + txTemp.dataAccount(dataAccount).setText(dataKey, dataVal, -1); // TX 准备就绪; PreparedTransaction prepTx = txTemp.prepare(); diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/IntegrationTest.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/IntegrationTest.java index fb64faec..f8899ec6 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/IntegrationTest.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/IntegrationTest.java @@ -23,6 +23,7 @@ import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; import com.jd.blockchain.ledger.AccountHeader; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.LedgerBlock; @@ -196,9 +197,9 @@ public class IntegrationTest { String dataAccount = dataAccountAddress; String dataKey = "jingdong" + new Random().nextInt(100000); - byte[] dataVal = "www.jd.com".getBytes(); + String dataVal = "www.jd.com"; - txTemp.dataAccount(dataAccount).set(dataKey, dataVal, -1); + txTemp.dataAccount(dataAccount).setText(dataKey, dataVal, -1); // TX 准备就绪; PreparedTransaction prepTx = txTemp.prepare(); @@ -637,11 +638,11 @@ public class IntegrationTest { // 注册数据账户,并验证最终写入; txTpl.dataAccounts().register(contractDataKey.getIdentity()); DataAccountKVSetOperation kvsetOP = txTpl.dataAccount(contractDataKey.getAddress()) - .set("A", "Value_A_0".getBytes(), -1).set("B", "Value_B_0".getBytes(), -1) - .set(KEY_TOTAL, "total value,dataAccount".getBytes(), -1) - .set(KEY_ABC, "abc value,dataAccount".getBytes(), -1) + .setText("A", "Value_A_0", -1).setText("B", "Value_B_0", -1) + .setText(KEY_TOTAL, "total value,dataAccount", -1) + .setText(KEY_ABC, "abc value,dataAccount", -1) // 所有的模拟数据都在这个dataAccount中填充; - .set("ledgerHash", ledgerHash.getRawDigest(), -1).getOperation(); + .setBytes("ledgerHash", ledgerHash.getRawDigest(), -1).getOperation(); // 签名; PreparedTransaction ptx = txTpl.prepare(); @@ -655,9 +656,9 @@ public class IntegrationTest { LedgerRepository ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); LedgerBlock block = ledgerOfNode0.getBlock(txResp.getBlockHeight()); - byte[] val1InDb = ledgerOfNode0.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) + BytesValue val1InDb = ledgerOfNode0.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) .getBytes("A"); - byte[] val2InDb = ledgerOfNode0.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) + BytesValue val2InDb = ledgerOfNode0.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) .getBytes(KEY_TOTAL); } diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java index bb567b9b..1e318f97 100644 --- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java +++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java @@ -16,9 +16,9 @@ import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.consensus.ConsensusProvider; import com.jd.blockchain.consensus.ConsensusProviders; import com.jd.blockchain.consensus.ConsensusSettings; -import com.jd.blockchain.crypto.CryptoAlgorithm; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoAlgorithm; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PrivKey; import com.jd.blockchain.ledger.BlockchainIdentity; @@ -54,7 +54,6 @@ import com.jd.blockchain.transaction.TxBuilder; import com.jd.blockchain.utils.ArgumentSet; import com.jd.blockchain.utils.ConsoleUtils; import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; -import com.jd.blockchain.utils.io.BytesUtils; import com.jd.blockchain.utils.io.FileUtils; import com.jd.blockchain.utils.net.NetworkAddress; @@ -408,8 +407,8 @@ public class LedgerPerformanceTest { // BlockchainKeyPair dataAccountKey = // BlockchainKeyGenerator.getInstance().generate(); BlockchainIdentity targetAccount = dataAccounts[count % dataAccounts.length]; - txbuilder.dataAccount(targetAccount.getAddress()).set("key-" + startTs + "-" + i, - BytesUtils.toBytes("value-" + i), -1L); + txbuilder.dataAccount(targetAccount.getAddress()).setText("key-" + startTs + "-" + i, + "value-" + i, -1L); TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); reqBuilder.signAsEndpoint(adminKey); txList.add(reqBuilder.buildRequest()); diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java index 17e6ad7f..c079b50e 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java @@ -43,7 +43,6 @@ import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.*; - /** * * @author shaozhuguang @@ -53,480 +52,484 @@ import static org.junit.Assert.*; public class IntegrationBase { - static { - DataContractRegistry.register(LedgerInitOperation.class); - DataContractRegistry.register(UserRegisterOperation.class); - } - - public static final String PASSWORD = "abc"; - - public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", - "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", - "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", - "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; - - public static final String[] PRIV_KEYS = { - "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", - "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", - "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", - "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; - - public static final AtomicLong validLong = new AtomicLong(); - - public static KeyPairResponse testSDK_RegisterUser(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService) { - // 注册用户,并验证最终写入; - BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); - - // 定义交易; - TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - txTpl.users().register(user.getIdentity()); - - // 签名; - PreparedTransaction ptx = txTpl.prepare(); - - HashDigest transactionHash = ptx.getHash(); + static { + DataContractRegistry.register(LedgerInitOperation.class); + DataContractRegistry.register(UserRegisterOperation.class); + } - ptx.sign(adminKey); + public static final String PASSWORD = "abc"; - // 提交并等待共识返回; - TransactionResponse txResp = ptx.commit(); + public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", + "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", + "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", + "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; - KeyPairResponse keyPairResponse = new KeyPairResponse(); - keyPairResponse.keyPair = user; - keyPairResponse.txResp = txResp; - keyPairResponse.txHash = transactionHash; - return keyPairResponse; - } + public static final String[] PRIV_KEYS = { + "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", + "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", + "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", + "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; - public static KeyPairResponse testSDK_RegisterDataAccount(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService) { - // 注册数据账户,并验证最终写入; - BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); + public static final AtomicLong validLong = new AtomicLong(); - // 定义交易; - TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - txTpl.dataAccounts().register(dataAccount.getIdentity()); + public static KeyPairResponse testSDK_RegisterUser(AsymmetricKeypair adminKey, HashDigest ledgerHash, + BlockchainService blockchainService) { + // 注册用户,并验证最终写入; + BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); - // 签名; - PreparedTransaction ptx = txTpl.prepare(); - - HashDigest transactionHash = ptx.getHash(); - - ptx.sign(adminKey); - - // 提交并等待共识返回; - TransactionResponse txResp = ptx.commit(); - - KeyPairResponse keyPairResponse = new KeyPairResponse(); - keyPairResponse.keyPair = dataAccount; - keyPairResponse.txResp = txResp; - keyPairResponse.txHash = transactionHash; - return keyPairResponse; - } - - public static KvResponse testSDK_InsertData(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, - Bytes dataAccount) { - - // 在本地定义注册账号的 TX; - TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); - - // -------------------------------------- - // 将商品信息写入到指定的账户中; - // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; - String dataKey = "jingdong" + System.currentTimeMillis() + new Random().nextInt(100000); - byte[] dataVal = "www.jd.com".getBytes(); - - txTemp.dataAccount(dataAccount).set(dataKey, dataVal, -1); - - // TX 准备就绪; - PreparedTransaction prepTx = txTemp.prepare(); - - HashDigest transactionHash = prepTx.getHash(); - - // 使用私钥进行签名; - prepTx.sign(adminKey); - - // 提交交易; - TransactionResponse txResp = prepTx.commit(); - - KvResponse kvResponse = new KvResponse(); - kvResponse.ledgerHash = ledgerHash; - kvResponse.dataAccount = dataAccount; - kvResponse.txResp = txResp; - kvResponse.txHash = transactionHash; - kvResponse.key = dataKey; - kvResponse.value = dataVal; - return kvResponse; - } - - - - public static void validKeyPair(IntegrationBase.KeyPairResponse keyPairResponse, LedgerRepository ledgerRepository, KeyPairType keyPairType) { - TransactionResponse txResp = keyPairResponse.txResp; - HashDigest transactionHash = keyPairResponse.txHash; - BlockchainKeypair keyPair = keyPairResponse.keyPair; - long index = validLong.incrementAndGet(); - System.out.printf("validKeyPair start %s \r\n", index); - ledgerRepository.retrieveLatestBlock(); - - assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); - assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); - assertEquals(txResp.getContentHash(), transactionHash); - assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); - if (keyPairType == KeyPairType.USER) { - assertTrue(ledgerRepository.getUserAccountSet(ledgerRepository.getLatestBlock()).contains(keyPair.getAddress())); - } - - if (keyPairType == KeyPairType.DATAACCOUNT) { - assertNotNull(ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) - .getDataAccount(keyPair.getAddress())); - } - System.out.printf("validKeyPair end %s \r\n", index); - } - - public static void validKeyPair(IntegrationBase.KeyPairResponse keyPairResponse, LedgerRepository ledgerRepository, KeyPairType keyPairType, CountDownLatch countDownLatch) { - - TransactionResponse txResp = keyPairResponse.txResp; - HashDigest transactionHash = keyPairResponse.txHash; - BlockchainKeypair keyPair = keyPairResponse.keyPair; - ledgerRepository.retrieveLatestBlock(); - - assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); - assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); - assertEquals(txResp.getContentHash(), transactionHash); - assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); - if (keyPairType == KeyPairType.USER) { - assertTrue(ledgerRepository.getUserAccountSet(ledgerRepository.getLatestBlock()).contains(keyPair.getAddress())); - } - - if (keyPairType == KeyPairType.DATAACCOUNT) { - assertNotNull(ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) - .getDataAccount(keyPair.getAddress())); - } - countDownLatch.countDown(); - } - - public static void validKvWrite(IntegrationBase.KvResponse kvResponse, LedgerRepository ledgerRepository, BlockchainService blockchainService) { - // 先验证应答 - TransactionResponse txResp = kvResponse.getTxResp(); - HashDigest transactionHash = kvResponse.getTxHash(); - HashDigest ledgerHash = kvResponse.getLedgerHash(); - String daAddress = kvResponse.getDataAccount().toBase58(); - String dataKey = kvResponse.getKey(); - byte[] dataVal = kvResponse.getValue(); - - ledgerRepository.retrieveLatestBlock(); - - assertEquals(TransactionState.SUCCESS, txResp.getExecutionState()); - assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); - assertEquals(txResp.getContentHash(), transactionHash); - assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); - - KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, daAddress, dataKey); - for (KVDataEntry kvDataEntry : kvDataEntries) { - assertEquals(dataKey, kvDataEntry.getKey()); - String valHexText = (String) kvDataEntry.getValue(); - byte[] valBytes = HexUtils.decode(valHexText); - boolean isEqual = Arrays.equals(dataVal, valBytes); - assertTrue(isEqual); - } - } - - - public static LedgerRepository[] buildLedgers(LedgerBindingConfig[] bindingConfigs, DbConnectionFactory[] dbConnectionFactories){ - int[] ids = {0, 1, 2, 3}; - LedgerRepository[] ledgers = new LedgerRepository[ids.length]; - LedgerManager[] ledgerManagers = new LedgerManager[ids.length]; - for (int i = 0; i < ids.length; i++) { - ledgerManagers[i] = new LedgerManager(); - HashDigest ledgerHash = bindingConfigs[0].getLedgerHashs()[0]; - DbConnection conn = dbConnectionFactories[i].connect(bindingConfigs[i].getLedger(ledgerHash).getDbConnection().getUri()); - ledgers[i] = ledgerManagers[i].register(ledgerHash, conn.getStorageService()); - } - return ledgers; - } - - public static void testConsistencyAmongNodes(LedgerRepository[] ledgers) { - LedgerRepository ledger0 = ledgers[0]; - LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); - for (int i = 1; i < ledgers.length; i++) { - LedgerRepository otherLedger = ledgers[i]; - LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); - assertEquals(ledger0.getHash(), otherLedger.getHash()); - assertEquals(ledger0.getLatestBlockHeight(), otherLedger.getLatestBlockHeight()); - assertEquals(ledger0.getLatestBlockHash(), otherLedger.getLatestBlockHash()); - - assertEquals(latestBlock0.getHeight(), otherLatestBlock.getHeight()); - assertEquals(latestBlock0.getHash(), otherLatestBlock.getHash()); - assertEquals(latestBlock0.getAdminAccountHash(), otherLatestBlock.getAdminAccountHash()); - assertEquals(latestBlock0.getTransactionSetHash(), otherLatestBlock.getTransactionSetHash()); - assertEquals(latestBlock0.getUserAccountSetHash(), otherLatestBlock.getUserAccountSetHash()); - assertEquals(latestBlock0.getDataAccountSetHash(), otherLatestBlock.getDataAccountSetHash()); - assertEquals(latestBlock0.getContractAccountSetHash(), otherLatestBlock.getContractAccountSetHash()); - assertEquals(latestBlock0.getPreviousHash(), otherLatestBlock.getPreviousHash()); - } - } - - public static PeerTestRunner[] peerNodeStart(HashDigest ledgerHash, String dbType) { - NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 12000); - LedgerBindingConfig bindingConfig0 = loadBindingConfig(0, ledgerHash, dbType); - PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, bindingConfig0); - - NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 12010); - LedgerBindingConfig bindingConfig1 = loadBindingConfig(1, ledgerHash, dbType); - PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, bindingConfig1); - - NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 12020); - LedgerBindingConfig bindingConfig2 = loadBindingConfig(2, ledgerHash, dbType); - PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, bindingConfig2); - - NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 12030); - LedgerBindingConfig bindingConfig3 = loadBindingConfig(3, ledgerHash, dbType); - PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, bindingConfig3); - - ThreadInvoker.AsyncCallback peerStarting0 = peer0.start(); - ThreadInvoker.AsyncCallback peerStarting1 = peer1.start(); - ThreadInvoker.AsyncCallback peerStarting2 = peer2.start(); - ThreadInvoker.AsyncCallback peerStarting3 = peer3.start(); - - peerStarting0.waitReturn(); - peerStarting1.waitReturn(); - peerStarting2.waitReturn(); - peerStarting3.waitReturn(); - - return new PeerTestRunner[]{peer0, peer1, peer2, peer3}; - } - - public static LedgerBindingConfig loadBindingConfig(int id, HashDigest ledgerHash, String dbType) { - LedgerBindingConfig ledgerBindingConfig; - String newLedger = ledgerHash.toBase58(); - String resourceClassPath = "ledger-binding-" + dbType + "-" + id + ".conf"; - String ledgerBindingUrl = IntegrationBase.class.getResource("/") + resourceClassPath; - - try { - URL url = new URL(ledgerBindingUrl); - File ledgerBindingConf = new File(url.getPath()); - System.out.printf("URL-ledgerBindingConf = %s \r\n", url.getPath()); - if (ledgerBindingConf.exists()) { - List readLines = FileUtils.readLines(ledgerBindingConf); - - List writeLines = new ArrayList<>(); - - if (readLines != null && !readLines.isEmpty()) { - String oldLedgerLine = null; - for (String readLine : readLines) { - if (readLine.startsWith("ledger")) { - oldLedgerLine = readLine; - break; - } - } - String[] oldLedgerArray = oldLedgerLine.split("="); - - String oldLedger = oldLedgerArray[1]; - if (!oldLedger.equalsIgnoreCase(newLedger)) { - for (String readLine : readLines) { - String newLine = readLine.replace(oldLedger, newLedger); - if (dbType.equalsIgnoreCase("rocksdb")) { - if (newLine.contains("db.uri")) { - String[] propArray = newLine.split("="); - String dbKey = propArray[0]; - String dbValue = LedgerInitConsensusConfig.rocksdbConnectionStrings[id]; - newLine = dbKey + "=" + dbValue; - } - } - writeLines.add(newLine); - } - } else if(dbType.equalsIgnoreCase("rocksdb")) { - for (String readLine : readLines) { - String newLine = readLine; - if (readLine.contains("db.uri")) { - String[] propArray = readLine.split("="); - String dbKey = propArray[0]; - String dbValue = LedgerInitConsensusConfig.rocksdbConnectionStrings[id]; - newLine = dbKey + "=" + dbValue; - } - writeLines.add(newLine); - } - } - if (!writeLines.isEmpty()) { - FileUtils.writeLines(ledgerBindingConf, writeLines); - } - } - } - } catch (Exception e) { - - } - - ClassPathResource res = new ClassPathResource(resourceClassPath); - try(InputStream in = res.getInputStream()){ - ledgerBindingConfig = LedgerBindingConfig.resolve(in); - } catch (IOException e) { - throw new IllegalStateException(e.getMessage(), e); - } - return ledgerBindingConfig; - } - - public static class KeyPairResponse { - HashDigest txHash; - - BlockchainKeypair keyPair; - - TransactionResponse txResp; - - public BlockchainKeypair getKeyPair() { - return keyPair; - } - - public TransactionResponse getTxResp() { - return txResp; - } - - public HashDigest getTxHash() { - return txHash; - } - } - - public static class KvResponse { - - Bytes dataAccount; - - HashDigest ledgerHash; - - HashDigest txHash; - - TransactionResponse txResp; - - String key; - - byte[] value; - - public HashDigest getTxHash() { - return txHash; - } - - public TransactionResponse getTxResp() { - return txResp; - } - - public String getKey() { - return key; - } - - public byte[] getValue() { - return value; - } - - public HashDigest getLedgerHash() { - return ledgerHash; - } - - public Bytes getDataAccount() { - return dataAccount; - } - } - - public enum KeyPairType { - USER, - DATAACCOUNT - } - - // 合约测试使用的初始化数据; - BlockchainKeypair contractDataKey = BlockchainKeyGenerator.getInstance().generate(); - BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate(); - // 保存资产总数的键; - private static final String KEY_TOTAL = "TOTAL"; - // 第二个参数; - private static final String KEY_ABC = "abc"; - private String contractZipName = "Example1.jar"; - HashDigest txContentHash; - String pubKeyVal = "jd.com"+System.currentTimeMillis(); - private String eventName = "issue-asset"; - public LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, - BlockchainService blockchainService,LedgerRepository ledgerRepository) { - System.out.println("adminKey="+ AddressEncoding.generateAddress(adminKey.getPubKey())); - BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); - System.out.println("userKey="+userKey.getAddress()); - TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - txTpl.users().register(userKey.getIdentity()); - - // 定义交易; - byte[] contractCode = getChainCodeBytes(); - txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); - - // 签名; - PreparedTransaction ptx = txTpl.prepare(); - ptx.sign(adminKey); - - // 提交并等待共识返回; - TransactionResponse txResp = ptx.commit(); - assertTrue(txResp.isSuccess()); - - // 验证结果; - txResp.getContentHash(); - - LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); - byte[] contractCodeInDb = ledgerRepository.getContractAccountSet(block).getContract(contractDeployKey.getAddress()) - .getChainCode(); - assertArrayEquals(contractCode, contractCodeInDb); - txContentHash = ptx.getHash(); - - // execute the contract; - testContractExe(adminKey, ledgerHash, userKey, blockchainService, ledgerRepository); - - return block; - } - - private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, - BlockchainService blockchainService,LedgerRepository ledgerRepository) { - LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); - LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); - - // 定义交易; - TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - - txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, - ("888##123##" + contractDataKey.getAddress()).getBytes()); - - // 签名; - PreparedTransaction ptx = txTpl.prepare(); - ptx.sign(adminKey); - - // 提交并等待共识返回; - TransactionResponse txResp = ptx.commit(); - - // 验证结果; - txResp.getContentHash(); - Assert.assertTrue(txResp.isSuccess()); - } - - /** - * 根据合约构建字节数组; - * - * @return - */ - private byte[] getChainCodeBytes() { - // 构建合约的字节数组; - byte[] contractCode = null; - File file = null; - InputStream input = null; - try { - ClassPathResource contractPath = new ClassPathResource(contractZipName); - file = new File(contractPath.getURI()); - assertTrue("contract zip file is not exist.", file.exists() == true); - input = new FileInputStream(file); - // 这种暴力的读取压缩包,在class解析时有问题,所有需要改进; - contractCode = new byte[input.available()]; - input.read(contractCode); - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - if (input != null) { - input.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - return contractCode; - } + // 定义交易; + TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); + txTpl.users().register(user.getIdentity()); + + // 签名; + PreparedTransaction ptx = txTpl.prepare(); + + HashDigest transactionHash = ptx.getHash(); + + ptx.sign(adminKey); + + // 提交并等待共识返回; + TransactionResponse txResp = ptx.commit(); + + KeyPairResponse keyPairResponse = new KeyPairResponse(); + keyPairResponse.keyPair = user; + keyPairResponse.txResp = txResp; + keyPairResponse.txHash = transactionHash; + return keyPairResponse; + } + + public static KeyPairResponse testSDK_RegisterDataAccount(AsymmetricKeypair adminKey, HashDigest ledgerHash, + BlockchainService blockchainService) { + // 注册数据账户,并验证最终写入; + BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); + + // 定义交易; + TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); + txTpl.dataAccounts().register(dataAccount.getIdentity()); + + // 签名; + PreparedTransaction ptx = txTpl.prepare(); + + HashDigest transactionHash = ptx.getHash(); + + ptx.sign(adminKey); + + // 提交并等待共识返回; + TransactionResponse txResp = ptx.commit(); + + KeyPairResponse keyPairResponse = new KeyPairResponse(); + keyPairResponse.keyPair = dataAccount; + keyPairResponse.txResp = txResp; + keyPairResponse.txHash = transactionHash; + return keyPairResponse; + } + + public static KvResponse testSDK_InsertData(AsymmetricKeypair adminKey, HashDigest ledgerHash, + BlockchainService blockchainService, Bytes dataAccount) { + + // 在本地定义注册账号的 TX; + TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); + + // -------------------------------------- + // 将商品信息写入到指定的账户中; + // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; + String dataKey = "jingdong" + System.currentTimeMillis() + new Random().nextInt(100000); + String dataVal = "www.jd.com"; + + txTemp.dataAccount(dataAccount).setText(dataKey, dataVal, -1); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + + HashDigest transactionHash = prepTx.getHash(); + + // 使用私钥进行签名; + prepTx.sign(adminKey); + + // 提交交易; + TransactionResponse txResp = prepTx.commit(); + + KvResponse kvResponse = new KvResponse(); + kvResponse.ledgerHash = ledgerHash; + kvResponse.dataAccount = dataAccount; + kvResponse.txResp = txResp; + kvResponse.txHash = transactionHash; + kvResponse.key = dataKey; + kvResponse.value = dataVal; + return kvResponse; + } + + public static void validKeyPair(IntegrationBase.KeyPairResponse keyPairResponse, LedgerRepository ledgerRepository, + KeyPairType keyPairType) { + TransactionResponse txResp = keyPairResponse.txResp; + HashDigest transactionHash = keyPairResponse.txHash; + BlockchainKeypair keyPair = keyPairResponse.keyPair; + long index = validLong.incrementAndGet(); + System.out.printf("validKeyPair start %s \r\n", index); + ledgerRepository.retrieveLatestBlock(); + + assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); + assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); + assertEquals(txResp.getContentHash(), transactionHash); + assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); + if (keyPairType == KeyPairType.USER) { + assertTrue(ledgerRepository.getUserAccountSet(ledgerRepository.getLatestBlock()) + .contains(keyPair.getAddress())); + } + + if (keyPairType == KeyPairType.DATAACCOUNT) { + assertNotNull(ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) + .getDataAccount(keyPair.getAddress())); + } + System.out.printf("validKeyPair end %s \r\n", index); + } + + public static void validKeyPair(IntegrationBase.KeyPairResponse keyPairResponse, LedgerRepository ledgerRepository, + KeyPairType keyPairType, CountDownLatch countDownLatch) { + + TransactionResponse txResp = keyPairResponse.txResp; + HashDigest transactionHash = keyPairResponse.txHash; + BlockchainKeypair keyPair = keyPairResponse.keyPair; + ledgerRepository.retrieveLatestBlock(); + + assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); + assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); + assertEquals(txResp.getContentHash(), transactionHash); + assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); + if (keyPairType == KeyPairType.USER) { + assertTrue(ledgerRepository.getUserAccountSet(ledgerRepository.getLatestBlock()) + .contains(keyPair.getAddress())); + } + + if (keyPairType == KeyPairType.DATAACCOUNT) { + assertNotNull(ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) + .getDataAccount(keyPair.getAddress())); + } + countDownLatch.countDown(); + } + + public static void validKvWrite(IntegrationBase.KvResponse kvResponse, LedgerRepository ledgerRepository, + BlockchainService blockchainService) { + // 先验证应答 + TransactionResponse txResp = kvResponse.getTxResp(); + HashDigest transactionHash = kvResponse.getTxHash(); + HashDigest ledgerHash = kvResponse.getLedgerHash(); + String daAddress = kvResponse.getDataAccount().toBase58(); + String dataKey = kvResponse.getKey(); + String dataVal = kvResponse.getValue(); + + ledgerRepository.retrieveLatestBlock(); + + assertEquals(TransactionState.SUCCESS, txResp.getExecutionState()); + assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); + assertEquals(txResp.getContentHash(), transactionHash); + assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); + + KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, daAddress, dataKey); + for (KVDataEntry kvDataEntry : kvDataEntries) { + assertEquals(dataKey, kvDataEntry.getKey()); + String valHexText = (String) kvDataEntry.getValue(); + assertEquals(dataVal, valHexText); + } + } + + public static LedgerRepository[] buildLedgers(LedgerBindingConfig[] bindingConfigs, + DbConnectionFactory[] dbConnectionFactories) { + int[] ids = { 0, 1, 2, 3 }; + LedgerRepository[] ledgers = new LedgerRepository[ids.length]; + LedgerManager[] ledgerManagers = new LedgerManager[ids.length]; + for (int i = 0; i < ids.length; i++) { + ledgerManagers[i] = new LedgerManager(); + HashDigest ledgerHash = bindingConfigs[0].getLedgerHashs()[0]; + DbConnection conn = dbConnectionFactories[i] + .connect(bindingConfigs[i].getLedger(ledgerHash).getDbConnection().getUri()); + ledgers[i] = ledgerManagers[i].register(ledgerHash, conn.getStorageService()); + } + return ledgers; + } + + public static void testConsistencyAmongNodes(LedgerRepository[] ledgers) { + LedgerRepository ledger0 = ledgers[0]; + LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); + for (int i = 1; i < ledgers.length; i++) { + LedgerRepository otherLedger = ledgers[i]; + LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); + assertEquals(ledger0.getHash(), otherLedger.getHash()); + assertEquals(ledger0.getLatestBlockHeight(), otherLedger.getLatestBlockHeight()); + assertEquals(ledger0.getLatestBlockHash(), otherLedger.getLatestBlockHash()); + + assertEquals(latestBlock0.getHeight(), otherLatestBlock.getHeight()); + assertEquals(latestBlock0.getHash(), otherLatestBlock.getHash()); + assertEquals(latestBlock0.getAdminAccountHash(), otherLatestBlock.getAdminAccountHash()); + assertEquals(latestBlock0.getTransactionSetHash(), otherLatestBlock.getTransactionSetHash()); + assertEquals(latestBlock0.getUserAccountSetHash(), otherLatestBlock.getUserAccountSetHash()); + assertEquals(latestBlock0.getDataAccountSetHash(), otherLatestBlock.getDataAccountSetHash()); + assertEquals(latestBlock0.getContractAccountSetHash(), otherLatestBlock.getContractAccountSetHash()); + assertEquals(latestBlock0.getPreviousHash(), otherLatestBlock.getPreviousHash()); + } + } + + public static PeerTestRunner[] peerNodeStart(HashDigest ledgerHash, String dbType) { + NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 12000); + LedgerBindingConfig bindingConfig0 = loadBindingConfig(0, ledgerHash, dbType); + PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, bindingConfig0); + + NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 12010); + LedgerBindingConfig bindingConfig1 = loadBindingConfig(1, ledgerHash, dbType); + PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, bindingConfig1); + + NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 12020); + LedgerBindingConfig bindingConfig2 = loadBindingConfig(2, ledgerHash, dbType); + PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, bindingConfig2); + + NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 12030); + LedgerBindingConfig bindingConfig3 = loadBindingConfig(3, ledgerHash, dbType); + PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, bindingConfig3); + + ThreadInvoker.AsyncCallback peerStarting0 = peer0.start(); + ThreadInvoker.AsyncCallback peerStarting1 = peer1.start(); + ThreadInvoker.AsyncCallback peerStarting2 = peer2.start(); + ThreadInvoker.AsyncCallback peerStarting3 = peer3.start(); + + peerStarting0.waitReturn(); + peerStarting1.waitReturn(); + peerStarting2.waitReturn(); + peerStarting3.waitReturn(); + + return new PeerTestRunner[] { peer0, peer1, peer2, peer3 }; + } + + public static LedgerBindingConfig loadBindingConfig(int id, HashDigest ledgerHash, String dbType) { + LedgerBindingConfig ledgerBindingConfig; + String newLedger = ledgerHash.toBase58(); + String resourceClassPath = "ledger-binding-" + dbType + "-" + id + ".conf"; + String ledgerBindingUrl = IntegrationBase.class.getResource("/") + resourceClassPath; + + try { + URL url = new URL(ledgerBindingUrl); + File ledgerBindingConf = new File(url.getPath()); + System.out.printf("URL-ledgerBindingConf = %s \r\n", url.getPath()); + if (ledgerBindingConf.exists()) { + List readLines = FileUtils.readLines(ledgerBindingConf); + + List writeLines = new ArrayList<>(); + + if (readLines != null && !readLines.isEmpty()) { + String oldLedgerLine = null; + for (String readLine : readLines) { + if (readLine.startsWith("ledger")) { + oldLedgerLine = readLine; + break; + } + } + String[] oldLedgerArray = oldLedgerLine.split("="); + + String oldLedger = oldLedgerArray[1]; + if (!oldLedger.equalsIgnoreCase(newLedger)) { + for (String readLine : readLines) { + String newLine = readLine.replace(oldLedger, newLedger); + if (dbType.equalsIgnoreCase("rocksdb")) { + if (newLine.contains("db.uri")) { + String[] propArray = newLine.split("="); + String dbKey = propArray[0]; + String dbValue = LedgerInitConsensusConfig.rocksdbConnectionStrings[id]; + newLine = dbKey + "=" + dbValue; + } + } + writeLines.add(newLine); + } + } else if (dbType.equalsIgnoreCase("rocksdb")) { + for (String readLine : readLines) { + String newLine = readLine; + if (readLine.contains("db.uri")) { + String[] propArray = readLine.split("="); + String dbKey = propArray[0]; + String dbValue = LedgerInitConsensusConfig.rocksdbConnectionStrings[id]; + newLine = dbKey + "=" + dbValue; + } + writeLines.add(newLine); + } + } + if (!writeLines.isEmpty()) { + FileUtils.writeLines(ledgerBindingConf, writeLines); + } + } + } + } catch (Exception e) { + + } + + ClassPathResource res = new ClassPathResource(resourceClassPath); + try (InputStream in = res.getInputStream()) { + ledgerBindingConfig = LedgerBindingConfig.resolve(in); + } catch (IOException e) { + throw new IllegalStateException(e.getMessage(), e); + } + return ledgerBindingConfig; + } + + public static class KeyPairResponse { + HashDigest txHash; + + BlockchainKeypair keyPair; + + TransactionResponse txResp; + + public BlockchainKeypair getKeyPair() { + return keyPair; + } + + public TransactionResponse getTxResp() { + return txResp; + } + + public HashDigest getTxHash() { + return txHash; + } + } + + public static class KvResponse { + + Bytes dataAccount; + + HashDigest ledgerHash; + + HashDigest txHash; + + TransactionResponse txResp; + + String key; + + String value; + + public HashDigest getTxHash() { + return txHash; + } + + public TransactionResponse getTxResp() { + return txResp; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + + public HashDigest getLedgerHash() { + return ledgerHash; + } + + public Bytes getDataAccount() { + return dataAccount; + } + } + + public enum KeyPairType { + USER, DATAACCOUNT + } + + // 合约测试使用的初始化数据; + BlockchainKeypair contractDataKey = BlockchainKeyGenerator.getInstance().generate(); + BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate(); + // 保存资产总数的键; + private static final String KEY_TOTAL = "TOTAL"; + // 第二个参数; + private static final String KEY_ABC = "abc"; + private String contractZipName = "Example1.jar"; + HashDigest txContentHash; + String pubKeyVal = "jd.com" + System.currentTimeMillis(); + private String eventName = "issue-asset"; + + public LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, + BlockchainService blockchainService, LedgerRepository ledgerRepository) { + System.out.println("adminKey=" + AddressEncoding.generateAddress(adminKey.getPubKey())); + BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); + System.out.println("userKey=" + userKey.getAddress()); + TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); + txTpl.users().register(userKey.getIdentity()); + + // 定义交易; + byte[] contractCode = getChainCodeBytes(); + txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); + + // 签名; + PreparedTransaction ptx = txTpl.prepare(); + ptx.sign(adminKey); + + // 提交并等待共识返回; + TransactionResponse txResp = ptx.commit(); + assertTrue(txResp.isSuccess()); + + // 验证结果; + txResp.getContentHash(); + + LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); + byte[] contractCodeInDb = ledgerRepository.getContractAccountSet(block) + .getContract(contractDeployKey.getAddress()).getChainCode(); + assertArrayEquals(contractCode, contractCodeInDb); + txContentHash = ptx.getHash(); + + // execute the contract; + testContractExe(adminKey, ledgerHash, userKey, blockchainService, ledgerRepository); + + return block; + } + + private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, + BlockchainService blockchainService, LedgerRepository ledgerRepository) { + LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); + LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); + + // 定义交易; + TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); + + txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, + ("888##123##" + contractDataKey.getAddress()).getBytes()); + + // 签名; + PreparedTransaction ptx = txTpl.prepare(); + ptx.sign(adminKey); + + // 提交并等待共识返回; + TransactionResponse txResp = ptx.commit(); + + // 验证结果; + txResp.getContentHash(); + Assert.assertTrue(txResp.isSuccess()); + } + + /** + * 根据合约构建字节数组; + * + * @return + */ + private byte[] getChainCodeBytes() { + // 构建合约的字节数组; + byte[] contractCode = null; + File file = null; + InputStream input = null; + try { + ClassPathResource contractPath = new ClassPathResource(contractZipName); + file = new File(contractPath.getURI()); + assertTrue("contract zip file is not exist.", file.exists() == true); + input = new FileInputStream(file); + // 这种暴力的读取压缩包,在class解析时有问题,所有需要改进; + contractCode = new byte[input.available()]; + input.read(contractCode); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (input != null) { + input.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return contractCode; + } } \ No newline at end of file diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestAll4Redis.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestAll4Redis.java index 1396f0c5..04915f52 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestAll4Redis.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestAll4Redis.java @@ -23,6 +23,7 @@ import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.LedgerBlock; @@ -219,9 +220,9 @@ public class IntegrationTestAll4Redis { txTpl.dataAccounts().register(dataKey.getIdentity()); // add kv ops for data account - DataAccountKVSetOperation dataKvsetOP = txTpl.dataAccount(dataKey.getAddress()) - .set("A", "Value_A_0".getBytes(), -1).set("B", "Value_B_0".getBytes(), -1) - .set("C", "Value_C_0".getBytes(), -1).set("D", "Value_D_0".getBytes(), -1).getOperation(); + DataAccountKVSetOperation dataKvsetOP = txTpl.dataAccount(dataKey.getAddress()).setText("A", "Value_A_0", -1) + .setText("B", "Value_B_0", -1).setText("C", "Value_C_0", -1).setText("D", "Value_D_0", -1) + .getOperation(); // 签名; PreparedTransaction ptx = txTpl.prepare(); @@ -233,18 +234,14 @@ public class IntegrationTestAll4Redis { assertTrue(txResp.isSuccess()); assertEquals(ledgerRepository.retrieveLatestBlockHeight(), txResp.getBlockHeight()); - assertArrayEquals("Value_A_0".getBytes(), - ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getDataAccount(dataKey.getAddress()).getBytes("A")); - assertArrayEquals("Value_B_0".getBytes(), - ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getDataAccount(dataKey.getAddress()).getBytes("B")); - assertArrayEquals("Value_C_0".getBytes(), - ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getDataAccount(dataKey.getAddress()).getBytes("C")); - assertArrayEquals("Value_D_0".getBytes(), - ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getDataAccount(dataKey.getAddress()).getBytes("D")); + assertEquals("Value_A_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) + .getDataAccount(dataKey.getAddress()).getBytes("A").getValue().toUTF8String()); + assertEquals("Value_B_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) + .getDataAccount(dataKey.getAddress()).getBytes("B").getValue().toUTF8String()); + assertEquals("Value_C_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) + .getDataAccount(dataKey.getAddress()).getBytes("C").getValue().toUTF8String()); + assertEquals("Value_D_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) + .getDataAccount(dataKey.getAddress()).getBytes("D").getValue().toUTF8String()); assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) .getDataAccount(dataKey.getAddress()).getDataVersion("A")); assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) @@ -271,8 +268,8 @@ public class IntegrationTestAll4Redis { } - private void testSDK_InsertData(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, - Bytes dataAccountAddress, LedgerRepository ledgerRepository) { + private void testSDK_InsertData(AsymmetricKeypair adminKey, HashDigest ledgerHash, + BlockchainService blockchainService, Bytes dataAccountAddress, LedgerRepository ledgerRepository) { // 在本地定义注册账号的 TX; TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); @@ -283,9 +280,9 @@ public class IntegrationTestAll4Redis { Bytes dataAccount = dataAccountAddress; String dataKey = "jingdong" + new Random().nextInt(100000); - byte[] dataVal = "www.jd.com".getBytes(); + String dataVal = "www.jd.com"; - txTemp.dataAccount(dataAccount).set(dataKey, dataVal, -1); + txTemp.dataAccount(dataAccount).setText(dataKey, dataVal, -1); // TX 准备就绪; PreparedTransaction prepTx = txTemp.prepare(); @@ -410,11 +407,10 @@ public class IntegrationTestAll4Redis { .getDataAccount(contractDataKey.getAddress()); DataAccountKVSetOperation kvsetOP = txTpl.dataAccount(contractDataKey.getAddress()) - .set("A", "Value_A_0".getBytes(), -1).set("B", "Value_B_0".getBytes(), -1) - .set(KEY_TOTAL, "total value,dataAccount".getBytes(), -1) - .set(KEY_ABC, "abc value,dataAccount".getBytes(), -1) + .setText("A", "Value_A_0", -1).setText("B", "Value_B_0", -1) + .setText(KEY_TOTAL, "total value,dataAccount", -1).setText(KEY_ABC, "abc value,dataAccount", -1) // 所有的模拟数据都在这个dataAccount中填充; - .set("ledgerHash", ledgerHash.getRawDigest(), -1).getOperation(); + .setBytes("ledgerHash", ledgerHash.getRawDigest(), -1).getOperation(); byte[] contractCode = getChainCodeBytes(); txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); @@ -478,7 +474,8 @@ public class IntegrationTestAll4Redis { PubKey pubKey = key.getPubKey(); Bytes dataAddress = AddressEncoding.generateAddress(pubKey); assertEquals(dataAddress, dataAccountSet.getDataAccount(dataAddress).getAddress()); - assertEquals("hello", new String(dataAccountSet.getDataAccount(dataAddress).getBytes(KEY_TOTAL, -1))); + assertEquals("hello", + dataAccountSet.getDataAccount(dataAddress).getBytes(KEY_TOTAL, -1).getValue().toUTF8String()); // 验证userAccount,从合约内部赋值,然后外部验证;内部定义动态key,外部不便于得到,临时屏蔽; // UserAccountSet userAccountSet = @@ -489,8 +486,8 @@ public class IntegrationTestAll4Redis { // assertEquals(userAddress, userAccountSet.getUser(userAddress).getAddress()); } - private void prepareContractData(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, - LedgerRepository ledgerRepository) { + private void prepareContractData(AsymmetricKeypair adminKey, HashDigest ledgerHash, + BlockchainService blockchainService, LedgerRepository ledgerRepository) { // 定义交易; TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); @@ -505,12 +502,12 @@ public class IntegrationTestAll4Redis { // 验证结果; LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); - byte[] val1InDb = ledgerRepository.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) + BytesValue val1InDb = ledgerRepository.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) .getBytes("A"); - byte[] val2InDb = ledgerRepository.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) + BytesValue val2InDb = ledgerRepository.getDataAccountSet(block).getDataAccount(contractDataKey.getAddress()) .getBytes(KEY_TOTAL); - assertArrayEquals("Value_A_0".getBytes(), val1InDb); - assertArrayEquals("total value,dataAccount".getBytes(), val2InDb); + assertEquals("Value_A_0", val1InDb.getValue().toUTF8String()); + assertEquals("total value,dataAccount", val2InDb.getValue().toUTF8String()); } /** diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java index e7bf18c5..e031d763 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTestDataAccount.java @@ -196,7 +196,7 @@ public class IntegrationTestDataAccount { JsonTest jsonTest = new JsonTest("Jack"); // // //add kv ops for data account: Bytes, string, long, json string - DataAccountKVSetOperation dataKvsetOP = txTpl.dataAccount(dataAddr).set("A", "Value_A_0".getBytes(), -1) + DataAccountKVSetOperation dataKvsetOP = txTpl.dataAccount(dataAddr).setText("A", "Value_A_0", -1) .setText("B", "Value_B_0", -1).setInt64("C", currentTime, -1).setText("D", JSON.toJSONString(jsonTest), -1) .getOperation(); diff --git a/source/tools/tools-capability/src/main/java/com/jd/blockchain/capability/service/RemoteTransactionService.java b/source/tools/tools-capability/src/main/java/com/jd/blockchain/capability/service/RemoteTransactionService.java index f45ca863..6ddd5b0f 100644 --- a/source/tools/tools-capability/src/main/java/com/jd/blockchain/capability/service/RemoteTransactionService.java +++ b/source/tools/tools-capability/src/main/java/com/jd/blockchain/capability/service/RemoteTransactionService.java @@ -42,321 +42,323 @@ import com.jd.blockchain.utils.io.BytesUtils; public class RemoteTransactionService { - private MsgQueueProducer txProducer; - - private final ExecutorService instanceFactory = Executors.newSingleThreadExecutor(); - - private final ArrayBlockingQueue> txBlockingQueue = new ArrayBlockingQueue(1); - - private final LinkedList dataAccountAddress = new LinkedList<>(); - - private Bytes defaultDataAccount; - - private static final AtomicLong keyPrefix = new AtomicLong(); - - public void userRegister(int count) throws Exception { - initTxProducer(); - int loop = 0; - if (count <= 0) { - userCreate(); - } else { - loop = count / CapabilitySettings.TX_SIZE_PER_SEND; - userCreate(loop); - } - // 从队列中获取数据 - if (count <= 0) { - for (;;) { - txRequestSend(); - } - } else { - for (int i = 0; i < loop; i++) { - txRequestSend(); - } - } - closeTxProducer(); - } - - public void dataAccountRegister(int count) throws Exception { - initTxProducer(); - int loop = 0; - if (count <= 0) { - dataAccountCreate(); - } else { - loop = count / CapabilitySettings.TX_SIZE_PER_SEND; - dataAccountCreate(loop); - } - // 从队列中获取数据 - if (count <= 0) { - for (;;) { - txRequestSend(); - } - } else { - for (int i = 0; i < loop; i++) { - txRequestSend(); - } - } - closeTxProducer(); - } - - public void userAndDataAccountRegister(int userCount, int dataAccountCount) throws Exception { - if (userCount <= 0 || dataAccountCount <= 0) { - throw new IllegalArgumentException("userCount and dataAccountCount can not be 0!!!"); - } - initTxProducer(); - int userLoop = userCount / CapabilitySettings.TX_SIZE_PER_SEND; - int dataAccountLoop = dataAccountCount / CapabilitySettings.TX_SIZE_PER_SEND; - userCreate(userLoop); - dataAccountCreate(dataAccountLoop); - for (int i = 0, totalLoop = userLoop + dataAccountCount; i < totalLoop; i++) { - txRequestSend(); - } - closeTxProducer(); - } - - public void dataAccountRegisterAndKvStorage(int dataAccountCount, int kvCount) throws Exception { - if (kvCount <= 0 || dataAccountCount <= 0) { - throw new IllegalArgumentException("userCount and dataAccountCount can not be 0!!!"); - } - initTxProducer(); - int dataAccountLoop = dataAccountCount / CapabilitySettings.TX_SIZE_PER_SEND; - dataAccountCreate(dataAccountLoop); - // 首先将数据账户写入 - for (int i = 0; i < dataAccountLoop; i++) { - txRequestSend(); - } - int kvLoop = kvCount / CapabilitySettings.TX_SIZE_PER_SEND; - // 然后将每个数据账户都写入指定数量的kv - Iterator iterator = dataAccountAddress.iterator(); - while(iterator.hasNext()){ - Bytes address = iterator.next(); - kvStorageCreate(kvCount, address); - } - for (int i = 0, loop = kvLoop * dataAccountCount; i < loop; i++) { - txRequestSend(); - } - - closeTxProducer(); - } - - public void kvStorage(int kvCount) throws Exception { - initTxProducer(); - - dataAccountDefaultCreate(); - try { - txRequestSend(); - // 确认结块成功 - Thread.sleep(10000); - } catch (Exception e) { - throw e; - } - int kvLoop = kvCount / CapabilitySettings.TX_SIZE_PER_SEND; - // 然后将每个数据账户都写入指定数量的kv - Bytes address = defaultDataAccount; - kvStorageCreate(kvLoop, address); - for (int i = 0; i < kvLoop; i++) { - txRequestSend(); - } - - closeTxProducer(); - } - - - - private void txRequestSend() throws Exception { - List txRequests = txBlockingQueue.take(); - if (txRequests != null && !txRequests.isEmpty()) { - Iterator iterator = txRequests.iterator(); - while(iterator.hasNext()){ - byte[] txRequest = iterator.next(); - try { - txProducer.publish(txRequest); - } catch (Exception e) { - e.printStackTrace(); - } - } - ConsoleUtils.info("[*] Transaction Request send success!!!"); - } - } - - private void initTxProducer() throws Exception { - txProducer = MsgQueueFactory.newProducer(CapabilitySettings.MSG_QUEUE_URL, CapabilitySettings.TX_TOPIC); - txProducer.connect(); - ConsoleUtils.info("[*] Transaction Producer start success!!!"); - } - - private void closeTxProducer() throws Exception{ - txProducer.close(); - } - - private void userCreate(int loop) { - instanceFactory.execute(() -> { - for (int index = 0; index < loop; index++) { - // 每次生产10000个,然后放入队列中 - try { - LinkedList txSerializeBytes = userActiveCreate(); - txBlockingQueue.put(txSerializeBytes); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - } - - private void userCreate() { - // 一直在生产用户 - instanceFactory.execute(() -> { - for (;;) { - // 每次生产10000个,然后放入队列中 - try { - LinkedList txSerializeBytes = userActiveCreate(); - txBlockingQueue.put(txSerializeBytes); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - } - - - private void dataAccountCreate(int loop) { - dataAccountCreate(loop, false); - } - - private void dataAccountCreate(int loop, final boolean isSave) { - instanceFactory.execute(() -> { - for (int index = 0; index < loop; index++) { - // 每次生产10000个,然后放入队列中 - try { - LinkedList txSerializeBytes = dataAccountActiveCreate(isSave); - txBlockingQueue.put(txSerializeBytes); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - } - - private void dataAccountDefaultCreate() { - instanceFactory.execute(() -> { - List currentBytes = new ArrayList<>(); - TransactionRequest txRequest = dataAccountRegisterRequest(CapabilitySettings.ledgerHash, CapabilitySettings.adminKey); - byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); - currentBytes.add(serializeBytes); - try { - txBlockingQueue.put(currentBytes); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } - - private void dataAccountCreate() { - // 一直在生产用户 - instanceFactory.execute(() -> { - for (;;) { - // 每次生产10000个,然后放入队列中 - try { - LinkedList txSerializeBytes = dataAccountActiveCreate(); - txBlockingQueue.put(txSerializeBytes); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - } - - private void kvStorageCreate(int loop, Bytes address) { - // 一直在生产用户 - instanceFactory.execute(() -> { - for (int index = 0; index < loop; index++) { - // 每次生产10000个,然后放入队列中 - try { - LinkedList txSerializeBytes = kvActiveCreate(address); - txBlockingQueue.put(txSerializeBytes); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - } - - private LinkedList userActiveCreate() { - // 每次生产10000个,然后放入队列中 - LinkedList txSerializeBytes = new LinkedList<>(); - for (int i = 0; i < CapabilitySettings.TX_SIZE_PER_SEND; i++) { - TransactionRequest txRequest = userRegisterRequest(CapabilitySettings.ledgerHash, CapabilitySettings.adminKey); - byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); - txSerializeBytes.addFirst(serializeBytes); - } - return txSerializeBytes; - } - - private LinkedList dataAccountActiveCreate() { - return dataAccountActiveCreate(false); - } - - private LinkedList dataAccountActiveCreate(boolean isSave) { - // 每次生产10000个,然后放入队列中 - LinkedList txSerializeBytes = new LinkedList<>(); - for (int i = 0; i < CapabilitySettings.TX_SIZE_PER_SEND; i++) { - TransactionRequest txRequest = dataAccountRegisterRequest(CapabilitySettings.ledgerHash, CapabilitySettings.adminKey, isSave); - byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); - txSerializeBytes.addFirst(serializeBytes); - } - return txSerializeBytes; - } - - private LinkedList kvActiveCreate(Bytes address) { - // 每次生产10000个,然后放入队列中 - LinkedList txSerializeBytes = new LinkedList<>(); - for (int i = 0; i < CapabilitySettings.TX_SIZE_PER_SEND; i++) { - TransactionRequest txRequest = kvStorageRequest(address, CapabilitySettings.ledgerHash, CapabilitySettings.adminKey); - byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); - txSerializeBytes.addFirst(serializeBytes); - } - return txSerializeBytes; - } - - private TransactionRequest userRegisterRequest(HashDigest ledgerHash, AsymmetricKeypair adminKey) { - TxBuilder txbuilder = new TxBuilder(ledgerHash); - BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); - txbuilder.users().register(userKey.getIdentity()); - TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); - reqBuilder.signAsEndpoint(adminKey); - return reqBuilder.buildRequest(); - } - - private TransactionRequest dataAccountRegisterRequest(HashDigest ledgerHash, AsymmetricKeypair adminKey, boolean isSave) { - TxBuilder txbuilder = new TxBuilder(ledgerHash); - BlockchainKeypair dataAccountKey = BlockchainKeyGenerator.getInstance().generate(); - BlockchainIdentity identity = dataAccountKey.getIdentity(); - txbuilder.dataAccounts().register(identity); - TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); - reqBuilder.signAsEndpoint(adminKey); - if (isSave) { - dataAccountAddress.addFirst(identity.getAddress()); - } - return reqBuilder.buildRequest(); - } - - private TransactionRequest dataAccountRegisterRequest(HashDigest ledgerHash, AsymmetricKeypair adminKey) { - TxBuilder txbuilder = new TxBuilder(ledgerHash); - BlockchainKeypair dataAccountKey = BlockchainKeyGenerator.getInstance().generate(); - BlockchainIdentity identity = dataAccountKey.getIdentity(); - txbuilder.dataAccounts().register(identity); - TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); - reqBuilder.signAsEndpoint(adminKey); - defaultDataAccount = identity.getAddress(); - return reqBuilder.buildRequest(); - } - - private TransactionRequest kvStorageRequest(Bytes address, HashDigest ledgerHash, AsymmetricKeypair adminKey) { - TxBuilder txbuilder = new TxBuilder(ledgerHash); - long currValue = keyPrefix.getAndIncrement(); - txbuilder.dataAccount(address).set("key-" + currValue + "-" + System.currentTimeMillis(), - BytesUtils.toBytes("value-" + currValue), -1L); - TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); - reqBuilder.signAsEndpoint(adminKey); - return reqBuilder.buildRequest(); - } + private MsgQueueProducer txProducer; + + private final ExecutorService instanceFactory = Executors.newSingleThreadExecutor(); + + private final ArrayBlockingQueue> txBlockingQueue = new ArrayBlockingQueue(1); + + private final LinkedList dataAccountAddress = new LinkedList<>(); + + private Bytes defaultDataAccount; + + private static final AtomicLong keyPrefix = new AtomicLong(); + + public void userRegister(int count) throws Exception { + initTxProducer(); + int loop = 0; + if (count <= 0) { + userCreate(); + } else { + loop = count / CapabilitySettings.TX_SIZE_PER_SEND; + userCreate(loop); + } + // 从队列中获取数据 + if (count <= 0) { + for (;;) { + txRequestSend(); + } + } else { + for (int i = 0; i < loop; i++) { + txRequestSend(); + } + } + closeTxProducer(); + } + + public void dataAccountRegister(int count) throws Exception { + initTxProducer(); + int loop = 0; + if (count <= 0) { + dataAccountCreate(); + } else { + loop = count / CapabilitySettings.TX_SIZE_PER_SEND; + dataAccountCreate(loop); + } + // 从队列中获取数据 + if (count <= 0) { + for (;;) { + txRequestSend(); + } + } else { + for (int i = 0; i < loop; i++) { + txRequestSend(); + } + } + closeTxProducer(); + } + + public void userAndDataAccountRegister(int userCount, int dataAccountCount) throws Exception { + if (userCount <= 0 || dataAccountCount <= 0) { + throw new IllegalArgumentException("userCount and dataAccountCount can not be 0!!!"); + } + initTxProducer(); + int userLoop = userCount / CapabilitySettings.TX_SIZE_PER_SEND; + int dataAccountLoop = dataAccountCount / CapabilitySettings.TX_SIZE_PER_SEND; + userCreate(userLoop); + dataAccountCreate(dataAccountLoop); + for (int i = 0, totalLoop = userLoop + dataAccountCount; i < totalLoop; i++) { + txRequestSend(); + } + closeTxProducer(); + } + + public void dataAccountRegisterAndKvStorage(int dataAccountCount, int kvCount) throws Exception { + if (kvCount <= 0 || dataAccountCount <= 0) { + throw new IllegalArgumentException("userCount and dataAccountCount can not be 0!!!"); + } + initTxProducer(); + int dataAccountLoop = dataAccountCount / CapabilitySettings.TX_SIZE_PER_SEND; + dataAccountCreate(dataAccountLoop); + // 首先将数据账户写入 + for (int i = 0; i < dataAccountLoop; i++) { + txRequestSend(); + } + int kvLoop = kvCount / CapabilitySettings.TX_SIZE_PER_SEND; + // 然后将每个数据账户都写入指定数量的kv + Iterator iterator = dataAccountAddress.iterator(); + while (iterator.hasNext()) { + Bytes address = iterator.next(); + kvStorageCreate(kvCount, address); + } + for (int i = 0, loop = kvLoop * dataAccountCount; i < loop; i++) { + txRequestSend(); + } + + closeTxProducer(); + } + + public void kvStorage(int kvCount) throws Exception { + initTxProducer(); + + dataAccountDefaultCreate(); + try { + txRequestSend(); + // 确认结块成功 + Thread.sleep(10000); + } catch (Exception e) { + throw e; + } + int kvLoop = kvCount / CapabilitySettings.TX_SIZE_PER_SEND; + // 然后将每个数据账户都写入指定数量的kv + Bytes address = defaultDataAccount; + kvStorageCreate(kvLoop, address); + for (int i = 0; i < kvLoop; i++) { + txRequestSend(); + } + + closeTxProducer(); + } + + private void txRequestSend() throws Exception { + List txRequests = txBlockingQueue.take(); + if (txRequests != null && !txRequests.isEmpty()) { + Iterator iterator = txRequests.iterator(); + while (iterator.hasNext()) { + byte[] txRequest = iterator.next(); + try { + txProducer.publish(txRequest); + } catch (Exception e) { + e.printStackTrace(); + } + } + ConsoleUtils.info("[*] Transaction Request send success!!!"); + } + } + + private void initTxProducer() throws Exception { + txProducer = MsgQueueFactory.newProducer(CapabilitySettings.MSG_QUEUE_URL, CapabilitySettings.TX_TOPIC); + txProducer.connect(); + ConsoleUtils.info("[*] Transaction Producer start success!!!"); + } + + private void closeTxProducer() throws Exception { + txProducer.close(); + } + + private void userCreate(int loop) { + instanceFactory.execute(() -> { + for (int index = 0; index < loop; index++) { + // 每次生产10000个,然后放入队列中 + try { + LinkedList txSerializeBytes = userActiveCreate(); + txBlockingQueue.put(txSerializeBytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + private void userCreate() { + // 一直在生产用户 + instanceFactory.execute(() -> { + for (;;) { + // 每次生产10000个,然后放入队列中 + try { + LinkedList txSerializeBytes = userActiveCreate(); + txBlockingQueue.put(txSerializeBytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + private void dataAccountCreate(int loop) { + dataAccountCreate(loop, false); + } + + private void dataAccountCreate(int loop, final boolean isSave) { + instanceFactory.execute(() -> { + for (int index = 0; index < loop; index++) { + // 每次生产10000个,然后放入队列中 + try { + LinkedList txSerializeBytes = dataAccountActiveCreate(isSave); + txBlockingQueue.put(txSerializeBytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + private void dataAccountDefaultCreate() { + instanceFactory.execute(() -> { + List currentBytes = new ArrayList<>(); + TransactionRequest txRequest = dataAccountRegisterRequest(CapabilitySettings.ledgerHash, + CapabilitySettings.adminKey); + byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); + currentBytes.add(serializeBytes); + try { + txBlockingQueue.put(currentBytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + private void dataAccountCreate() { + // 一直在生产用户 + instanceFactory.execute(() -> { + for (;;) { + // 每次生产10000个,然后放入队列中 + try { + LinkedList txSerializeBytes = dataAccountActiveCreate(); + txBlockingQueue.put(txSerializeBytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + private void kvStorageCreate(int loop, Bytes address) { + // 一直在生产用户 + instanceFactory.execute(() -> { + for (int index = 0; index < loop; index++) { + // 每次生产10000个,然后放入队列中 + try { + LinkedList txSerializeBytes = kvActiveCreate(address); + txBlockingQueue.put(txSerializeBytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + private LinkedList userActiveCreate() { + // 每次生产10000个,然后放入队列中 + LinkedList txSerializeBytes = new LinkedList<>(); + for (int i = 0; i < CapabilitySettings.TX_SIZE_PER_SEND; i++) { + TransactionRequest txRequest = userRegisterRequest(CapabilitySettings.ledgerHash, + CapabilitySettings.adminKey); + byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); + txSerializeBytes.addFirst(serializeBytes); + } + return txSerializeBytes; + } + + private LinkedList dataAccountActiveCreate() { + return dataAccountActiveCreate(false); + } + + private LinkedList dataAccountActiveCreate(boolean isSave) { + // 每次生产10000个,然后放入队列中 + LinkedList txSerializeBytes = new LinkedList<>(); + for (int i = 0; i < CapabilitySettings.TX_SIZE_PER_SEND; i++) { + TransactionRequest txRequest = dataAccountRegisterRequest(CapabilitySettings.ledgerHash, + CapabilitySettings.adminKey, isSave); + byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); + txSerializeBytes.addFirst(serializeBytes); + } + return txSerializeBytes; + } + + private LinkedList kvActiveCreate(Bytes address) { + // 每次生产10000个,然后放入队列中 + LinkedList txSerializeBytes = new LinkedList<>(); + for (int i = 0; i < CapabilitySettings.TX_SIZE_PER_SEND; i++) { + TransactionRequest txRequest = kvStorageRequest(address, CapabilitySettings.ledgerHash, + CapabilitySettings.adminKey); + byte[] serializeBytes = BinaryProtocol.encode(txRequest, TransactionRequest.class); + txSerializeBytes.addFirst(serializeBytes); + } + return txSerializeBytes; + } + + private TransactionRequest userRegisterRequest(HashDigest ledgerHash, AsymmetricKeypair adminKey) { + TxBuilder txbuilder = new TxBuilder(ledgerHash); + BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); + txbuilder.users().register(userKey.getIdentity()); + TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); + reqBuilder.signAsEndpoint(adminKey); + return reqBuilder.buildRequest(); + } + + private TransactionRequest dataAccountRegisterRequest(HashDigest ledgerHash, AsymmetricKeypair adminKey, + boolean isSave) { + TxBuilder txbuilder = new TxBuilder(ledgerHash); + BlockchainKeypair dataAccountKey = BlockchainKeyGenerator.getInstance().generate(); + BlockchainIdentity identity = dataAccountKey.getIdentity(); + txbuilder.dataAccounts().register(identity); + TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); + reqBuilder.signAsEndpoint(adminKey); + if (isSave) { + dataAccountAddress.addFirst(identity.getAddress()); + } + return reqBuilder.buildRequest(); + } + + private TransactionRequest dataAccountRegisterRequest(HashDigest ledgerHash, AsymmetricKeypair adminKey) { + TxBuilder txbuilder = new TxBuilder(ledgerHash); + BlockchainKeypair dataAccountKey = BlockchainKeyGenerator.getInstance().generate(); + BlockchainIdentity identity = dataAccountKey.getIdentity(); + txbuilder.dataAccounts().register(identity); + TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); + reqBuilder.signAsEndpoint(adminKey); + defaultDataAccount = identity.getAddress(); + return reqBuilder.buildRequest(); + } + + private TransactionRequest kvStorageRequest(Bytes address, HashDigest ledgerHash, AsymmetricKeypair adminKey) { + TxBuilder txbuilder = new TxBuilder(ledgerHash); + long currValue = keyPrefix.getAndIncrement(); + txbuilder.dataAccount(address).setText("key-" + currValue + "-" + System.currentTimeMillis(), + "value-" + currValue, -1L); + TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); + reqBuilder.signAsEndpoint(adminKey); + return reqBuilder.buildRequest(); + } } \ No newline at end of file diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitException.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitException.java index 22a09f31..3695a19e 100644 --- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitException.java +++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitException.java @@ -1,6 +1,6 @@ package com.jd.blockchain.tools.initializer; -import com.jd.blockchain.ledger.core.LedgerException; +import com.jd.blockchain.ledger.LedgerException; public class LedgerInitException extends LedgerException{ diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Bytes.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Bytes.java index 2aeb488e..dd87b2ff 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Bytes.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Bytes.java @@ -235,6 +235,10 @@ public class Bytes implements BytesSerializable { } return new Bytes(BytesUtils.toBytes(value)); } + + public String toUTF8String() { + return BytesUtils.toString(toBytes()); + } public static Bytes fromLong(long value) { if (value > -1 && value < MAX_CACHE) { 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 c6b0bccf..255ebd2a 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 @@ -1,6 +1,11 @@ package com.jd.blockchain.utils.io; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; import com.jd.blockchain.utils.IllegalDataException; @@ -296,6 +301,10 @@ public class BytesUtils { } } + /** + * @param bytes + * @return + */ public static String toString(byte[] bytes) { return toString(bytes, DEFAULT_CHARSET); } @@ -326,6 +335,10 @@ public class BytesUtils { } } + public static boolean toBoolean(byte value) { + return value != FALSE_BYTE; + } + /** * 按从高位到低位的顺序将指定二进制数组从位置 0 开始的 4 个字节转换为 int 整数; *