From 544d138375640b0e7adb0de939feef76cf70f527 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Thu, 19 Sep 2019 09:34:19 +0800 Subject: [PATCH 1/9] Renamed; --- .../src/main/java/com/jd/blockchain/consts/DataCodes.java | 4 ++-- .../src/main/java/com/jd/blockchain/ledger/ContractInfo.java | 2 +- .../src/main/java/com/jd/blockchain/ledger/UserInfo.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java index e3e2506c..80eaa4f7 100644 --- a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java +++ b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java @@ -121,12 +121,12 @@ public interface DataCodes { public static final int ACCOUNT_HEADER = 0x710; - public static final int USER = 0x800; + public static final int USER_ACCOUNT_HEADER = 0x800; public static final int DATA = 0x900; // contract related; - public static final int CONTRACT = 0xA00; + public static final int CONTRACT_ACCOUNT_HEADER = 0xA00; // ...0xA19 public static final int HASH = 0xB00; diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java index cb1da5c4..9ee1a75b 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java @@ -5,7 +5,7 @@ import com.jd.blockchain.binaryproto.DataField; import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.consts.DataCodes; -@DataContract(code= DataCodes.CONTRACT) +@DataContract(code= DataCodes.CONTRACT_ACCOUNT_HEADER) public interface ContractInfo extends AccountHeader { @DataField(order=4, primitiveType= PrimitiveType.BYTES) diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java index 48759b9f..3ad9ed85 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java @@ -4,7 +4,7 @@ import com.jd.blockchain.binaryproto.DataContract; import com.jd.blockchain.consts.DataCodes; import com.jd.blockchain.crypto.PubKey; -@DataContract(code= DataCodes.USER) +@DataContract(code= DataCodes.USER_ACCOUNT_HEADER) public interface UserInfo extends AccountHeader { PubKey getDataPubKey(); From 0debb28abcb347b7c9b510c0cdf9a360a7ae1c23 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Wed, 25 Sep 2019 09:20:43 +0800 Subject: [PATCH 2/9] temp; --- .../com/jd/blockchain/consts/DataCodes.java | 4 + .../binaryproto/impl/DynamicDataContract.java | 2 - .../blockchain/ledger/core/AccountQuery.java | 15 +- .../blockchain/ledger/core/BytesKeyMap.java | 8 + .../ledger/core/ContractAccount.java | 22 +- .../blockchain/ledger/core/DataAccount.java | 22 +- .../ledger/core/GenericAccount.java | 83 +++ .../ledger/core/GenericAccountSet.java | 92 ++++ .../ledger/core/HashDegistList.java | 42 ++ .../blockchain/ledger/core/HashProvable.java | 10 + .../blockchain/ledger/core/LedgerAccount.java | 14 + .../blockchain/ledger/core/MerkleAccount.java | 417 ++++++++++++---- .../ledger/core/MerkleAccountHeader.java | 12 + .../ledger/core/MerkleAccountSet.java | 190 +++---- .../ledger/core/MerkleDataEntry.java | 5 +- .../blockchain/ledger/core/MerkleDataSet.java | 177 ++++--- .../ledger/core/RolePrivilegeDataset.java | 2 +- .../blockchain/ledger/core/StringKeyMap.java | 7 + .../blockchain/ledger/core/UserAccount.java | 38 +- .../ledger/core/UserAccountSet.java | 7 +- .../ledger/core/UserRoleDataset.java | 2 +- .../core/handles/ContractLedgerContext.java | 16 +- .../ledger/core/BaseAccountTest.java | 14 +- .../ledger/core/ContractInvokingTest.java | 4 +- .../ledger/core/MerkleDataSetTest.java | 2 +- .../core/TransactionBatchProcessorTest.java | 12 +- .../jd/blockchain/ledger/AccountHeader.java | 2 +- .../com/jd/blockchain/ledger/BytesData.java | 118 ----- .../jd/blockchain/ledger/BytesDataList.java | 8 +- .../blockchain/ledger/BytesValueEncoding.java | 2 +- .../com/jd/blockchain/ledger/DataType.java | 59 +++ .../com/jd/blockchain/ledger/HashProof.java | 44 ++ .../com/jd/blockchain/ledger/MerkleProof.java | 76 ++- .../jd/blockchain/ledger/TypedBytesValue.java | 455 +++++++++++++++++ .../com/jd/blockchain/ledger/TypedValue_.java | 472 ++++++++++++++++++ .../blockchain/ledger/UserAccountHeader.java | 12 + .../com/jd/blockchain/ledger/UserInfo.java | 9 +- .../resolver/BooleanToBytesValueResolver.java | 4 +- .../resolver/BytesToBytesValueResolver.java | 6 +- .../resolver/IntegerToBytesValueResolver.java | 4 +- .../resolver/LongToBytesValueResolver.java | 4 +- .../resolver/ShortToBytesValueResolver.java | 4 +- .../resolver/StringToBytesValueResolver.java | 6 +- .../DataAccountKVSetOperationBuilderImpl.java | 18 +- .../ContractEventSendOpTemplateTest.java | 4 +- .../DataAccountKVSetOpTemplateTest.java | 8 +- .../com/jd/blockchain/ledger/KVDataTest.java | 4 +- .../sdk/converters/ClientResolveUtil.java | 7 +- .../impl/redis/RedisVerioningStorage.java | 2 +- .../rocksdb/RocksDBVersioningStorage.java | 2 +- .../storage/service/VersioningKVEntry.java | 20 - .../storage/service/VersioningKVStorage.java | 3 +- .../service/utils/BufferedKVStorage.java | 10 +- .../service/utils/MemoryKVStorage.java | 2 +- .../service/utils/VersioningKVData.java | 15 +- .../service/utils/VersioningKVStorageMap.java | 2 +- .../com/jd/blockchain/utils/RegionMap.java | 122 +++++ .../blockchain/utils/VersioningKVEntry.java | 17 + .../jd/blockchain/utils/VersioningMap.java | 116 +++++ 59 files changed, 2202 insertions(+), 654 deletions(-) create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccountSet.java create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashDegistList.java create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashProvable.java create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountHeader.java create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java delete mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesData.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashProof.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedBytesValue.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue_.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java delete mode 100644 source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVEntry.java create mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java create mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java create mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningMap.java diff --git a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java index 80eaa4f7..cd1da3d5 100644 --- a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java +++ b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java @@ -122,11 +122,15 @@ public interface DataCodes { public static final int ACCOUNT_HEADER = 0x710; public static final int USER_ACCOUNT_HEADER = 0x800; + + public static final int USER_INFO = 0x801; public static final int DATA = 0x900; // contract related; public static final int CONTRACT_ACCOUNT_HEADER = 0xA00; + + public static final int CONTRACT_INFO = 0xA01; // ...0xA19 public static final int HASH = 0xB00; diff --git a/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/impl/DynamicDataContract.java b/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/impl/DynamicDataContract.java index aaa8780b..58b94e25 100644 --- a/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/impl/DynamicDataContract.java +++ b/source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/impl/DynamicDataContract.java @@ -21,8 +21,6 @@ class DynamicDataContract implements InvocationHandler { private DataContractEncoderImpl contractEncoder; -// private BytesSlice contractBytes; - // 字段的数据片段列表,首个是 HeaderSlice,其次是按字段顺序排列的数据片段; private BytesSlices[] dataSlices; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountQuery.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountQuery.java index 8f1f3cb0..23afd3fd 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountQuery.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountQuery.java @@ -1,12 +1,11 @@ package com.jd.blockchain.ledger.core; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.utils.Bytes; public interface AccountQuery extends MerkleProvable { - - AccountHeader[] getHeaders(int fromIndex, int count); - + /** * 返回总数; * @@ -14,7 +13,15 @@ public interface AccountQuery extends MerkleProvable { */ long getTotal(); + BlockchainIdentity[] getHeaders(int fromIndex, int count); + boolean contains(Bytes address); + + /** + * get proof of specified account; + */ + @Override + MerkleProof getProof(Bytes address); /** * 返回账户实例; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java new file mode 100644 index 00000000..e4b6ffeb --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java @@ -0,0 +1,8 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningMap; + +public interface BytesKeyMap extends VersioningMap { + +} 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 69dfac2c..88583505 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 @@ -2,7 +2,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.ContractInfo; import com.jd.blockchain.ledger.MerkleProof; @@ -44,16 +44,16 @@ public class ContractAccount implements ContractInfo { } public long setChaincode(byte[] chaincode, long version) { - BytesValue bytesValue = BytesData.fromBytes(chaincode); - return accBase.setBytes(CHAIN_CODE_KEY, bytesValue, version); + BytesValue bytesValue = TypedBytesValue.fromBytes(chaincode); + return accBase.setValue(CHAIN_CODE_KEY, bytesValue, version); } public byte[] getChainCode() { - return accBase.getBytes(CHAIN_CODE_KEY).getValue().toBytes(); + return accBase.getValue(CHAIN_CODE_KEY).getValue().toBytes(); } public byte[] getChainCode(long version) { - return accBase.getBytes(CHAIN_CODE_KEY, version).getValue().toBytes(); + return accBase.getValue(CHAIN_CODE_KEY, version).getValue().toBytes(); } public long getChaincodeVersion() { @@ -61,18 +61,18 @@ public class ContractAccount implements ContractInfo { } public long setProperty(Bytes key, String value, long version) { - BytesValue bytesValue = BytesData.fromText(value); - return accBase.setBytes(encodePropertyKey(key), bytesValue, version); + BytesValue bytesValue = TypedBytesValue.fromText(value); + return accBase.setValue(encodePropertyKey(key), bytesValue, version); } public String getProperty(Bytes key) { - BytesValue bytesValue = accBase.getBytes(encodePropertyKey(key)); - return BytesData.toText(bytesValue); + BytesValue bytesValue = accBase.getValue(encodePropertyKey(key)); + return TypedBytesValue.toText(bytesValue); } public String getProperty(Bytes key, long version) { - BytesValue bytesValue = accBase.getBytes(encodePropertyKey(key), version); - return BytesData.toText(bytesValue); + BytesValue bytesValue = accBase.getValue(encodePropertyKey(key), version); + return TypedBytesValue.toText(bytesValue); } private Bytes encodePropertyKey(Bytes key) { 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 afaab416..3abbdfd7 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 @@ -4,7 +4,7 @@ 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.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.KVDataObject; @@ -67,7 +67,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * return -1; */ public long setBytes(Bytes key, BytesValue value, long version) { - return baseAccount.setBytes(key, value, version); + return baseAccount.setValue(key, value, version); } @@ -95,8 +95,8 @@ public class DataAccount implements AccountHeader, MerkleProvable { * return -1; */ public long setBytes(Bytes key, String value, long version) { - BytesValue bytesValue = BytesData.fromText(value); - return baseAccount.setBytes(key, bytesValue, version); + BytesValue bytesValue = TypedBytesValue.fromText(value); + return baseAccount.setValue(key, bytesValue, version); } /** @@ -123,8 +123,8 @@ public class DataAccount implements AccountHeader, MerkleProvable { * return -1; */ public long setBytes(Bytes key, byte[] value, long version) { - BytesValue bytesValue = BytesData.fromBytes(value); - return baseAccount.setBytes(key, bytesValue, version); + BytesValue bytesValue = TypedBytesValue.fromBytes(value); + return baseAccount.setValue(key, bytesValue, version); } /** @@ -156,7 +156,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @return return null if not exist; */ public BytesValue getBytes(String key) { - return baseAccount.getBytes(Bytes.fromString(key)); + return baseAccount.getValue(Bytes.fromString(key)); } /** @@ -166,7 +166,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @return return null if not exist; */ public BytesValue getBytes(Bytes key) { - return baseAccount.getBytes(key); + return baseAccount.getValue(key); } /** @@ -177,7 +177,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @return return null if not exist; */ public BytesValue getBytes(String key, long version) { - return baseAccount.getBytes(Bytes.fromString(key), version); + return baseAccount.getValue(Bytes.fromString(key), version); } /** @@ -188,7 +188,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @return return null if not exist; */ public BytesValue getBytes(Bytes key, long version) { - return baseAccount.getBytes(key, version); + return baseAccount.getValue(key, version); } /** @@ -206,7 +206,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { * @return */ public KVDataEntry getDataEntry(Bytes key, long version) { - BytesValue value = baseAccount.getBytes(key, version); + BytesValue value = baseAccount.getValue(key, version); if (value == null) { return new KVDataObject(key.toUTF8String(), -1, null); }else { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java new file mode 100644 index 00000000..e374c08a --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java @@ -0,0 +1,83 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.MerkleProof; +import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningMap; + +/** + * Super Type of concrete accounts, e.g. UserAccount, DataAccount, + * ContractAccount etc.; + * + * @author huanghaiquan + * + * @param Type of Account Header; + */ +public class GenericAccount implements MerkleAccountHeader, MerkleProvable, Transactional { + + private MerkleAccount merkleAccount; + + + /** + * 头部类型; + * + * @param headerType + */ + public GenericAccount(MerkleAccount merkleAccount) { + this.merkleAccount = merkleAccount; + } + + @Override + public HashDigest getRootHash() { + return merkleAccount.getRootHash(); + } + + @Override + public MerkleProof getProof(Bytes key) { + key = buildInnerKey(key); + return merkleAccount.getProof(key); + } + + + @Override + public BlockchainIdentity getID() { + return merkleAccount.getID(); + } + + public TypedMap getDataset() { + VersioningMap state = merkleAccount.getDataset(); + return new TypedMap(state); + } + + + @Override + public boolean isUpdated() { + return merkleAccount.isUpdated(); + } + + boolean isReadonly() { + return merkleAccount.isReadonly(); + } + + @Override + public void commit() { + merkleAccount.commit(); + } + + @Override + public void cancel() { + merkleAccount.cancel(); + } + + private Bytes buildInnerKey(Bytes key) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccountSet.java new file mode 100644 index 00000000..372163e1 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccountSet.java @@ -0,0 +1,92 @@ +//package com.jd.blockchain.ledger.core; +// +//import com.jd.blockchain.crypto.HashDigest; +//import com.jd.blockchain.ledger.AccountHeader; +//import com.jd.blockchain.ledger.CryptoSetting; +//import com.jd.blockchain.ledger.MerkleProof; +//import com.jd.blockchain.storage.service.ExPolicyKVStorage; +//import com.jd.blockchain.storage.service.VersioningKVStorage; +//import com.jd.blockchain.utils.Bytes; +//import com.jd.blockchain.utils.Transactional; +// +//public class GenericAccountSet> implements AccountQuery, Transactional { +// +// private Class headerType; +// +// private MerkleAccountSet merkleAccountSet; +// +// public GenericAccountSet(Class headerType, CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, +// VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { +// this(headerType, null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy); +// } +// +// public GenericAccountSet(Class headerType, HashDigest rootHash, CryptoSetting cryptoSetting, String keyPrefix, +// ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, +// AccountAccessPolicy accessPolicy) { +// this.headerType = headerType; +// this.merkleAccountSet = new MerkleAccountSet(rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly, accessPolicy); +// } +// +// @Override +// public MerkleProof getProof(Bytes address) { +// return merkleAccountSet.getProof(address); +// } +// +// @Override +// public HashDigest getRootHash() { +// return merkleAccountSet.getRootHash(); +// } +// +// @Override +// public boolean isUpdated() { +// return merkleAccountSet.isUpdated(); +// } +// +// @Override +// public void commit() { +// merkleAccountSet.commit(); +// } +// +// @Override +// public void cancel() { +// merkleAccountSet.cancel(); +// } +// +// @Override +// public H[] getHeaders(int fromIndex, int count) { +// merkleAccountSet.getHeaders(fromIndex, count) +// return null; +// } +// +// @Override +// public long getTotal() { +// // TODO Auto-generated method stub +// return 0; +// } +// +// @Override +// public boolean contains(Bytes address) { +// // TODO Auto-generated method stub +// return false; +// } +// +// @Override +// public T getAccount(String address) { +// // TODO Auto-generated method stub +// return null; +// } +// +// @Override +// public T getAccount(Bytes address) { +// // TODO Auto-generated method stub +// return null; +// } +// +// @Override +// public T getAccount(Bytes address, long version) { +// // TODO Auto-generated method stub +// return null; +// } +// +// +//} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashDegistList.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashDegistList.java new file mode 100644 index 00000000..41dc4f3d --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashDegistList.java @@ -0,0 +1,42 @@ +package com.jd.blockchain.ledger.core; + +import java.util.ArrayList; +import java.util.List; + +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.HashProof; + +/** + * + * @author huanghaiquan + * + */ +public class HashDegistList implements HashProof { + + private List proofs = new ArrayList(); + + public HashDegistList() { + } + + public HashDegistList(HashProof proof) { + concat(proof); + } + + public void concat(HashProof proof) { + int levels = proof.getLevels(); + for (int i = levels; i > -1; i--) { + proofs.add(proof.getHash(i)); + } + } + + @Override + public int getLevels() { + return proofs.size(); + } + + @Override + public HashDigest getHash(int level) { + return proofs.get(level); + } + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashProvable.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashProvable.java new file mode 100644 index 00000000..88da19ae --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/HashProvable.java @@ -0,0 +1,10 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.ledger.HashProof; +import com.jd.blockchain.utils.Bytes; + +public interface HashProvable { + + HashProof getProof(Bytes key); + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java new file mode 100644 index 00000000..02d6c7a1 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java @@ -0,0 +1,14 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningMap; + +public interface LedgerAccount { + + BlockchainIdentity getID(); + + VersioningMap getDataset(); + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java index 49ef5753..a0973e12 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java @@ -3,16 +3,20 @@ 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.ledger.HashProof; +import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.MerkleProof; +import com.jd.blockchain.ledger.MerkleSnapshot; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.VersioningMap; /** * 事务性的基础账户; @@ -20,28 +24,26 @@ import com.jd.blockchain.utils.Transactional; * @author huanghaiquan * */ -public class MerkleAccount implements AccountHeader, MerkleProvable, Transactional { +public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapshot, Transactional { - private BlockchainIdentity bcid; + private static final Bytes HEADER_PREFIX = Bytes.fromString("HD/"); + private static final Bytes DATA_PREFIX = Bytes.fromString("DT/"); - protected MerkleDataSet dataset; + private static final Bytes KEY_PUBKEY = Bytes.fromString("PUBKEY"); - /** - * Create a new Account with the specified address and pubkey;
- * - * At the same time, a empty merkle dataset is also created for this account, - * which is used for storing data of this account.
- * - * Note that, the blockchain identity of the account is not stored in the - * account's merkle dataset, but is stored by the outer invoker; - * - * @param address - * @param pubKey - */ - public MerkleAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { - this(address, pubKey, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); - } + private static final Bytes KEY_HEADER_ROOT = Bytes.fromString("HEADER"); + + private static final Bytes KEY_DATA_ROOT = Bytes.fromString("DATA"); + + private BlockchainIdentity accountID; + + private MerkleDataSet rootDS; + + private MerkleDatasetAdapter headerDS; + + private MerkleDatasetAdapter dataDS; + + protected long version; /** * Create a new Account with the specified address and pubkey;
@@ -52,62 +54,101 @@ public class MerkleAccount implements AccountHeader, MerkleProvable, Transaction * Note that, the blockchain identity of the account is not stored in the * account's merkle dataset, but is stored by the outer invoker; * - * @param bcid - * @param cryptoSetting + * @param accountID 身份; + * @param version 版本; + * @param cryptoSetting 密码参数; + * @param keyPrefix 数据前缀; * @param exStorage * @param verStorage - * @param accessPolicy */ - public MerkleAccount(BlockchainIdentity bcid, CryptoSetting cryptoSetting, String keyPrefix, + public MerkleAccount(BlockchainIdentity accountID, long version, CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { - this(bcid, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); + this(accountID.getAddress(), accountID.getPubKey(), version, null, cryptoSetting, keyPrefix, exStorage, + verStorage, false); + + savePubKey(accountID.getPubKey()); } /** * Create a account instance with the specified address and pubkey and load it's - * merkle dataset from the specified root hash. This merkle dateset is used for storing data - * of this account.
+ * merkle dataset from the specified root hash. This merkle dateset is used for + * storing data of this account.
* - * @param address - * @param pubKey - * @param dataRootHash merkle root hash of account's data; if set to a null value, - * an empty merkle dataset is created; + * @param accountID identity of this account; + * @param version + * @param dataRootHash merkle root hash of account's data; if set to a null + * value, an empty merkle dataset is created; * @param cryptoSetting + * @param keyPrefix * @param exStorage * @param verStorage * @param readonly - * @param accessPolicy */ - public MerkleAccount(Bytes address, PubKey pubKey, HashDigest dataRootHash, CryptoSetting cryptoSetting, - String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { - this(new BlockchainIdentityData(address, pubKey), dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, + public MerkleAccount(Bytes address, long version, HashDigest dataRootHash, CryptoSetting cryptoSetting, + Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { + this(address, null, version, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + } + + private MerkleAccount(Bytes address, PubKey pubKey, long version, HashDigest dataRootHash, + CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, + boolean readonly) { + this.accountID = new BlockchainIdentityProxy(address, pubKey); + this.version = version; + this.rootDS = new MerkleDataSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + + // 初始化数据; + DataChangedListener dataChangedListener = new DataChangedListener() { + @Override + public void onChanged(Bytes key, BytesValue value, long newVersion) { + onUpdated(keyPrefix, value, newVersion); + } + }; + + HashDigest headerRoot = loadHeaderRoot(); + Bytes headerPrefix = keyPrefix.concat(HEADER_PREFIX); + MerkleDataSet headerDataset = new MerkleDataSet(headerRoot, cryptoSetting, headerPrefix, exStorage, verStorage, readonly); + this.headerDS = new MerkleDatasetAdapter(headerDataset, dataChangedListener); + + HashDigest dataRoot = loadDataRoot(); + Bytes dataPrefix = keyPrefix.concat(DATA_PREFIX); + MerkleDataSet dataDataset = new MerkleDataSet(dataRoot, cryptoSetting, dataPrefix, exStorage, verStorage, + readonly); + this.dataDS = new MerkleDatasetAdapter(dataDataset, dataChangedListener); + } + + private HashDigest loadHeaderRoot() { + byte[] hashBytes = rootDS.getValue(KEY_HEADER_ROOT); + if (hashBytes == null) { + return null; + } + return new HashDigest(hashBytes); } - public MerkleAccount(BlockchainIdentity bcid, HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { - this.bcid = bcid; - this.dataset = new MerkleDataSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + private HashDigest loadDataRoot() { + byte[] hashBytes = rootDS.getValue(KEY_DATA_ROOT); + if (hashBytes == null) { + return null; + } + return new HashDigest(hashBytes); } - /* - * (non-Javadoc) - * - * @see com.jd.blockchain.ledger.core.AccountDataSet#getAddress() - */ - @Override public Bytes getAddress() { - return bcid.getAddress(); + return accountID.getAddress(); } - /* - * (non-Javadoc) - * - * @see com.jd.blockchain.ledger.core.AccountDataSet#getPubKey() - */ - @Override public PubKey getPubKey() { - return bcid.getPubKey(); + return accountID.getPubKey(); + } + + @Override + public BlockchainIdentity getID() { + return accountID; + } + + @Override + public VersioningMap getDataset() { + return dataDS; } /* @@ -117,12 +158,22 @@ public class MerkleAccount implements AccountHeader, MerkleProvable, Transaction */ @Override public HashDigest getRootHash() { - return dataset.getRootHash(); + return rootDS.getRootHash(); } @Override - public MerkleProof getProof(Bytes key) { - return dataset.getProof(key); + public HashProof getProof(Bytes key) { + MerkleProof dataProof = dataDS.getDataset().getProof(key); + if (dataProof == null) { + return null; + } + MerkleProof rootProof = rootDS.getProof(KEY_DATA_ROOT); + if (rootProof == null) { + return null; + } + HashDegistList proof = new HashDegistList(rootProof); + proof.concat(dataProof); + return proof; } /** @@ -131,90 +182,234 @@ public class MerkleAccount implements AccountHeader, MerkleProvable, Transaction * @return */ public boolean isReadonly() { - return dataset.isReadonly(); + return dataDS.getDataset().isReadonly(); } - /** - * Create or update the value associated the specified key if the version - * checking is passed.
- * - * The value of the key will be updated only if it's latest version equals the - * specified version argument.
- * If the key doesn't exist, the version checking will be ignored, and key will - * be created with a new sequence number as id.
- * It also could specify the version argument to -1 to ignore the version - * checking. - *

- * 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. - * @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;
- * If this operation fail by version checking or other reason, then - * return -1; - */ - public long setBytes(Bytes key, BytesValue value, long version) { - byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); - return dataset.setValue(key, bytesValue, version); + public long getDataCount() { + return dataDS.getDataset().getDataCount(); } /** - * Return the latest version entry associated the specified key; If the key - * doesn't exist, then return -1; + * 保存公钥; * - * @param key - * @return + * @param pubKey */ - public long getVersion(Bytes key) { - return dataset.getVersion(key); + private void savePubKey(PubKey pubKey) { + long v = headerDS.setValue(KEY_PUBKEY, TypedBytesValue.fromPubKey(pubKey), -1); + if (v < 0) { + throw new LedgerException("PubKey storage conflict!"); + } } /** - * return the latest version's value; + * 加载公钥; * - * @param key - * @return return null if not exist; + * @return */ - public BytesValue getBytes(Bytes key) { - byte[] bytesValue = dataset.getValue(key); - if (bytesValue == null) { - return null; - } - return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); + private PubKey loadPubKey() { + BytesValue bytesValue = headerDS.getValue(KEY_PUBKEY); + return TypedBytesValue.wrap(bytesValue).pubKeyValue(); } /** - * Return the specified version's value; + * 当写入新值时触发此方法; * * @param key - * @param version - * @return return null if not exist; + * @param value + * @param newVersion */ - public BytesValue getBytes(Bytes key, long version) { - byte[] bytesValue = dataset.getValue(key, version); - if (bytesValue == null) { - return null; - } - return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); + protected void onUpdated(Bytes key, BytesValue value, long newVersion) { } @Override public boolean isUpdated() { - return dataset.isUpdated(); + return dataDS.getDataset().isUpdated() || headerDS.getDataset().isUpdated() || rootDS.isUpdated(); } @Override public void commit() { - dataset.commit(); + dataDS.getDataset().commit(); + headerDS.getDataset().commit(); + + rootDS.setValue(key, value, version) + + baseDS.commit(); } @Override public void cancel() { - dataset.cancel(); + baseDS.cancel(); + } + + private class BlockchainIdentityProxy implements BlockchainIdentity { + + private Bytes address; + + private PubKey pubKey; + + public BlockchainIdentityProxy(Bytes address, PubKey pubKey) { + this.address = address; + this.pubKey = pubKey; + } + + @Override + public Bytes getAddress() { + return address; + } + + @Override + public PubKey getPubKey() { + if (pubKey == null) { + pubKey = loadPubKey(); + } + return pubKey; + } + + } + + // ---------------------- + + private static class MerkleDatasetAdapter implements VersioningMap { + + private static DataChangedListener NULL_LISTENER = new DataChangedListener() { + @Override + public void onChanged(Bytes key, BytesValue value, long newVersion) { + } + }; + + private DataChangedListener changedListener; + + private MerkleDataSet dataset; + + public MerkleDataSet getDataset() { + return dataset; + } + + public MerkleDatasetAdapter(MerkleDataSet dataset) { + this(dataset, NULL_LISTENER); + } + + public MerkleDatasetAdapter(MerkleDataSet dataset, DataChangedListener listener) { + this.dataset = dataset; + this.changedListener = listener == null ? NULL_LISTENER : listener; + } + + @Override + public VersioningKVEntry getDataEntry(Bytes key) { + return new VersioningKVEntryWraper(dataset.getDataEntry(key)); + } + + @Override + public VersioningKVEntry getDataEntry(Bytes key, long version) { + return new VersioningKVEntryWraper(dataset.getDataEntry(key, version)); + } + + /** + * Create or update the value associated the specified key if the version + * checking is passed.
+ * + * The value of the key will be updated only if it's latest version equals the + * specified version argument.
+ * If the key doesn't exist, the version checking will be ignored, and key will + * be created with a new sequence number as id.
+ * It also could specify the version argument to -1 to ignore the version + * checking. + *

+ * 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. + * @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;
+ * If this operation fail by version checking or other reason, then + * return -1; + */ + @Override + public long setValue(Bytes key, BytesValue value, long version) { + byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); + long v = dataset.setValue(key, bytesValue, version); + if (v > -1) { + changedListener.onChanged(key, value, v); + } + return v; + } + + /** + * Return the latest version entry associated the specified key; If the key + * doesn't exist, then return -1; + * + * @param key + * @return + */ + @Override + public long getVersion(Bytes key) { + return dataset.getVersion(key); + } + + /** + * return the latest version's value; + * + * @param key + * @return return null if not exist; + */ + @Override + public BytesValue getValue(Bytes key) { + byte[] bytesValue = dataset.getValue(key); + if (bytesValue == null) { + return null; + } + return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); + } + + /** + * Return the specified version's value; + * + * @param key + * @param version + * @return return null if not exist; + */ + @Override + public BytesValue getValue(Bytes key, long version) { + byte[] bytesValue = dataset.getValue(key, version); + if (bytesValue == null) { + return null; + } + return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); + } + } + + private static interface DataChangedListener { + + void onChanged(Bytes key, BytesValue value, long newVersion); + + } + + private static class VersioningKVEntryWraper implements VersioningKVEntry { + + private VersioningKVEntry kv; + + public VersioningKVEntryWraper(VersioningKVEntry kv) { + this.kv = kv; + } + + @Override + public Bytes getKey() { + return kv.getKey(); + } + + @Override + public long getVersion() { + return kv.getVersion(); + } + + @Override + public BytesValue getValue() { + return BinaryProtocol.decodeAs(kv.getValue(), BytesValue.class); + } + } } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountHeader.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountHeader.java new file mode 100644 index 00000000..94faeb6a --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountHeader.java @@ -0,0 +1,12 @@ +//package com.jd.blockchain.ledger.core; +// +//import com.jd.blockchain.binaryproto.DataField; +//import com.jd.blockchain.ledger.BlockchainIdentity; +//import com.jd.blockchain.ledger.MerkleSnapshot; +// +//public interface MerkleAccountHeader extends MerkleSnapshot { +// +// @DataField(order = 1, refContract = true) +// BlockchainIdentity getID(); +// +//} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java index d3e507ba..0a833516 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java @@ -9,6 +9,7 @@ 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.BlockchainIdentity; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.LedgerException; @@ -17,17 +18,24 @@ import com.jd.blockchain.ledger.MerkleSnapshot; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.RegionMap; import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningMap; -public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery { +public abstract class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery { + + private static final Bytes ACCOUNT_ROOT_PREFIX = Bytes.fromString("ROOT/"); static { DataContractRegistry.register(MerkleSnapshot.class); DataContractRegistry.register(AccountHeader.class); } - private final String keyPrefix; - + private final Bytes keyPrefix; + + /** + * 账户根哈希的数据集; + */ private MerkleDataSet merkleDataset; /** @@ -36,7 +44,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * */ // TODO:未考虑大数据量时,由于缺少过期策略,会导致内存溢出的问题; - private Map latestAccountsCache = new HashMap<>(); + private Map latestAccountsCache = new HashMap<>(); private ExPolicyKVStorage baseExStorage; @@ -44,7 +52,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ private CryptoSetting cryptoSetting; - private boolean updated; + private volatile boolean updated; private AccountAccessPolicy accessPolicy; @@ -56,12 +64,12 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ merkleDataset.setReadonly(); } - public MerkleAccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, + public MerkleAccountSet(CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { this(null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy); } - public MerkleAccountSet(HashDigest rootHash, CryptoSetting cryptoSetting, String keyPrefix, + public MerkleAccountSet(HashDigest rootHash, CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, AccountAccessPolicy accessPolicy) { this.keyPrefix = keyPrefix; @@ -70,6 +78,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ this.baseVerStorage = verStorage; this.merkleDataset = new MerkleDataSet(rootHash, cryptoSetting, keyPrefix, this.baseExStorage, this.baseVerStorage, readonly); + this.accessPolicy = accessPolicy; } @@ -83,10 +92,11 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ return merkleDataset.getProof(key); } - public AccountHeader[] getHeaders(int fromIndex, int count) { + @Override + public BlockchainIdentity[] getHeaders(int fromIndex, int count) { byte[][] results = merkleDataset.getLatestValues(fromIndex, count); - AccountHeader[] accounts = new AccountHeader[results.length]; + BlockchainIdentity[] accounts = new BlockchainIdentity[results.length]; for (int i = 0; i < results.length; i++) { accounts[i] = deserialize(results[i]); } @@ -104,8 +114,8 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ // keyPrefix, baseExStorage, baseVerStorage, true, accessPolicy, accInfo.); // } - private AccountHeader deserialize(byte[] txBytes) { - return BinaryProtocol.decode(txBytes); + private BlockchainIdentity deserialize(byte[] txBytes) { + return BinaryProtocol.decodeAs(txBytes, BlockchainIdentity.class); } /** @@ -128,6 +138,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * @param address * @return */ + @Override public MerkleAccount getAccount(Bytes address) { return this.getAccount(address, -1); } @@ -157,7 +168,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * @return */ public long getVersion(Bytes address) { - InnerVersioningAccount acc = latestAccountsCache.get(address); + InnerMerkleAccount acc = latestAccountsCache.get(address); if (acc != null) { // 已注册尚未提交,也返回 -1; return acc.version == -1 ? 0 : acc.version; @@ -177,7 +188,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ */ public MerkleAccount getAccount(Bytes address, long version) { version = version < 0 ? -1 : version; - InnerVersioningAccount acc = latestAccountsCache.get(address); + InnerMerkleAccount acc = latestAccountsCache.get(address); if (acc != null && version == -1) { return acc; } else if (acc != null && acc.version == version) { @@ -218,8 +229,9 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ // ExPolicyKVStorage ss = PrefixAppender.prefix(prefix, baseExStorage); // VersioningKVStorage vs = PrefixAppender.prefix(prefix, baseVerStorage); // BaseAccount accDS = deserialize(bytes, cryptoSetting, ss, vs, readonly); - String prefix = keyPrefix + address; - acc = deserialize(bytes, cryptoSetting, prefix, baseExStorage, baseVerStorage, readonly, latestVersion); + + Bytes prefix = keyPrefix.concat(address); + acc = deserialize(bytes, cryptoSetting, prefix, readonly, latestVersion); if (!readonly) { // cache the latest version witch enable reading and writing; // readonly version of account not necessary to be cached; @@ -239,14 +251,16 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * @param pubKey 公钥; * @return 注册成功的账户对象; */ - public MerkleAccount register(Bytes address, PubKey pubKey) { + public MerkleAccount register(BlockchainIdentity accountId) { if (isReadonly()) { throw new IllegalArgumentException("This AccountSet is readonly!"); } + Bytes address = accountId.getAddress(); + PubKey pubKey = accountId.getPubKey(); verifyAddressEncoding(address, pubKey); - InnerVersioningAccount cachedAcc = latestAccountsCache.get(address); + InnerMerkleAccount cachedAcc = latestAccountsCache.get(address); if (cachedAcc != null) { if (cachedAcc.version < 0) { // 同一个新账户已经注册,但尚未提交,所以重复注册不会引起任何变化; @@ -272,9 +286,8 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ // BaseAccount accDS = createInstance(address, pubKey, cryptoSetting, // accExStorage, accVerStorage); - String prefix = keyPrefix + address; - InnerVersioningAccount acc = createInstance(address, pubKey, cryptoSetting, prefix, baseExStorage, baseVerStorage, - -1); + Bytes prefix = keyPrefix.concat(address); + InnerMerkleAccount acc = createInstance(accountId, cryptoSetting, prefix, -1); latestAccountsCache.put(address, acc); updated = true; @@ -288,20 +301,24 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ } } - private InnerVersioningAccount createInstance(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, - String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { - return new InnerVersioningAccount(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage, version); + private InnerMerkleAccount createInstance(BlockchainIdentity header, CryptoSetting cryptoSetting, Bytes keyPrefix, + long version) { + return new InnerMerkleAccount(header, version, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage); } - private InnerVersioningAccount deserialize(byte[] bytes, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, long version) { - AccountHeader accInfo = BinaryProtocol.decode(bytes); - return new InnerVersioningAccount(accInfo.getAddress(), accInfo.getPubKey(), accInfo.getRootHash(), cryptoSetting, - keyPrefix, exStorage, verStorage, readonly, version); + private InnerMerkleAccount deserialize(byte[] bytes, CryptoSetting cryptoSetting, Bytes keyPrefix, boolean readonly, + long version) { + BlockchainIdentity id = BinaryProtocol.decodeAs(bytes, BlockchainIdentity.class); + + return new InnerMerkleAccount(header.getID(), version, header.getRootHash(), cryptoSetting, keyPrefix, + baseExStorage, baseVerStorage, readonly); + } - private byte[] serialize(AccountHeader account) { - return BinaryProtocol.encode(account, AccountHeader.class); + // TODO: 优化:区块链身份(地址+公钥)与其 Merkle + // 树根哈希分开独立存储;不必作为一个整块,避免状态数据写入时频繁重写公钥,尤其某些算法的公钥可能很大; + private byte[] serialize(MerkleAccountHeader account) { + return BinaryProtocol.encode(account, MerkleAccountHeader.class); } @Override @@ -315,16 +332,17 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ return; } try { - for (InnerVersioningAccount acc : latestAccountsCache.values()) { + for (InnerMerkleAccount acc : latestAccountsCache.values()) { // updated or new created; if (acc.isUpdated() || acc.version < 0) { // 提交更改,更新哈希; acc.commit(); byte[] value = serialize(acc); - long ver = merkleDataset.setValue(acc.getAddress(), value, acc.version); + long ver = merkleDataset.setValue(acc.getID().getAddress(), value, acc.version); if (ver < 0) { // Update fail; - throw new LedgerException("Account updating fail! --[Address=" + acc.getAddress() + "]"); + throw new LedgerException( + "Account updating fail! --[Address=" + acc.getID().getAddress() + "]"); } } } @@ -343,7 +361,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ Bytes[] addresses = new Bytes[latestAccountsCache.size()]; latestAccountsCache.keySet().toArray(addresses); for (Bytes address : addresses) { - InnerVersioningAccount acc = latestAccountsCache.remove(address); + InnerMerkleAccount acc = latestAccountsCache.remove(address); // cancel; if (acc.isUpdated()) { acc.cancel(); @@ -352,108 +370,24 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ updated = false; } - public static class AccountHeaderData implements AccountHeader { - - private Bytes address; - private PubKey pubKey; - private HashDigest rootHash; - - public AccountHeaderData(Bytes address, PubKey pubKey, HashDigest rootHash) { - this.address = address; - this.pubKey = pubKey; - this.rootHash = rootHash; - } + private class InnerMerkleAccount extends MerkleAccount { - @Override - public Bytes getAddress() { - return address; + public InnerMerkleAccount(BlockchainIdentity accountID, long version, CryptoSetting cryptoSetting, + Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { + super(accountID, version, cryptoSetting, keyPrefix, exStorage, verStorage); } - @Override - public PubKey getPubKey() { - return pubKey; + public InnerMerkleAccount(BlockchainIdentity accountID, long version, HashDigest dataRootHash, + CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, + VersioningKVStorage verStorage, boolean readonly) { + super(accountID, version, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); } @Override - public HashDigest getRootHash() { - return rootHash; + protected void onUpdated(Bytes key, BytesValue value, long newVersion) { + updated = true; } } - private class InnerVersioningAccount extends MerkleAccount { - - // private final BaseAccount account; - - private final long version; - - // public VersioningAccount(BaseAccount account, long version) { - // this.account = account; - // this.version = version; - // } - - public InnerVersioningAccount(Bytes address, PubKey pubKey, HashDigest rootHash, CryptoSetting cryptoSetting, - String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, - long version) { - super(address, pubKey, rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); - this.version = version; - } - - public InnerVersioningAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, - ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { - super(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage); - this.version = version; - } - - // @Override - // public Bytes getAddress() { - // return account.getAddress(); - // } - // - // @Override - // public PubKey getPubKey() { - // return account.getPubKey(); - // } - // - // @Override - // public HashDigest getRootHash() { - // return account.getRootHash(); - // } - // - // @Override - // public MerkleProof getProof(Bytes key) { - // return account.getProof(key); - // } - // - // @Override - // public boolean isReadonly() { - // return account.isReadonly(); - // } - - @Override - public long setBytes(Bytes key, BytesValue value, long version) { - long v = super.setBytes(key, value, version); - if (v > -1) { - updated = true; - } - return v; - } - - // @Override - // public long getKeyVersion(Bytes key) { - // return account.getKeyVersion(key); - // } - // - // @Override - // public byte[] getBytes(Bytes key) { - // return account.getBytes(key); - // } - // - // @Override - // public byte[] getBytes(Bytes key, long version) { - // return account.getBytes(key, version); - // } - - } - } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java index 3dd99df0..75894d0f 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java @@ -1,11 +1,12 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.ledger.MerkleProof; -import com.jd.blockchain.storage.service.VersioningKVEntry; +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; public interface MerkleDataEntry { - VersioningKVEntry getData(); + VersioningKVEntry getData(); MerkleProof getProof(); } 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 16927b97..0ea23990 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 @@ -7,12 +7,13 @@ import com.jd.blockchain.ledger.MerkleDataNode; import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.storage.service.utils.BufferedKVStorage; import com.jd.blockchain.storage.service.utils.VersioningKVData; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.VersioningMap; import com.jd.blockchain.utils.io.BytesUtils; /** @@ -23,7 +24,7 @@ import com.jd.blockchain.utils.io.BytesUtils; * @author huanghaiquan * */ -public class MerkleDataSet implements Transactional, MerkleProvable { +public class MerkleDataSet implements Transactional, MerkleProvable, VersioningMap { /** * 4 MB MaxSize of value; @@ -32,9 +33,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { public static final String ORIG_KEY_SEPERATOR = LedgerConsts.KEY_SEPERATOR; - public static final String SN_PREFIX = "SN" + ORIG_KEY_SEPERATOR; - public static final String DATA_PREFIX = "KV" + ORIG_KEY_SEPERATOR; - public static final String MERKLE_TREE_PREFIX = "MKL" + ORIG_KEY_SEPERATOR; + public static final Bytes SN_PREFIX = Bytes.fromString("SN" + ORIG_KEY_SEPERATOR); + public static final Bytes DATA_PREFIX = Bytes.fromString("KV" + ORIG_KEY_SEPERATOR); + public static final Bytes MERKLE_TREE_PREFIX = Bytes.fromString("MKL" + ORIG_KEY_SEPERATOR); private final Bytes snKeyPrefix; private final Bytes dataKeyPrefix; @@ -102,19 +103,21 @@ public class MerkleDataSet implements Transactional, MerkleProvable { * @param merkleTreeStorage * @param snGenerator */ - public MerkleDataSet(HashDigest merkleRootHash, CryptoSetting setting, String keyPrefix, + public MerkleDataSet(HashDigest merkleRootHash, CryptoSetting setting, Bytes keyPrefix, ExPolicyKVStorage exPolicyStorage, VersioningKVStorage versioningStorage, boolean readonly) { // 缓冲对KV的写入; this.bufferedStorage = new BufferedKVStorage(exPolicyStorage, versioningStorage, false); // 把存储数据值、SN、Merkle节点的 key 分别加入独立的前缀,避免针对 key 的注入攻击; - snKeyPrefix = Bytes.fromString(keyPrefix + SN_PREFIX); - dataKeyPrefix = Bytes.fromString(keyPrefix + DATA_PREFIX); +// snKeyPrefix = Bytes.fromString(keyPrefix + SN_PREFIX); +// dataKeyPrefix = Bytes.fromString(keyPrefix + DATA_PREFIX); + snKeyPrefix = keyPrefix.concat(SN_PREFIX); + dataKeyPrefix = keyPrefix.concat(DATA_PREFIX); this.valueStorage = bufferedStorage; this.snStorage = bufferedStorage; // MerkleTree 本身是可缓冲的; - merkleKeyPrefix = Bytes.fromString(keyPrefix + MERKLE_TREE_PREFIX); + merkleKeyPrefix = keyPrefix.concat(MERKLE_TREE_PREFIX); ExPolicyKVStorage merkleTreeStorage = exPolicyStorage; this.merkleTree = new MerkleTree(merkleRootHash, setting, merkleKeyPrefix, merkleTreeStorage, readonly); @@ -154,20 +157,21 @@ public class MerkleDataSet implements Transactional, MerkleProvable { return values; } - public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) { + public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) { if (count > LedgerConsts.MAX_LIST_COUNT) { throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!"); } if (fromIndex < 0 || (fromIndex + count) > merkleTree.getDataCount()) { throw new IllegalArgumentException("Index out of bound!"); } - VersioningKVEntry[] values = new VersioningKVEntry[count]; + @SuppressWarnings("unchecked") + VersioningKVEntry[] values = new VersioningKVEntry[count]; byte[] bytesValue; for (int i = 0; i < count; i++) { MerkleDataNode dataNode = merkleTree.getData(fromIndex + i); Bytes dataKey = encodeDataKey(dataNode.getKey()); bytesValue = valueStorage.get(dataKey, dataNode.getVersion()); - values[i] = new VersioningKVData(dataNode.getKey(), dataNode.getVersion(), bytesValue); + values[i] = new VersioningKVData(dataNode.getKey(), dataNode.getVersion(), bytesValue); } return values; } @@ -192,32 +196,34 @@ public class MerkleDataSet implements Transactional, MerkleProvable { */ public String getKeyAtIndex(int fromIndex) { MerkleDataNode dataNode = merkleTree.getData(fromIndex); - return dataNode.getKey().toUTF8String(); - } - - /** - * Create or update the value associated the specified key if the version - * checking is passed.
- * - * The value of the key will be updated only if it's latest version equals the - * specified version argument.
- * If the key doesn't exist, it will be created when the version arg was -1. - *

- * 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 latest 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;
- * If this operation fail by version checking or other reason, then - * return -1; - */ - public long setValue(String key, byte[] value, long version) { - return setValue(Bytes.fromString(key), value, version); - } + //TODO: 未去掉前缀; + return dataNode.getKey().toUTF8String(); + } + +// /** +// * Create or update the value associated the specified key if the version +// * checking is passed.
+// * +// * The value of the key will be updated only if it's latest version equals the +// * specified version argument.
+// * If the key doesn't exist, it will be created when the version arg was -1. +// *

+// * 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 latest 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;
+// * If this operation fail by version checking or other reason, then +// * return -1; +// */ +// @Override +// public long setValue(String key, byte[] value, long version) { +// return setValue(Bytes.fromString(key), value, version); +// } /** * Create or update the value associated the specified key if the version @@ -239,6 +245,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable { * If this operation fail by version checking or other reason, then * return -1; */ + @Override public long setValue(Bytes key, byte[] value, long version) { if (readonly) { throw new IllegalArgumentException("This merkle dataset is readonly!"); @@ -336,18 +343,19 @@ public class MerkleDataSet implements Transactional, MerkleProvable { return mdn.getVersion(); } - /** - * Return the specified version's value;
- * - * If the key with the specified version doesn't exist, then return null;
- * If the version is specified to -1, then return the latest version's value; - * - * @param key - * @param version - */ - public byte[] getValue(String key, long version) { - return getValue(Bytes.fromString(key), version); - } +// /** +// * Return the specified version's value;
+// * +// * If the key with the specified version doesn't exist, then return null;
+// * If the version is specified to -1, then return the latest version's value; +// * +// * @param key +// * @param version +// */ +// @Override +// public byte[] getValue(String key, long version) { +// return getValue(Bytes.fromString(key), version); +// } /** * Return the specified version's value;
@@ -358,6 +366,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable { * @param key * @param version */ + @Override public byte[] getValue(Bytes key, long version) { long latestVersion = getMerkleVersion(key); if (latestVersion < 0 || version > latestVersion) { @@ -370,15 +379,16 @@ public class MerkleDataSet implements Transactional, MerkleProvable { return valueStorage.get(dataKey, version); } - /** - * Return the latest version's value; - * - * @param key - * @return return null if not exist; - */ - public byte[] getValue(String key) { - return getValue(Bytes.fromString(key)); - } +// /** +// * Return the latest version's value; +// * +// * @param key +// * @return return null if not exist; +// */ +// @Override +// public byte[] getValue(String key) { +// return getValue(Bytes.fromString(key)); +// } /** * Return the latest version's value; @@ -386,6 +396,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable { * @param key * @return return null if not exist; */ + @Override public byte[] getValue(Bytes key) { long latestVersion = getMerkleVersion(key); if (latestVersion < 0) { @@ -395,16 +406,17 @@ public class MerkleDataSet implements Transactional, MerkleProvable { return valueStorage.get(dataKey, latestVersion); } - /** - * Return the latest version entry associated the specified key; If the key - * doesn't exist, then return -1; - * - * @param key - * @return - */ - public long getVersion(String key) { - return getMerkleVersion(Bytes.fromString(key)); - } +// /** +// * Return the latest version entry associated the specified key; If the key +// * doesn't exist, then return -1; +// * +// * @param key +// * @return +// */ +// @Override +// public long getVersion(String key) { +// return getMerkleVersion(Bytes.fromString(key)); +// } /** * Return the latest version entry associated the specified key; If the key @@ -413,20 +425,22 @@ public class MerkleDataSet implements Transactional, MerkleProvable { * @param key * @return */ + @Override public long getVersion(Bytes key) { return getMerkleVersion(key); } - public VersioningKVEntry getDataEntry(String key) { - return getDataEntry(Bytes.fromString(key)); - } +// public VersioningKVEntry getDataEntry(String key) { +// return getDataEntry(Bytes.fromString(key)); +// } /** * * @param key * @return Null if the key doesn't exist! */ - public VersioningKVEntry getDataEntry(Bytes key) { + @Override + public VersioningKVEntry getDataEntry(Bytes key) { long latestVersion = getMerkleVersion(key); if (latestVersion < 0) { return null; @@ -436,10 +450,11 @@ public class MerkleDataSet implements Transactional, MerkleProvable { if (value == null) { return null; } - return new VersioningKVData(key, latestVersion, value); + return new VersioningKVData(key, latestVersion, value); } - public VersioningKVEntry getDataEntry(Bytes key, long version) { + @Override + public VersioningKVEntry getDataEntry(Bytes key, long version) { long latestVersion = getMerkleVersion(key); if (latestVersion < 0 || version > latestVersion) { // key not exist, or the specified version is out of the latest version indexed @@ -452,11 +467,11 @@ public class MerkleDataSet implements Transactional, MerkleProvable { if (value == null) { return null; } - return new VersioningKVData(key, version, value); + return new VersioningKVData(key, version, value); } public MerkleDataEntry getMerkleEntry(Bytes key, long version) { - VersioningKVEntry dataEntry = getDataEntry(key, version); + VersioningKVEntry dataEntry = getDataEntry(key, version); if (dataEntry == null) { return null; } @@ -465,7 +480,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable { } public MerkleDataEntry getMerkleEntry(Bytes key) { - VersioningKVEntry dataEntry = getDataEntry(key); + VersioningKVEntry dataEntry = getDataEntry(key); if (dataEntry == null) { return null; } @@ -499,16 +514,16 @@ public class MerkleDataSet implements Transactional, MerkleProvable { */ private static class MerkleDataEntryWrapper implements MerkleDataEntry { - private VersioningKVEntry data; + private VersioningKVEntry data; private MerkleProof proof; - public MerkleDataEntryWrapper(VersioningKVEntry data, MerkleProof proof) { + public MerkleDataEntryWrapper(VersioningKVEntry data, MerkleProof proof) { this.data = data; this.proof = proof; } @Override - public VersioningKVEntry getData() { + public VersioningKVEntry getData() { return data; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java index 14673435..74d670c4 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java @@ -14,10 +14,10 @@ import com.jd.blockchain.ledger.RolePrivileges; import com.jd.blockchain.ledger.TransactionPermission; import com.jd.blockchain.ledger.TransactionPrivilege; import com.jd.blockchain.storage.service.ExPolicyKVStorage; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningKVEntry; public class RolePrivilegeDataset implements Transactional, MerkleProvable, RolePrivilegeSettings { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java new file mode 100644 index 00000000..227c3dd7 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java @@ -0,0 +1,7 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.utils.VersioningMap; + +public interface StringKeyMap extends VersioningMap { + +} 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 49743f90..0e7dc692 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,10 +2,11 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.BytesData; -import com.jd.blockchain.ledger.UserInfo; +import com.jd.blockchain.ledger.UserAccountHeader; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningMap; /** * 用户账户; @@ -13,35 +14,20 @@ import com.jd.blockchain.utils.Bytes; * @author huanghaiquan * */ -public class UserAccount implements UserInfo { +public class UserAccount extends MerkleAccount{ //implements UserInfo { private static final Bytes USER_INFO_PREFIX = Bytes.fromString("PROP" + LedgerConsts.KEY_SEPERATOR); private static final Bytes DATA_PUB_KEY = Bytes.fromString("DATA-PUBKEY"); - private MerkleAccount baseAccount; +// private MerkleAccount baseAccount; - @Override - public Bytes getAddress() { - return baseAccount.getAddress(); - } - - @Override - public PubKey getPubKey() { - return baseAccount.getPubKey(); - } - - @Override - public HashDigest getRootHash() { - return baseAccount.getRootHash(); - } - - public UserAccount(MerkleAccount baseAccount) { + public UserAccount(VersioningMap baseAccount) { this.baseAccount = baseAccount; } public PubKey getDataPubKey() { - BytesValue pkBytes = baseAccount.getBytes(DATA_PUB_KEY); + BytesValue pkBytes = baseAccount.getValue(DATA_PUB_KEY); if (pkBytes == null) { return null; } @@ -50,12 +36,12 @@ public class UserAccount implements UserInfo { public long setDataPubKey(PubKey pubKey) { byte[] pkBytes = pubKey.toBytes(); - return baseAccount.setBytes(DATA_PUB_KEY, BytesData.fromBytes(pkBytes), -1); + return baseAccount.setValue(DATA_PUB_KEY, TypedBytesValue.fromBytes(pkBytes), -1); } public long setDataPubKey(PubKey pubKey, long version) { byte[] pkBytes = pubKey.toBytes(); - return baseAccount.setBytes(DATA_PUB_KEY, BytesData.fromBytes(pkBytes), version); + return baseAccount.setValue(DATA_PUB_KEY, TypedBytesValue.fromBytes(pkBytes), version); } public long setProperty(String key, String value, long version) { @@ -63,16 +49,16 @@ public class UserAccount implements UserInfo { } public long setProperty(Bytes key, String value, long version) { - return baseAccount.setBytes(encodePropertyKey(key), BytesData.fromText(value), version); + return baseAccount.setValue(encodePropertyKey(key), TypedBytesValue.fromText(value), version); } public String getProperty(Bytes key) { - BytesValue value = baseAccount.getBytes(encodePropertyKey(key)); + BytesValue value = baseAccount.getValue(encodePropertyKey(key)); return value == null ? null : value.getValue().toUTF8String(); } public String getProperty(Bytes key, long version) { - BytesValue value = baseAccount.getBytes(encodePropertyKey(key), version); + BytesValue value = baseAccount.getValue(encodePropertyKey(key), version); return value == null ? null : value.getValue().toUTF8String(); } 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 a2e25356..700c0a49 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 @@ -10,6 +10,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningMap; /** * @author huanghaiquan @@ -71,7 +72,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { @Override public UserAccount getAccount(Bytes address) { - MerkleAccount baseAccount = accountSet.getAccount(address); + VersioningMap baseAccount = accountSet.getAccount(address); return new UserAccount(baseAccount); } @@ -82,7 +83,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { @Override public UserAccount getAccount(Bytes address, long version) { - MerkleAccount baseAccount = accountSet.getAccount(address, version); + VersioningMap baseAccount = accountSet.getAccount(address, version); return new UserAccount(baseAccount); } @@ -100,7 +101,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { * @return 注册成功的用户对象; */ public UserAccount register(Bytes address, PubKey pubKey) { - MerkleAccount baseAccount = accountSet.register(address, pubKey); + VersioningMap baseAccount = accountSet.register(address, pubKey); return new UserAccount(baseAccount); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java index 25ecd85a..84d71347 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java @@ -13,10 +13,10 @@ import com.jd.blockchain.ledger.RolesPolicy; import com.jd.blockchain.ledger.UserRoles; import com.jd.blockchain.ledger.UserAuthorizationSettings; import com.jd.blockchain.storage.service.ExPolicyKVStorage; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningKVEntry; /** * User-Role authorization data set; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java index 0d0d3c3d..5c22a7dc 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java @@ -268,7 +268,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { - BytesValue bytesValue = BytesData.fromText(value); + BytesValue bytesValue = TypedBytesValue.fromText(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -276,7 +276,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) { - BytesValue bytesValue = BytesData.fromBytes(value); + BytesValue bytesValue = TypedBytesValue.fromBytes(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -284,7 +284,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) { - BytesValue bytesValue = BytesData.fromInt64(value); + BytesValue bytesValue = TypedBytesValue.fromInt64(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -301,7 +301,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { - BytesValue bytesValue = BytesData.fromJSON(value); + BytesValue bytesValue = TypedBytesValue.fromJSON(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -309,7 +309,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) { - BytesValue bytesValue = BytesData.fromXML(value); + BytesValue bytesValue = TypedBytesValue.fromXML(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -317,7 +317,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { - BytesValue bytesValue = BytesData.fromBytes(value); + BytesValue bytesValue = TypedBytesValue.fromBytes(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -325,7 +325,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) { - BytesValue bytesValue = BytesData.fromImage(value); + BytesValue bytesValue = TypedBytesValue.fromImage(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -333,7 +333,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) { - BytesValue bytesValue = BytesData.fromTimestamp(value); + BytesValue bytesValue = TypedBytesValue.fromTimestamp(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java index 51c8232b..8ca0fe9f 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java @@ -12,7 +12,7 @@ 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.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.core.MerkleAccount; import com.jd.blockchain.ledger.core.CryptoConfig; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; @@ -53,33 +53,33 @@ public class BaseAccountTest { assertFalse(baseAccount.isReadonly()); // 在空白状态下写入数据; - long v = baseAccount.setBytes(Bytes.fromString("A"), BytesData.fromText("VALUE_A"), 0); + long v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A"), 0); // 预期失败; assertEquals(-1, v); - v = baseAccount.setBytes(Bytes.fromString("A"), BytesData.fromText("VALUE_A"), 1); + v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A"), 1); // 预期失败; assertEquals(-1, v); - v = baseAccount.setBytes(Bytes.fromString("A"), BytesData.fromText("VALUE_A"), -1); + v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A"), -1); // 预期成功; assertEquals(0, v); - v = baseAccount.setBytes(Bytes.fromString("A"), BytesData.fromText("VALUE_A-1"), -1); + v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.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"), BytesData.fromText("VALUE_A_" + i), v); + long s = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A_" + i), v); baseAccount.commit(); // 预期成功; assertEquals(v + 1, s); v++; } - v = baseAccount.setBytes(Bytes.fromString("A"), BytesData.fromText("VALUE_A_" + v), v + 1); + v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A_" + v), v + 1); // 预期成功; assertEquals(-1, v); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java index 3232c385..57711c42 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java @@ -132,7 +132,7 @@ public class ContractInvokingTest { assertEquals(1, opResults.length); assertEquals(0, opResults[0].getIndex()); - byte[] expectedRetnBytes = BinaryProtocol.encode(BytesData.fromInt64(issueAmount), BytesValue.class); + byte[] expectedRetnBytes = BinaryProtocol.encode(TypedBytesValue.fromInt64(issueAmount), BytesValue.class); byte[] reallyRetnBytes = BinaryProtocol.encode(opResults[0].getResult(), BytesValue.class); assertArrayEquals(expectedRetnBytes, reallyRetnBytes); @@ -218,7 +218,7 @@ public class ContractInvokingTest { TransactionBatchResultHandle txResultHandle = txbatchProcessor.prepare(); txResultHandle.commit(); - BytesValue latestValue = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getBytes(key, + BytesValue latestValue = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getValue(key, -1); System.out.printf("latest value=[%s] %s \r\n", latestValue.getType(), latestValue.getValue().toUTF8String()); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java index a90806d6..46ae96ae 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java @@ -23,9 +23,9 @@ import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.ledger.core.CryptoConfig; import com.jd.blockchain.ledger.core.MerkleDataSet; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; import com.jd.blockchain.utils.io.BytesUtils; public class MerkleDataSetTest { diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java index 06bf987d..ff4d160f 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java @@ -332,13 +332,13 @@ public class TransactionBatchProcessorTest { newBlock = newBlockEditor.prepare(); newBlockEditor.commit(); - BytesValue v1_0 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getBytes("K1", + BytesValue v1_0 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K1", 0); - BytesValue v1_1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getBytes("K1", + BytesValue v1_1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K1", 1); - BytesValue v2 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getBytes("K2", + BytesValue v2 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K2", 0); - BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getBytes("K3", + BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K3", 0); assertNotNull(v1_0); @@ -376,8 +376,8 @@ public class TransactionBatchProcessorTest { newBlock = newBlockEditor.prepare(); newBlockEditor.commit(); - BytesValue v1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getBytes("K1"); - v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getBytes("K3"); + BytesValue v1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K1"); + v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K3"); // k1 的版本仍然为1,没有更新; long k1_version = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()) diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java index 16f2794b..45d049ae 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java @@ -8,7 +8,7 @@ import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.utils.Bytes; @DataContract(code= DataCodes.ACCOUNT_HEADER) -public interface AccountHeader extends MerkleSnapshot{ +public interface AccountHeader { //extends MerkleSnapshot{ @DataField(order=1, primitiveType = PrimitiveType.BYTES) Bytes getAddress(); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesData.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesData.java deleted file mode 100644 index ca4e9cb0..00000000 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesData.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.jd.blockchain.ledger; - -import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; - -/** - * - * @author huanghaiquan - * - */ -public class BytesData implements BytesValue { - DataType type; - Bytes value; - - private BytesData(DataType type, byte[] bytes) { - this.type = type; - this.value = new Bytes(bytes); - } - - private BytesData(DataType type, Bytes bytes) { - this.type = type; - this.value = bytes; - } - - public static BytesValue fromType(DataType type, byte[] value) { - return new BytesData(type, value); - } - - public static BytesValue fromBytes(byte[] value) { - return new BytesData(DataType.BYTES, value); - } - - public static BytesValue fromBytes(Bytes value) { - return new BytesData(DataType.BYTES, value); - } - - public static BytesValue fromImage(byte[] value) { - return new BytesData(DataType.IMG, value); - } - - public static BytesValue fromImage(Bytes value) { - return new BytesData(DataType.IMG, value); - } - - /** - * 以 UTF-8 编码从字符串转换为字节数组值; - * - * @param value - * @return - */ - public static BytesValue fromText(String value) { - return new BytesData(DataType.TEXT, BytesUtils.toBytes(value)); - } - - /** - * 以 UTF-8 编码把字节数组值转换为字符串; - * - * @param bytesValue - * @return - */ - public static String toText(BytesValue bytesValue) { - if (bytesValue == null) { - return null; - } - if (bytesValue.getType() != DataType.TEXT) { - throw new ValueTypeCastException("The expected value type is " + DataType.TEXT.toString() - + ", but it is actually " + bytesValue.getType().toString() + "!"); - } - return bytesValue.getValue().toUTF8String(); - } - - public static BytesValue fromJSON(String value) { - return new BytesData(DataType.JSON, BytesUtils.toBytes(value)); - } - - public static BytesValue fromXML(String value) { - return new BytesData(DataType.XML, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt32(int value) { - return new BytesData(DataType.INT32, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt64(long value) { - return new BytesData(DataType.INT64, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt16(short value) { - return new BytesData(DataType.INT16, BytesUtils.toBytes(value)); - } - - public static BytesValue fromInt8(byte value) { - return new BytesData(DataType.INT8, BytesUtils.toBytes(value)); - } - - public static BytesValue fromTimestamp(long value) { - return new BytesData(DataType.TIMESTAMP, BytesUtils.toBytes(value)); - } - - public static BytesValue fromBoolean(boolean value) { - return new BytesData(DataType.BOOLEAN, BytesUtils.toBytes(value)); - } - - @Override - public DataType getType() { - return this.type; - } - - public void setType(DataType 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/BytesDataList.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesDataList.java index f7aef959..7aa87c82 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesDataList.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesDataList.java @@ -14,18 +14,18 @@ public class BytesDataList implements BytesValueList { } public static BytesValueList singleText(String value) { - return new BytesDataList(BytesData.fromText(value)); + return new BytesDataList(TypedBytesValue.fromText(value)); } public static BytesValueList singleLong(long value) { - return new BytesDataList(BytesData.fromInt64(value)); + return new BytesDataList(TypedBytesValue.fromInt64(value)); } public static BytesValueList singleInt(int value) { - return new BytesDataList(BytesData.fromInt32(value)); + return new BytesDataList(TypedBytesValue.fromInt32(value)); } public static BytesValueList singleBoolean(boolean value) { - return new BytesDataList(BytesData.fromBoolean(value)); + return new BytesDataList(TypedBytesValue.fromBoolean(value)); } } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java index baee5868..3315c511 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java @@ -68,7 +68,7 @@ public class BytesValueEncoding { } // 将对象序列化 byte[] serialBytes = BinaryProtocol.encode(value, type); - return BytesData.fromType(DataType.DATA_CONTRACT, serialBytes); + return TypedBytesValue.fromType(DataType.DATA_CONTRACT, serialBytes); } BytesValueResolver bytesValueResolver = CLASS_RESOLVER_MAP.get(type); if (bytesValueResolver == null) { diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataType.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataType.java index 1cb8fce3..6395bcc2 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataType.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataType.java @@ -106,6 +106,20 @@ public enum DataType { * DataContract 数据; */ DATA_CONTRACT((byte) (BaseType.EXT | 0x01)); + + + + public static final boolean BOOLEAN_DEFAULT_VALUE = false; + + public static final byte INT8_DEFAULT_VALUE = 0; + + public static final short INT16_DEFAULT_VALUE = 0; + + public static final int INT32_DEFAULT_VALUE = 0; + + public static final long INT64_DEFAULT_VALUE = 0; + + @EnumField(type = PrimitiveType.INT8) public final byte CODE; @@ -114,6 +128,51 @@ public enum DataType { this.CODE = code; } + /** + * 是否表示“文本类型”或“文本衍生类型”; + * + * @return + */ + public boolean isText() { + return BaseType.TEXT == (BaseType.TEXT & CODE); + } + + /** + * 是否表示“字节类型”或“字节衍生类型”; + * + * @return + */ + public boolean isBytes() { + return BaseType.BYTES == (BaseType.BYTES & CODE); + } + + /** + * 是否表示“整数类型”或“整数衍生类型”; + * + * @return + */ + public boolean isInteger() { + return BaseType.INTEGER == (BaseType.INTEGER & CODE); + } + + /** + * 是否表示“布尔类型”; + * + * @return + */ + public boolean isBoolean() { + return BaseType.BOOLEAN == (BaseType.BOOLEAN & CODE); + } + + /** + * 是否表示“扩展类型”; + * + * @return + */ + public boolean isExt() { + return BaseType.EXT == (BaseType.EXT & CODE); + } + public static DataType valueOf(byte code) { for (DataType dataType : DataType.values()) { if (dataType.CODE == code) { diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashProof.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashProof.java new file mode 100644 index 00000000..4b2dd9c5 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashProof.java @@ -0,0 +1,44 @@ +package com.jd.blockchain.ledger; + +import com.jd.blockchain.crypto.HashDigest; + +public interface HashProof { + /** + * 最大层级数;
+ * 叶子节点(即数据节点)的层级为 0,数据节点之上的每一级父节点的层级加 1, 最大层级便是根节点的层级; + * + * @return + * + * @see MerkleTree#getLevel() + */ + int getLevels(); + + /** + * 返回证明中指定层级的节点的哈希; + *

+ * + * @param level + * 参数值为 0 返回的是数据节点的哈希;
+ * 参数值为 {@link #getLevels()} 返回的是根节点的哈希; + * @return + */ + HashDigest getHash(int level); + + /** + * 返回根节点的哈希; + * + * @return + */ + default HashDigest getRootHash() { + return getHash(getLevels()); + } + + /** + * 返回数据节点的哈希; + * + * @return + */ + default HashDigest getDataHash() { + return getHash(0); + } +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/MerkleProof.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/MerkleProof.java index 1463f736..75721f7f 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/MerkleProof.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/MerkleProof.java @@ -1,8 +1,6 @@ package com.jd.blockchain.ledger; -import com.jd.blockchain.crypto.HashDigest; - -public interface MerkleProof { +public interface MerkleProof extends HashProof { /** * 所证明的数据节点的序列号; @@ -11,62 +9,46 @@ public interface MerkleProof { */ long getSN(); - /** - * 最大层级数;
- * 叶子节点(即数据节点)的层级为 0,数据节点之上的每一级父节点的层级加 1, 最大层级便是根节点的层级; - * - * @return - * - * @see MerkleTree#getLevel() - */ - int getLevels(); - - /** - * 返回证明中指定层级的节点的哈希; - *

- * - * @param level - * 参数值为 0 返回的是数据节点的哈希;
- * 参数值为 {@link #getLevels()} 返回的是根节点的哈希; - * @return - */ - HashDigest getHash(int level); - - MerkleNode getNode(int level); - // /** -// * 返回证明中指定层级的数据起始序号; +// * 最大层级数;
+// * 叶子节点(即数据节点)的层级为 0,数据节点之上的每一级父节点的层级加 1, 最大层级便是根节点的层级; // * -// * @param level // * @return +// * +// * @see MerkleTree#getLevel() // */ -// long getStartingSN(int level); - +// int getLevels(); +// // /** -// * 返回证明中指定层级的数据记录总数; +// * 返回证明中指定层级的节点的哈希; +// *

// * // * @param level +// * 参数值为 0 返回的是数据节点的哈希;
+// * 参数值为 {@link #getLevels()} 返回的是根节点的哈希; // * @return // */ -// long getDataCount(int level); +// HashDigest getHash(int level); - /** - * 返回根节点的哈希; - * - * @return - */ - default HashDigest getRootHash() { - return getHash(getLevels()); - } + MerkleNode getNode(int level); /** - * 返回数据节点的哈希; - * - * @return - */ - default HashDigest getDataHash() { - return getHash(0); - } +// * 返回根节点的哈希; +// * +// * @return +// */ +// default HashDigest getRootHash() { +// return getHash(getLevels()); +// } +// +// /** +// * 返回数据节点的哈希; +// * +// * @return +// */ +// default HashDigest getDataHash() { +// return getHash(0); +// } default MerkleDataNode getDataNode() { return (MerkleDataNode)getNode(0); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedBytesValue.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedBytesValue.java new file mode 100644 index 00000000..6436f816 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedBytesValue.java @@ -0,0 +1,455 @@ +package com.jd.blockchain.ledger; + +import java.math.BigInteger; +import java.util.Date; + +import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.crypto.PubKey; +import com.jd.blockchain.crypto.SignatureDigest; +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.io.BytesUtils; + +/** + * + * @author huanghaiquan + * + */ +public class TypedBytesValue implements BytesValue { + + public static final BytesValue NIL = new TypedBytesValue(); + + private DataType type; + private Bytes value; + + private TypedBytesValue(DataType type, byte[] bytes) { + this.type = type; + this.value = new Bytes(bytes); + } + + private TypedBytesValue(DataType type, Bytes bytes) { + this.type = type; + this.value = bytes; + } + + private TypedBytesValue(BytesValue bytesValue) { + this.type = bytesValue.getType(); + this.value = bytesValue.getValue(); + } + + private TypedBytesValue() { + this.type = DataType.NIL; + } + + + @Override + public DataType getType() { + return this.type; + } + + @Override + public Bytes getValue() { + return this.value; + } + + public Object getTypedValue() { + if (isNil()) { + return null; + } + switch (type) { + case BOOLEAN: + return toBoolean(); + case INT8: + return toInt8(); + case INT16: + return toInt16(); + case INT32: + return toInt32(); + case INT64: + return toInt64(); + case BIG_INT: + return toBigInteger(); + case TIMESTAMP: + return toDatetime(); + case TEXT: + case JSON: + case XML: + return toText(); + + case BYTES: + case VIDEO: + case IMG: + case LOCATION: + case ENCRYPTED_DATA: + return toBytesArray(); + + case HASH_DIGEST: + return toHashDegist(); + case PUB_KEY: + return toPubKey(); + case SIGNATURE_DIGEST: + return toSignatureDigest(); + + case DATA_CONTRACT: + return toBytesArray(); + default: + throw new IllegalStateException(String.format("Type [%s] has not be supported!", type)); + } + } + + /** + * 是否为空值; + *

+ * + * 仅当数据类型 {@link #getType()} 为 {@link PrimitiveType#NIL} 时返回 true,其它情况返回 false; + *

+ * + * @return + */ + public boolean isNil() { + return value == null || DataType.NIL == type; + } + + /** + * 返回 8 位整数值; + *

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

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public byte tinyValue() { + if (isNil()) { + return DataType.INT8_DEFAULT_VALUE; + } + if (DataType.INT8 == getType()) { + return toInt8(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int8!", type)); + } + + private byte toInt8() { + return value.toBytes()[0]; + } + + /** + * 返回 16 位整数值; + *

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

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public short shortValue() { + if (isNil()) { + return DataType.INT16_DEFAULT_VALUE; + } + if (DataType.INT16 == getType()) { + return toInt16(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int16!", type)); + } + + private short toInt16() { + return BytesUtils.toShort(value.toBytes(), 0); + } + + /** + * 返回 32 位整数值; + *

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

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public int intValue() { + if (isNil()) { + return DataType.INT32_DEFAULT_VALUE; + } + if (DataType.INT32 == getType()) { + return toInt32(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int32!", type)); + } + + private int toInt32() { + return BytesUtils.toInt(value.toBytes(), 0); + } + + /** + * 返回 64 位整数值; + *

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

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public long longValue() { + if (isNil()) { + return DataType.INT64_DEFAULT_VALUE; + } + if (DataType.INT64 == type) { + return toInt64(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int64!", type)); + + } + + private long toInt64() { + return BytesUtils.toLong(value.toBytes(), 0); + } + + /** + * 返回大整数值; + *

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

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public BigInteger bigIntValue() { + if (isNil()) { + return null; + } + if (DataType.BIG_INT == type) { + return toBigInteger(); + } + throw new IllegalStateException( + String.format("Type [%s] cannot be convert to BigInteger!", type)); + } + + private BigInteger toBigInteger() { + return new BigInteger(value.toBytes()); + } + + /** + * 返回布尔值; + *

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

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public boolean boolValue() { + if (isNil()) { + return DataType.BOOLEAN_DEFAULT_VALUE; + } + if (DataType.BOOLEAN == type) { + return toBoolean(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to boolean!", type)); + } + + private boolean toBoolean() { + return BytesUtils.toBoolean(value.toBytes()[0]); + } + + /** + * 返回日期时间值; + *

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

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public Date datetimeValue() { + if (isNil()) { + return null; + } + if (DataType.TIMESTAMP == type) { + return toDatetime(); + } + throw new IllegalStateException( + String.format("Type [%s] cannot be convert to datetime!", type)); + } + + private Date toDatetime() { + long ts = BytesUtils.toLong(value.toBytes()); + return new Date(ts); + } + + /** + * 返回文本值; + *

+ * + * 仅当数据类型 {@link #getType()} 为“文本类型”或“文本衍生类型”时有效; + *

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public String stringValue() { + if (isNil()) { + return null; + } + if (type.isText()) { + return toText(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to text!", type)); + } + + private String toText() { + return value.toUTF8String(); + } + + /** + * 返回字节数组的值; + *

+ * + * 仅当数据类型 {@link #getType()} 为“字节类型”或“字节衍生类型”时有效; + *

+ * + * 无效类型将引发 {@link IllegalStateException} 异常; + * + * @return + */ + public byte[] bytesValue() { + if (isNil()) { + return null; + } + if (type.isBytes()) { + return toBytesArray(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to bytes!", type)); + } + + private byte[] toBytesArray() { + return value.toBytes(); + } + + public HashDigest hashDigestValue() { + if (isNil()) { + return null; + } + if (DataType.HASH_DIGEST == type) { + return toHashDegist(); + } + throw new IllegalStateException( + String.format("Type [%s] cannot be convert to hash digest!", type)); + } + + private HashDigest toHashDegist() { + return new HashDigest(toBytesArray()); + } + + public PubKey pubKeyValue() { + if (isNil()) { + return null; + } + if (DataType.PUB_KEY == type) { + return toPubKey(); + } + throw new IllegalStateException(String.format("Type [%s] cannot be convert to pub key!", type)); + } + + private PubKey toPubKey() { + return new PubKey(toBytesArray()); + } + + public SignatureDigest signatureDigestValue() { + if (isNil()) { + return null; + } + if (DataType.SIGNATURE_DIGEST == type) { + return toSignatureDigest(); + } + throw new IllegalStateException( + String.format("Type [%s] cannot be convert to signature digest!", type)); + } + + private SignatureDigest toSignatureDigest() { + return new SignatureDigest(toBytesArray()); + } + + public static TypedBytesValue wrap(BytesValue value) { + return new TypedBytesValue(value); + } + + public static TypedBytesValue fromType(DataType type, byte[] value) { + return new TypedBytesValue(type, value); + } + + public static TypedBytesValue fromBytes(byte[] value) { + return new TypedBytesValue(DataType.BYTES, value); + } + + public static TypedBytesValue fromBytes(Bytes value) { + return new TypedBytesValue(DataType.BYTES, value); + } + + public static TypedBytesValue fromImage(byte[] value) { + return new TypedBytesValue(DataType.IMG, value); + } + + public static TypedBytesValue fromImage(Bytes value) { + return new TypedBytesValue(DataType.IMG, value); + } + + /** + * 以 UTF-8 编码从字符串转换为字节数组值; + * + * @param value + * @return + */ + public static TypedBytesValue fromText(String value) { + return new TypedBytesValue(DataType.TEXT, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromJSON(String value) { + return new TypedBytesValue(DataType.JSON, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromXML(String value) { + return new TypedBytesValue(DataType.XML, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromInt32(int value) { + return new TypedBytesValue(DataType.INT32, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromInt64(long value) { + return new TypedBytesValue(DataType.INT64, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromInt16(short value) { + return new TypedBytesValue(DataType.INT16, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromInt8(byte value) { + return new TypedBytesValue(DataType.INT8, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromTimestamp(long value) { + return new TypedBytesValue(DataType.TIMESTAMP, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromBoolean(boolean value) { + return new TypedBytesValue(DataType.BOOLEAN, BytesUtils.toBytes(value)); + } + + public static TypedBytesValue fromPubKey(PubKey pubKey) { + return new TypedBytesValue(DataType.PUB_KEY, pubKey.toBytes()); + } +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue_.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue_.java new file mode 100644 index 00000000..145344b5 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue_.java @@ -0,0 +1,472 @@ +//package com.jd.blockchain.ledger; +// +//import java.math.BigInteger; +//import java.util.Date; +// +//import com.jd.blockchain.binaryproto.PrimitiveType; +//import com.jd.blockchain.crypto.HashDigest; +//import com.jd.blockchain.crypto.PubKey; +//import com.jd.blockchain.crypto.SignatureDigest; +//import com.jd.blockchain.utils.Bytes; +//import com.jd.blockchain.utils.io.BytesUtils; +// +//public class TypedValue_ { +// +// private BytesValue bytesValue; +// +// public TypedValue_(BytesValue bytesValue) { +// this.bytesValue = bytesValue; +// } +// +// public DataType getType() { +// return bytesValue == null ? DataType.NIL : bytesValue.getType(); +// } +// +// public Object getValue() { +// if (isNil()) { +// return null; +// } +// switch (bytesValue.getType()) { +// case BOOLEAN: +// return toBoolean(); +// case INT8: +// return toInt8(); +// case INT16: +// return toInt16(); +// case INT32: +// return toInt32(); +// case INT64: +// return toInt64(); +// case BIG_INT: +// return toBigInteger(); +// case TIMESTAMP: +// return toDatetime(); +// case TEXT: +// case JSON: +// case XML: +// return toText(); +// +// case BYTES: +// case VIDEO: +// case IMG: +// case LOCATION: +// case ENCRYPTED_DATA: +// return toBytesArray(); +// +// case HASH_DIGEST: +// return toHashDegist(); +// case PUB_KEY: +// return toPubKey(); +// case SIGNATURE_DIGEST: +// return toSignatureDigest(); +// +// case DATA_CONTRACT: +// return toBytesArray(); +// default: +// throw new IllegalStateException(String.format("Type [%s] has not be supported!", bytesValue.getType())); +// } +// } +// +// /** +// * 是否为空值; +// *

+// * +// * 仅当数据类型 {@link #getType()} 为 {@link PrimitiveType#NIL} 时返回 true,其它情况返回 false; +// *

+// * +// * @return +// */ +// public boolean isNil() { +// return bytesValue == null || DataType.NIL == bytesValue.getType(); +// } +// +// /** +// * 返回 8 位整数值; +// *

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

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public byte tinyValue() { +// if (isNil()) { +// return DataType.INT8_DEFAULT_VALUE; +// } +// if (DataType.INT8 == getType()) { +// return toInt8(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int8!", bytesValue.getType())); +// } +// +// private byte toInt8() { +// return bytesValue.getValue().toBytes()[0]; +// } +// +// /** +// * 返回 16 位整数值; +// *

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

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public short shortValue() { +// if (isNil()) { +// return DataType.INT16_DEFAULT_VALUE; +// } +// if (DataType.INT16 == getType()) { +// return toInt16(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int16!", bytesValue.getType())); +// } +// +// private short toInt16() { +// return BytesUtils.toShort(bytesValue.getValue().toBytes(), 0); +// } +// +// /** +// * 返回 32 位整数值; +// *

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

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public int intValue() { +// if (isNil()) { +// return DataType.INT32_DEFAULT_VALUE; +// } +// if (DataType.INT32 == getType()) { +// return toInt32(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int32!", bytesValue.getType())); +// } +// +// private int toInt32() { +// return BytesUtils.toInt(bytesValue.getValue().toBytes(), 0); +// } +// +// /** +// * 返回 64 位整数值; +// *

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

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public long longValue() { +// if (isNil()) { +// return DataType.INT64_DEFAULT_VALUE; +// } +// if (DataType.INT64 == bytesValue.getType()) { +// return toInt64(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to Int64!", bytesValue.getType())); +// +// } +// +// private long toInt64() { +// return BytesUtils.toLong(bytesValue.getValue().toBytes(), 0); +// } +// +// /** +// * 返回大整数值; +// *

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

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public BigInteger bigIntValue() { +// if (isNil()) { +// return null; +// } +// if (DataType.BIG_INT == bytesValue.getType()) { +// return toBigInteger(); +// } +// throw new IllegalStateException( +// String.format("Type [%s] cannot be convert to BigInteger!", bytesValue.getType())); +// } +// +// private BigInteger toBigInteger() { +// return new BigInteger(bytesValue.getValue().toBytes()); +// } +// +// /** +// * 返回布尔值; +// *

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

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public boolean boolValue() { +// if (isNil()) { +// return DataType.BOOLEAN_DEFAULT_VALUE; +// } +// if (DataType.BOOLEAN == bytesValue.getType()) { +// return toBoolean(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to boolean!", bytesValue.getType())); +// } +// +// private boolean toBoolean() { +// return BytesUtils.toBoolean(bytesValue.getValue().toBytes()[0]); +// } +// +// /** +// * 返回日期时间值; +// *

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

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public Date datetimeValue() { +// if (isNil()) { +// return null; +// } +// if (DataType.TIMESTAMP == bytesValue.getType()) { +// return toDatetime(); +// } +// throw new IllegalStateException( +// String.format("Type [%s] cannot be convert to datetime!", bytesValue.getType())); +// } +// +// private Date toDatetime() { +// long ts = BytesUtils.toLong(bytesValue.getValue().toBytes()); +// return new Date(ts); +// } +// +// /** +// * 返回文本值; +// *

+// * +// * 仅当数据类型 {@link #getType()} 为“文本类型”或“文本衍生类型”时有效; +// *

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public String stringValue() { +// if (isNil()) { +// return null; +// } +// DataType type = bytesValue.getType(); +// if (type.isText()) { +// return toText(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to text!", type)); +// } +// +// private String toText() { +// return bytesValue.getValue().toUTF8String(); +// } +// +// /** +// * 返回字节数组的值; +// *

+// * +// * 仅当数据类型 {@link #getType()} 为“字节类型”或“字节衍生类型”时有效; +// *

+// * +// * 无效类型将引发 {@link IllegalStateException} 异常; +// * +// * @return +// */ +// public byte[] bytesValue() { +// if (isNil()) { +// return null; +// } +// DataType type = bytesValue.getType(); +// if (type.isBytes()) { +// return toBytesArray(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to bytes!", type)); +// } +// +// private byte[] toBytesArray() { +// return bytesValue.getValue().toBytes(); +// } +// +// public HashDigest hashDigestValue() { +// if (isNil()) { +// return null; +// } +// if (DataType.HASH_DIGEST == bytesValue.getType()) { +// return toHashDegist(); +// } +// throw new IllegalStateException( +// String.format("Type [%s] cannot be convert to hash digest!", bytesValue.getType())); +// } +// +// private HashDigest toHashDegist() { +// return new HashDigest(toBytesArray()); +// } +// +// public PubKey pubKeyValue() { +// if (isNil()) { +// return null; +// } +// if (DataType.PUB_KEY == bytesValue.getType()) { +// return toPubKey(); +// } +// throw new IllegalStateException(String.format("Type [%s] cannot be convert to pub key!", bytesValue.getType())); +// } +// +// private PubKey toPubKey() { +// return new PubKey(toBytesArray()); +// } +// +// public SignatureDigest signatureDigestValue() { +// if (isNil()) { +// return null; +// } +// if (DataType.SIGNATURE_DIGEST == bytesValue.getType()) { +// return toSignatureDigest(); +// } +// throw new IllegalStateException( +// String.format("Type [%s] cannot be convert to signature digest!", bytesValue.getType())); +// } +// +// private SignatureDigest toSignatureDigest() { +// return new SignatureDigest(toBytesArray()); +// } +// +// public BytesValue convertToBytesValue() { +// return bytesValue == null ? TypedBytesValue.NIL : bytesValue; +// } +// +// public static TypedBytesValue fromText(String key, String value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromText(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromBoolean(String key, boolean value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromBoolean(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt8(String key, byte value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt8(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt16(String key, short value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt16(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt32(String key, int value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt32(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt64(String key, long value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt64(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromBytes(String key, byte[] value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromBytes(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromTimestamp(String key, long value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromTimestamp(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromJSON(String key, String value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromJSON(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromXML(String key, String value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromXML(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromImage(String key, byte[] value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromImage(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromText(Bytes key, String value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromText(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromBoolean(Bytes key, boolean value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromBoolean(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt8(Bytes key, byte value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt8(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt16(Bytes key, short value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt16(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt32(Bytes key, int value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt32(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromInt64(Bytes key, long value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromInt64(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromBytes(Bytes key, byte[] value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromBytes(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromTimestamp(Bytes key, long value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromTimestamp(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromJSON(Bytes key, String value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromJSON(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromXML(Bytes key, String value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromXML(value); +// return new TypedBytesValue(bytesValue); +// } +// +// public static TypedBytesValue fromImage(Bytes key, byte[] value, long version) { +// BytesValue bytesValue = TypedBytesValue.fromImage(value); +// return new TypedBytesValue(bytesValue); +// } +// +//} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java new file mode 100644 index 00000000..0fcfd9ef --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java @@ -0,0 +1,12 @@ +package com.jd.blockchain.ledger; + +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.consts.DataCodes; +import com.jd.blockchain.crypto.PubKey; + +@DataContract(code= DataCodes.USER_ACCOUNT_HEADER) +public interface UserAccountHeader extends AccountHeader { + + PubKey getDataPubKey(); + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java index 3ad9ed85..c7b14d1a 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfo.java @@ -2,11 +2,8 @@ package com.jd.blockchain.ledger; import com.jd.blockchain.binaryproto.DataContract; import com.jd.blockchain.consts.DataCodes; -import com.jd.blockchain.crypto.PubKey; -@DataContract(code= DataCodes.USER_ACCOUNT_HEADER) -public interface UserInfo extends AccountHeader { - - PubKey getDataPubKey(); - +@DataContract(code = DataCodes.USER_INFO) +public interface UserInfo extends UserAccountHeader { + } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java index 0664fdb9..bcc688cf 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class BooleanToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return BytesData.fromBoolean((boolean) value); + return TypedBytesValue.fromBoolean((boolean) value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java index f4871515..d455e471 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,9 +21,9 @@ public class BytesToBytesValueResolver extends AbstractBytesValueResolver { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } if (type.equals(byte[].class)) { - return BytesData.fromBytes((byte[]) value); + return TypedBytesValue.fromBytes((byte[]) value); } - return BytesData.fromBytes((Bytes) value); + return TypedBytesValue.fromBytes((Bytes) value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java index a8400f02..6eec5e6f 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class IntegerToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return BytesData.fromInt32((int) value); + return TypedBytesValue.fromInt32((int) value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java index fa11bcf4..9ae9910e 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class LongToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return BytesData.fromInt64((long)value); + return TypedBytesValue.fromInt64((long)value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java index b8eea38c..220d6121 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class ShortToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return BytesData.fromInt16((short)value); + return TypedBytesValue.fromInt16((short)value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java index dca8e5d1..56da60bf 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -26,10 +26,10 @@ public class StringToBytesValueResolver extends AbstractBytesValueResolver { // 类型判断 String valString = (String)value; if (JSONSerializeUtils.isJSON(valString)) { - return BytesData.fromJSON(valString); + return TypedBytesValue.fromJSON(valString); } // 暂不处理XML格式 - return BytesData.fromText(valString); + return TypedBytesValue.fromText(valString); } @Override 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 b2ccef13..f0e1a18b 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 @@ -1,7 +1,7 @@ package com.jd.blockchain.transaction; import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.utils.Bytes; @@ -26,14 +26,14 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe @Override public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { - BytesValue bytesValue = BytesData.fromBytes(value); + BytesValue bytesValue = TypedBytesValue.fromBytes(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) { - BytesValue bytesValue = BytesData.fromImage(value); + BytesValue bytesValue = TypedBytesValue.fromImage(value); operation.set(key, bytesValue, expVersion); return this; } @@ -45,42 +45,42 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe @Override public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { - BytesValue bytesValue = BytesData.fromText(value); + BytesValue bytesValue = TypedBytesValue.fromText(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) { - BytesValue bytesValue = BytesData.fromBytes(value); + BytesValue bytesValue = TypedBytesValue.fromBytes(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) { - BytesValue bytesValue = BytesData.fromInt64(value); + BytesValue bytesValue = TypedBytesValue.fromInt64(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { - BytesValue bytesValue = BytesData.fromJSON(value); + BytesValue bytesValue = TypedBytesValue.fromJSON(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) { - BytesValue bytesValue = BytesData.fromXML(value); + BytesValue bytesValue = TypedBytesValue.fromXML(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) { - BytesValue bytesValue = BytesData.fromTimestamp(value); + BytesValue bytesValue = TypedBytesValue.fromTimestamp(value); operation.set(key, bytesValue, expVersion); return this; } diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java index d010ae6f..271063ec 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesDataList; import com.jd.blockchain.ledger.BytesValueList; import com.jd.blockchain.ledger.ContractEventSendOperation; @@ -41,7 +41,7 @@ public class ContractEventSendOpTemplateTest { DataContractRegistry.register(ContractEventSendOperation.class); DataContractRegistry.register(Operation.class); String contractAddress = "zhangsan-address", event = "zhangsan-event"; - BytesValueList args = new BytesDataList(BytesData.fromText("zhangsan-args")); + BytesValueList args = new BytesDataList(TypedBytesValue.fromText("zhangsan-args")); data = new ContractEventSendOpTemplate(Bytes.fromString(contractAddress), event, args); } diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java index d8b33048..c75eeed7 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; @@ -41,11 +41,11 @@ public class DataAccountKVSetOpTemplateTest { String accountAddress = "zhangsandhakhdkah"; data = new DataAccountKVSetOpTemplate(Bytes.fromString(accountAddress)); KVData kvData1 = - new KVData("test1", BytesData.fromText("zhangsan"), 9999L); + new KVData("test1", TypedBytesValue.fromText("zhangsan"), 9999L); KVData kvData2 = - new KVData("test2", BytesData.fromText("lisi"), 9990L); + new KVData("test2", TypedBytesValue.fromText("lisi"), 9990L); KVData kvData3 = - new KVData("test3", BytesData.fromText("wangwu"), 1990L); + new KVData("test3", TypedBytesValue.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/KVDataTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java index d1a6fcb9..8a914f7f 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; import com.jd.blockchain.transaction.KVData; @@ -38,7 +38,7 @@ public class KVDataTest { byte[] value = "test-value".getBytes(); long expectedVersion = 9999L; - kvData = new KVData(key, BytesData.fromBytes(value), expectedVersion); + kvData = new KVData(key, TypedBytesValue.fromBytes(value), expectedVersion); } @Test diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java index e4aea5a0..ef63137f 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java @@ -151,7 +151,7 @@ public class ClientResolveUtil { String realValBase58 = valueObj.getJSONObject("value").getString("value"); String key = currWriteSetObj.getString("key"); DataType dataType = DataType.valueOf(typeStr); - BytesValue bytesValue = BytesData.fromType(dataType, Base58Utils.decode(realValBase58)); + BytesValue bytesValue = TypedBytesValue.fromType(dataType, Base58Utils.decode(realValBase58)); KVData kvData = new KVData(key, bytesValue, expectedVersion); kvOperation.set(kvData); } @@ -200,7 +200,7 @@ public class ClientResolveUtil { JSONObject pubKeyObj = currConsensusParticipant.getJSONObject("pubKey"); String pubKeyBase58 = pubKeyObj.getString("value"); // 生成ParticipantNode对象 - ParticipantCertData participantCertData = new ParticipantCertData(id, address, name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes())); + ParticipantCertData participantCertData = new ParticipantCertData(id, address, name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes()), null); participantNodes[i] = participantCertData; } ledgerInitSettingData.setConsensusParticipants(participantNodes); @@ -294,11 +294,12 @@ public class ClientResolveUtil { this.pubKey = participantNode.getPubKey(); } - public ParticipantCertData(int id, Bytes address, String name, PubKey pubKey) { + public ParticipantCertData(int id, Bytes address, String name, PubKey pubKey, ParticipantNodeState participantNodeState) { this.id = id; this.address = address; this.name = name; this.pubKey = pubKey; + this.participantNodeState = participantNodeState; } diff --git a/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java b/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java index 773b3748..da809c0a 100644 --- a/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java +++ b/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java @@ -1,8 +1,8 @@ package com.jd.blockchain.storage.service.impl.redis; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; diff --git a/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java b/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java index 978fd8c5..40dba131 100644 --- a/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java +++ b/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java @@ -7,9 +7,9 @@ import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.collections4.map.LRUMap; import org.rocksdb.*; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; import com.jd.blockchain.utils.io.BytesUtils; /** diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVEntry.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVEntry.java deleted file mode 100644 index a18f6740..00000000 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVEntry.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.jd.blockchain.storage.service; - -import com.jd.blockchain.utils.Bytes; - -/** - * 版本化的键值数据项; - * - * @author huanghaiquan - * - */ -public interface VersioningKVEntry { - -// String getKey(); - Bytes getKey(); - - long getVersion(); - - byte[] getValue(); - -} \ No newline at end of file diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java index 711606d3..dfa26404 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java @@ -1,6 +1,7 @@ package com.jd.blockchain.storage.service; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; /** * Versioning Key-Value Storage @@ -40,7 +41,7 @@ public interface VersioningKVStorage extends BatchStorageService { * @param version * @return */ - VersioningKVEntry getEntry(Bytes key, long version); + VersioningKVEntry getEntry(Bytes key, long version); /** * Return the specified verson's value;
diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java index 7b292248..8f334ca3 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java @@ -7,10 +7,10 @@ import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveTask; import com.jd.blockchain.storage.service.ExPolicyKVStorage; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningKVEntry; /** * {@link BufferedKVStorage} 缓冲写入的KV存储;
@@ -77,9 +77,9 @@ public class BufferedKVStorage implements VersioningKVStorage, ExPolicyKVStorage } return ws.getLatestVersion(); } - + @Override - public VersioningKVEntry getEntry(Bytes key, long version) { + public VersioningKVEntry getEntry(Bytes key, long version) { VersioningWritingSet ws = versioningCache.get(key); if (ws == null) { return origVersioningStorage.getEntry(key, version); @@ -484,7 +484,7 @@ public class BufferedKVStorage implements VersioningKVStorage, ExPolicyKVStorage return startingVersion; } - public VersioningKVEntry getEntry(long version) { + public VersioningKVEntry getEntry(long version) { byte[] value = get(version); if (value == null) { return null; @@ -505,7 +505,7 @@ public class BufferedKVStorage implements VersioningKVStorage, ExPolicyKVStorage } } - private static class VersioningKVData implements VersioningKVEntry { + private static class VersioningKVData implements VersioningKVEntry { private Bytes key; diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java index 0c2192a3..8bce7e32 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java @@ -5,9 +5,9 @@ import java.util.Set; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.KVStorageService; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; import com.jd.blockchain.utils.io.BytesMap; public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, KVStorageService, BytesMap { diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java index 684c75fe..4d1e1509 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java @@ -1,24 +1,23 @@ package com.jd.blockchain.storage.service.utils; -import com.jd.blockchain.storage.service.VersioningKVEntry; -import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; -public class VersioningKVData implements VersioningKVEntry { +public class VersioningKVData implements VersioningKVEntry { - private Bytes key; + private K key; private long version; - private byte[] value; + private V value; - public VersioningKVData(Bytes key, long version, byte[] value) { + public VersioningKVData(K key, long version, V value) { this.key = key; this.version = version; this.value = value; } @Override - public Bytes getKey() { + public K getKey() { return key; } @@ -28,7 +27,7 @@ public class VersioningKVData implements VersioningKVEntry { } @Override - public byte[] getValue() { + public V getValue() { return value; } diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java index 3c4855e3..e9aee04b 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java @@ -5,9 +5,9 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import com.jd.blockchain.storage.service.VersioningKVEntry; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningKVEntry; import com.jd.blockchain.utils.io.BytesMap; public class VersioningKVStorageMap implements VersioningKVStorage, BytesMap { diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java new file mode 100644 index 00000000..20b3da6f --- /dev/null +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java @@ -0,0 +1,122 @@ +package com.jd.blockchain.utils; + +public abstract class RegionMap implements VersioningMap { + + private K region; + + private VersioningMap dataMap; + + public RegionMap(K region, VersioningMap dataMap) { + this.region = region; + this.dataMap = dataMap; + } + + @Override + public long setValue(K key, V value, long version) { + K dataKey = concatKey(region, key); + return dataMap.setValue(dataKey, value, version); + } + + @Override + public V getValue(K key, long version) { + K dataKey = concatKey(region, key); + return dataMap.getValue(dataKey, version); + } + + @Override + public V getValue(K key) { + K dataKey = concatKey(region, key); + return dataMap.getValue(dataKey); + } + + @Override + public long getVersion(K key) { + K dataKey = concatKey(region, key); + return dataMap.getVersion(dataKey); + } + + @Override + public VersioningKVEntry getDataEntry(K key) { + K dataKey = concatKey(region, key); + VersioningKVEntry entry = dataMap.getDataEntry(dataKey); + return new KVEntryWrapper(key, entry); + } + + @Override + public VersioningKVEntry getDataEntry(K key, long version) { + K dataKey = concatKey(region, key); + VersioningKVEntry entry = dataMap.getDataEntry(dataKey, version); + return new KVEntryWrapper(key, entry); + } + + /** + * 以指定的前缀组成新的key; + * + * @param prefix + * @param key + * @return + */ + protected abstract K concatKey(K prefix, K key); + + public static VersioningMap newRegion(Bytes region, VersioningMap dataMap) { + return new BytesKeyRegionMap(region, dataMap); + } + + public static VersioningMap newRegion(String region, VersioningMap dataMap) { + return new StringKeyRegionMap(region, dataMap); + } + + private static class BytesKeyRegionMap extends RegionMap { + + public BytesKeyRegionMap(Bytes region, VersioningMap dataMap) { + super(region, dataMap); + } + + @Override + protected Bytes concatKey(Bytes prefix, Bytes key) { + return prefix.concat(key); + } + + } + + private static class StringKeyRegionMap extends RegionMap { + + public StringKeyRegionMap(String region, VersioningMap dataMap) { + super(region, dataMap); + } + + @Override + protected String concatKey(String prefix, String key) { + return prefix + key; + } + + } + + private static class KVEntryWrapper implements VersioningKVEntry { + + private K key; + + private VersioningKVEntry entry; + + public KVEntryWrapper(K key, VersioningKVEntry entry) { + this.key = key; + this.entry = entry; + } + + @Override + public K getKey() { + return key; + } + + @Override + public long getVersion() { + return entry.getVersion(); + } + + @Override + public V getValue() { + return entry.getValue(); + } + + } +} diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java new file mode 100644 index 00000000..b92eda41 --- /dev/null +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java @@ -0,0 +1,17 @@ +package com.jd.blockchain.utils; + +/** + * 版本化的键值数据项; + * + * @author huanghaiquan + * + */ +public interface VersioningKVEntry{ + + K getKey(); + + long getVersion(); + + V getValue(); + +} \ No newline at end of file diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningMap.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningMap.java new file mode 100644 index 00000000..84d198a9 --- /dev/null +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningMap.java @@ -0,0 +1,116 @@ +package com.jd.blockchain.utils; + +public interface VersioningMap { + +// long getDataCount(); + +// /** +// * Create or update the value associated the specified key if the version +// * checking is passed.
+// * +// * The value of the key will be updated only if it's latest version equals the +// * specified version argument.
+// * If the key doesn't exist, it will be created when the version arg was -1. +// *

+// * 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 latest 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;
+// * If this operation fail by version checking or other reason, then +// * return -1; +// */ +// long setValue(String key, byte[] value, long version); + + /** + * Create or update the value associated the specified key if the version + * checking is passed.
+ * + * The value of the key will be updated only if it's latest version equals the + * specified version argument.
+ * If the key doesn't exist, it will be created when the version arg was -1. + *

+ * 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 latest 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;
+ * If this operation fail by version checking or other reason, then + * return -1; + */ + long setValue(K key, V value, long version); + +// /** +// * Return the specified version's value;
+// * +// * If the key with the specified version doesn't exist, then return null;
+// * If the version is specified to -1, then return the latest version's value; +// * +// * @param key +// * @param version +// */ +// byte[] getValue(String key, long version); + + /** + * Return the specified version's value;
+ * + * If the key with the specified version doesn't exist, then return null;
+ * If the version is specified to -1, then return the latest version's value; + * + * @param key + * @param version + */ + V getValue(K key, long version); + +// /** +// * Return the latest version's value; +// * +// * @param key +// * @return return null if not exist; +// */ +// byte[] getValue(String key); + + /** + * Return the latest version's value; + * + * @param key + * @return return null if not exist; + */ + V getValue(K key); + +// /** +// * Return the latest version entry associated the specified key; If the key +// * doesn't exist, then return -1; +// * +// * @param key +// * @return +// */ +// long getVersion(String key); + + /** + * Return the latest version entry associated the specified key; If the key + * doesn't exist, then return -1; + * + * @param key + * @return + */ + long getVersion(K key); + + /** + * + * @param key + * @return Null if the key doesn't exist! + */ + VersioningKVEntry getDataEntry(K key); + + VersioningKVEntry getDataEntry(K key, long version); + +} \ No newline at end of file From 6167bb7d89511f153895902cf1ee0ea7b5d5de1c Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Fri, 27 Sep 2019 22:32:04 +0800 Subject: [PATCH 3/9] Added MerkleDataCluster; --- .../ledger/core/MerkleDataCluster.java | 76 +++++++++++++++++++ .../blockchain/ledger/core/MerkleDataSet.java | 8 +- 2 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java new file mode 100644 index 00000000..d8adbcc2 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java @@ -0,0 +1,76 @@ +package com.jd.blockchain.ledger.core; + +import java.util.Map; + +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.MerkleProof; +import com.jd.blockchain.ledger.MerkleSnapshot; +import com.jd.blockchain.storage.service.ExPolicyKVStorage; +import com.jd.blockchain.storage.service.VersioningKVStorage; +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.Transactional; +import com.jd.blockchain.utils.VersioningMap; + +public class MerkleDataCluster implements Transactional, MerkleSnapshot { + + private boolean readonly; + + private MerkleDataSet rootDS; + + private Map partitions; + + /** + * Create an empty readable {@link MerkleDataCluster} instance; + */ + public MerkleDataCluster(CryptoSetting setting, Bytes keyPrefix, ExPolicyKVStorage exPolicyStorage, + VersioningKVStorage versioningStorage) { + this(null, setting, keyPrefix, exPolicyStorage, versioningStorage, false); + } + + /** + * Create an {@link MerkleDataCluster} instance; + * + * @param rootHash root hash of this {@link MerkleDataCluster} instance; + * @param readonly whether read only; + */ + public MerkleDataCluster(HashDigest rootHash, CryptoSetting setting, Bytes keyPrefix, + ExPolicyKVStorage exPolicyStorage, VersioningKVStorage versioningStorage, boolean readonly) { + this.rootDS = new MerkleDataSet(rootHash, setting, keyPrefix, exPolicyStorage, versioningStorage, readonly); + } + + @Override + public HashDigest getRootHash() { + return rootDS.getRootHash(); + } + + @Override + public boolean isUpdated() { + return rootDS.isUpdated(); + } + + public VersioningMap getPartition(Bytes name) { + return getPartition(name, false); + } + + public VersioningMap getPartition(Bytes name, boolean create) { + + } + + public VersioningMap createPartition(Bytes name) { + + } + + @Override + public void commit() { + // TODO Auto-generated method stub + + } + + @Override + public void cancel() { + // TODO Auto-generated method stub + + } + +} 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 0ea23990..896a8f37 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 @@ -31,11 +31,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM */ public static final int MAX_SIZE_OF_VALUE = 4 * 1024 * 1024; - public static final String ORIG_KEY_SEPERATOR = LedgerConsts.KEY_SEPERATOR; - - public static final Bytes SN_PREFIX = Bytes.fromString("SN" + ORIG_KEY_SEPERATOR); - public static final Bytes DATA_PREFIX = Bytes.fromString("KV" + ORIG_KEY_SEPERATOR); - public static final Bytes MERKLE_TREE_PREFIX = Bytes.fromString("MKL" + ORIG_KEY_SEPERATOR); + public static final Bytes SN_PREFIX = Bytes.fromString("SN" + LedgerConsts.KEY_SEPERATOR); + public static final Bytes DATA_PREFIX = Bytes.fromString("KV" + LedgerConsts.KEY_SEPERATOR); + public static final Bytes MERKLE_TREE_PREFIX = Bytes.fromString("MKL" + LedgerConsts.KEY_SEPERATOR); private final Bytes snKeyPrefix; private final Bytes dataKeyPrefix; From 9a381ebfe9e9a25d46fd9b441db5ae7b495cb75b Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Tue, 22 Oct 2019 23:35:26 +0800 Subject: [PATCH 4/9] Refactor ledger account; --- .../gateway/web/BlockBrowserController.java | 10 +- .../ledger/core/AccountAccessPolicy.java | 4 +- .../ledger/core/AccountDecorator.java | 44 ++ .../blockchain/ledger/core/BytesKeyMap.java | 8 - .../ledger/core/ContractAccount.java | 57 +-- .../ledger/core/ContractAccountSet.java | 9 +- .../blockchain/ledger/core/DataAccount.java | 482 +++++++++--------- .../ledger/core/DataAccountSet.java | 9 +- .../ledger/core/EmptyAccountSet.java | 6 +- .../ledger/core/GenericAccount.java | 83 --- .../ledger/core/LedgerQueryService.java | 17 +- .../blockchain/ledger/core/MerkleAccount.java | 110 +++- .../ledger/core/MerkleAccountSet.java | 108 ++-- .../ledger/core/MerkleDataCluster.java | 22 +- .../ledger/core/OpeningAccessPolicy.java | 4 +- .../ledger/core/ParticipantDataset.java | 2 +- .../ledger/core/RolePrivilegeDataset.java | 7 +- .../blockchain/ledger/core/StringKeyMap.java | 7 - .../ledger/core/TransactionSet.java | 3 +- .../blockchain/ledger/core/UserAccount.java | 63 ++- .../ledger/core/UserAccountSet.java | 30 +- .../ledger/core/UserRoleDataset.java | 6 +- .../core/handles/ContractLedgerContext.java | 43 +- .../DataAccountKVSetOperationHandle.java | 2 +- .../ledger/core/AccountSetTest.java | 5 +- .../ledger/core/BaseAccountTest.java | 22 +- .../ledger/core/ContractInvokingTest.java | 31 +- .../jd/blockchain/ledger/AccountHeader.java | 40 +- .../jd/blockchain/ledger/BytesDataList.java | 8 +- .../blockchain/ledger/BytesValueEncoding.java | 2 +- .../jd/blockchain/ledger/ContractInfo.java | 2 +- .../{TypedBytesValue.java => TypedValue.java} | 76 +-- .../blockchain/ledger/UserAccountHeader.java | 2 +- .../resolver/BooleanToBytesValueResolver.java | 4 +- .../resolver/BytesToBytesValueResolver.java | 6 +- .../resolver/IntegerToBytesValueResolver.java | 4 +- .../resolver/LongToBytesValueResolver.java | 4 +- .../resolver/ShortToBytesValueResolver.java | 4 +- .../resolver/StringToBytesValueResolver.java | 6 +- .../transaction/BlockchainQueryService.java | 10 +- .../DataAccountKVSetOperationBuilderImpl.java | 18 +- .../ContractEventSendOpTemplateTest.java | 4 +- .../DataAccountKVSetOpTemplateTest.java | 8 +- .../com/jd/blockchain/ledger/KVDataTest.java | 4 +- .../peer/web/LedgerQueryController.java | 16 +- .../sdk/converters/ClientResolveUtil.java | 2 +- .../sdk/proxy/BlockchainServiceProxy.java | 10 +- .../sdk/proxy/HttpBlockchainQueryService.java | 8 +- .../sdk/test/SDK_GateWay_Query_Test_.java | 6 +- .../jd/blockchain/intgr/IntegrationTest.java | 8 +- .../MerkleDatasetPerformanceTester.java | 7 +- 51 files changed, 747 insertions(+), 706 deletions(-) create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java delete mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java delete mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java delete mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java rename source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/{TypedBytesValue.java => TypedValue.java} (78%) diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java index 50f528ba..f39e9424 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java @@ -23,7 +23,7 @@ import com.jd.blockchain.crypto.KeyGenUtils; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.gateway.PeerService; import com.jd.blockchain.gateway.service.DataRetrievalService; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.ContractInfo; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.KVInfoVO; @@ -252,7 +252,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/address/{address}") @Override - public AccountHeader getDataAccount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity getDataAccount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @PathVariable(name = "address") String address) { return peerService.getQueryService().getDataAccount(ledgerHash, address); @@ -594,7 +594,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { */ @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users") @Override - public AccountHeader[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { return peerService.getQueryService().getUsers(ledgerHash, fromIndex, count); @@ -602,7 +602,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts") @Override - public AccountHeader[] getDataAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity[] getDataAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { return peerService.getQueryService().getDataAccounts(ledgerHash, fromIndex, count); @@ -610,7 +610,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts") @Override - public AccountHeader[] getContractAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity[] getContractAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { return peerService.getQueryService().getContractAccounts(ledgerHash, fromIndex, count); 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 2e025bf2..3ffa5536 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 @@ -2,7 +2,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.utils.Bytes; /** @@ -19,7 +19,7 @@ public interface AccountAccessPolicy { * @param account * @return Return true if it satisfies this policy, or false if it doesn't; */ - boolean checkDataWriting(AccountHeader account); + boolean checkDataWriting(BlockchainIdentity account); boolean checkRegistering(Bytes address, PubKey pubKey); diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java new file mode 100644 index 00000000..a0fddbe1 --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java @@ -0,0 +1,44 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.HashProof; +import com.jd.blockchain.ledger.MerkleSnapshot; +import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.VersioningMap; + +public class AccountDecorator implements LedgerAccount, HashProvable, MerkleSnapshot{ + + private MerkleAccount mklAccount; + + public AccountDecorator(MerkleAccount mklAccount) { + this.mklAccount = mklAccount; + } + + protected VersioningMap getHeaders() { + return mklAccount.getHeaders(); + } + + + @Override + public HashDigest getRootHash() { + return mklAccount.getRootHash(); + } + + @Override + public HashProof getProof(Bytes key) { + return mklAccount.getProof(key); + } + + @Override + public BlockchainIdentity getID() { + return mklAccount.getID(); + } + + @Override + public VersioningMap getDataset() { + return mklAccount.getDataset(); + } + +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java deleted file mode 100644 index e4b6ffeb..00000000 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/BytesKeyMap.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.jd.blockchain.ledger.core; - -import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningMap; - -public interface BytesKeyMap extends VersioningMap { - -} 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 88583505..514ddf0f 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 @@ -1,78 +1,69 @@ package com.jd.blockchain.ledger.core; -import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.ContractInfo; -import com.jd.blockchain.ledger.MerkleProof; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.utils.Bytes; -public class ContractAccount implements ContractInfo { +public class ContractAccount extends AccountDecorator implements ContractInfo { private static final Bytes CONTRACT_INFO_PREFIX = Bytes.fromString("INFO" + LedgerConsts.KEY_SEPERATOR); private static final Bytes CHAIN_CODE_KEY = Bytes.fromString("CHAIN-CODE"); - private MerkleAccount accBase; - - public ContractAccount(MerkleAccount accBase) { - this.accBase = accBase; + public ContractAccount(MerkleAccount mklAccount) { + super(mklAccount); } @Override public Bytes getAddress() { - return accBase.getAddress(); + return getID().getAddress(); } @Override public PubKey getPubKey() { - return accBase.getPubKey(); - } - - @Override - public HashDigest getRootHash() { - return accBase.getRootHash(); + return getID().getPubKey(); } - public MerkleProof getChaincodeProof() { - return accBase.getProof(CHAIN_CODE_KEY); - } - - public MerkleProof getPropertyProof(Bytes key) { - return accBase.getProof(encodePropertyKey(key)); - } +// public MerkleProof getChaincodeProof() { +// return getHeaders().getProof(CHAIN_CODE_KEY); +// } +// +// public MerkleProof getPropertyProof(Bytes key) { +// return getHeaders().getProof(encodePropertyKey(key)); +// } public long setChaincode(byte[] chaincode, long version) { - BytesValue bytesValue = TypedBytesValue.fromBytes(chaincode); - return accBase.setValue(CHAIN_CODE_KEY, bytesValue, version); + BytesValue bytesValue = TypedValue.fromBytes(chaincode); + return getHeaders().setValue(CHAIN_CODE_KEY, bytesValue, version); } public byte[] getChainCode() { - return accBase.getValue(CHAIN_CODE_KEY).getValue().toBytes(); + return getHeaders().getValue(CHAIN_CODE_KEY).getValue().toBytes(); } public byte[] getChainCode(long version) { - return accBase.getValue(CHAIN_CODE_KEY, version).getValue().toBytes(); + return getHeaders().getValue(CHAIN_CODE_KEY, version).getValue().toBytes(); } public long getChaincodeVersion() { - return accBase.getVersion(CHAIN_CODE_KEY); + return getHeaders().getVersion(CHAIN_CODE_KEY); } public long setProperty(Bytes key, String value, long version) { - BytesValue bytesValue = TypedBytesValue.fromText(value); - return accBase.setValue(encodePropertyKey(key), bytesValue, version); + BytesValue bytesValue = TypedValue.fromText(value); + return getHeaders().setValue(encodePropertyKey(key), bytesValue, version); } public String getProperty(Bytes key) { - BytesValue bytesValue = accBase.getValue(encodePropertyKey(key)); - return TypedBytesValue.toText(bytesValue); + BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key)); + return TypedValue.wrap(bytesValue).stringValue(); } public String getProperty(Bytes key, long version) { - BytesValue bytesValue = accBase.getValue(encodePropertyKey(key), version); - return TypedBytesValue.toText(bytesValue); + BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key), version); + return TypedValue.wrap(bytesValue).stringValue(); } private Bytes encodePropertyKey(Bytes key) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java index 5f4c7855..8d9fdbda 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java @@ -2,7 +2,7 @@ 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.BlockchainIdentity; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.DigitalSignature; import com.jd.blockchain.ledger.MerkleProof; @@ -17,17 +17,18 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { public ContractAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { - accountSet = new MerkleAccountSet(cryptoSetting, prefix, exStorage, verStorage, accessPolicy); + accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, accessPolicy); } public ContractAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, AccountAccessPolicy accessPolicy) { - accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, prefix, exStorage, verStorage, readonly, accessPolicy); + accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, + readonly, accessPolicy); } @Override - public AccountHeader[] getHeaders(int fromIndex, int count) { + public BlockchainIdentity[] getHeaders(int fromIndex, int count) { return accountSet.getHeaders(fromIndex, count); } 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 3abbdfd7..324de791 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 @@ -1,268 +1,242 @@ 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.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.KVDataObject; import com.jd.blockchain.ledger.MerkleProof; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.utils.Bytes; -public class DataAccount implements AccountHeader, MerkleProvable { - - private MerkleAccount baseAccount; - - public DataAccount(MerkleAccount accBase) { - this.baseAccount = accBase; - } - - @Override - public Bytes getAddress() { - return baseAccount.getAddress(); - } - - @Override - public PubKey getPubKey() { - return baseAccount.getPubKey(); - } - - @Override - public HashDigest getRootHash() { - return baseAccount.getRootHash(); - } - - /** - * 返回指定数据的存在性证明; - */ - @Override - public MerkleProof getProof(Bytes key) { - return baseAccount.getProof(key); - } +public class DataAccount extends AccountDecorator { + + public DataAccount(MerkleAccount mklAccount) { + super(mklAccount); + } + +// /** +// * Create or update the value associated the specified key if the version +// * checking is passed.
+// * +// * The value of the key will be updated only if it's latest version equals the +// * specified version argument.
+// * If the key doesn't exist, the version checking will be ignored, and key will +// * be created with a new sequence number as id.
+// * It also could specify the version argument to -1 to ignore the version +// * checking. +// *

+// * 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. +// * @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;
+// * If this operation fail by version checking or other reason, then +// * return -1; +// */ +// public long setBytes(Bytes key, BytesValue value, long version) { +// return super.getDataset().setValue(key, value, version); +// } + +// +// /** +// * Create or update the value associated the specified key if the version +// * checking is passed.
+// * +// * The value of the key will be updated only if it's latest version equals the +// * specified version argument.
+// * If the key doesn't exist, the version checking will be ignored, and key will +// * be created with a new sequence number as id.
+// * It also could specify the version argument to -1 to ignore the version +// * checking. +// *

+// * 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. +// * @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;
+// * If this operation fail by version checking or other reason, then +// * return -1; +// */ +// public long setBytes(Bytes key, String value, long version) { +// BytesValue bytesValue = TypedValue.fromText(value); +// return baseAccount.setValue(key, bytesValue, version); +// } +// +// /** +// * Create or update the value associated the specified key if the version +// * checking is passed.
+// * +// * The value of the key will be updated only if it's latest version equals the +// * specified version argument.
+// * If the key doesn't exist, the version checking will be ignored, and key will +// * be created with a new sequence number as id.
+// * It also could specify the version argument to -1 to ignore the version +// * checking. +// *

+// * 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. +// * @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;
+// * If this operation fail by version checking or other reason, then +// * return -1; +// */ +// public long setBytes(Bytes key, byte[] value, long version) { +// BytesValue bytesValue = TypedValue.fromBytes(value); +// return baseAccount.setValue(key, bytesValue, version); +// } +// +// /** +// * Return the latest version entry associated the specified key; If the key +// * doesn't exist, then return -1; +// * +// * @param key +// * @return +// */ +// public long getDataVersion(String key) { +// return baseAccount.getVersion(Bytes.fromString(key)); +// } +// +// /** +// * Return the latest version entry associated the specified key; If the key +// * doesn't exist, then return -1; +// * +// * @param key +// * @return +// */ +// public long getDataVersion(Bytes key) { +// return baseAccount.getVersion(key); +// } +// +// /** +// * return the latest version's value; +// * +// * @param key +// * @return return null if not exist; +// */ +// public BytesValue getBytes(String key) { +// return baseAccount.getValue(Bytes.fromString(key)); +// } +// +// /** +// * return the latest version's value; +// * +// * @param key +// * @return return null if not exist; +// */ +// public BytesValue getBytes(Bytes key) { +// return baseAccount.getValue(key); +// } +// +// /** +// * return the specified version's value; +// * +// * @param key +// * @param version +// * @return return null if not exist; +// */ +// public BytesValue getBytes(String key, long version) { +// return baseAccount.getValue(Bytes.fromString(key), version); +// } +// +// /** +// * return the specified version's value; +// * +// * @param key +// * @param version +// * @return return null if not exist; +// */ +// public BytesValue getBytes(Bytes key, long version) { +// return baseAccount.getValue(key, version); +// } - - /** - * Create or update the value associated the specified key if the version - * checking is passed.
- * - * The value of the key will be updated only if it's latest version equals the - * specified version argument.
- * If the key doesn't exist, the version checking will be ignored, and key will - * be created with a new sequence number as id.
- * It also could specify the version argument to -1 to ignore the version - * checking. - *

- * 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. - * @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;
- * If this operation fail by version checking or other reason, then - * return -1; - */ - public long setBytes(Bytes key, BytesValue value, long version) { - return baseAccount.setValue(key, value, version); - } - - /** - * Create or update the value associated the specified key if the version - * checking is passed.
- * - * The value of the key will be updated only if it's latest version equals the - * specified version argument.
- * If the key doesn't exist, the version checking will be ignored, and key will - * be created with a new sequence number as id.
- * It also could specify the version argument to -1 to ignore the version - * checking. - *

- * 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. - * @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;
- * If this operation fail by version checking or other reason, then - * return -1; - */ - public long setBytes(Bytes key, String value, long version) { - BytesValue bytesValue = TypedBytesValue.fromText(value); - return baseAccount.setValue(key, bytesValue, version); - } - - /** - * Create or update the value associated the specified key if the version - * checking is passed.
- * - * The value of the key will be updated only if it's latest version equals the - * specified version argument.
- * If the key doesn't exist, the version checking will be ignored, and key will - * be created with a new sequence number as id.
- * It also could specify the version argument to -1 to ignore the version - * checking. - *

- * 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. - * @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;
- * If this operation fail by version checking or other reason, then - * return -1; - */ - public long setBytes(Bytes key, byte[] value, long version) { - BytesValue bytesValue = TypedBytesValue.fromBytes(value); - return baseAccount.setValue(key, bytesValue, version); - } - - /** - * Return the latest version entry associated the specified key; If the key - * doesn't exist, then return -1; - * - * @param key - * @return - */ - public long getDataVersion(String key) { - return baseAccount.getVersion(Bytes.fromString(key)); - } - - /** - * Return the latest version entry associated the specified key; If the key - * doesn't exist, then return -1; - * - * @param key - * @return - */ - public long getDataVersion(Bytes key) { - return baseAccount.getVersion(key); - } - - /** - * return the latest version's value; - * - * @param key - * @return return null if not exist; - */ - public BytesValue getBytes(String key) { - return baseAccount.getValue(Bytes.fromString(key)); - } - - /** - * return the latest version's value; - * - * @param key - * @return return null if not exist; - */ - public BytesValue getBytes(Bytes key) { - return baseAccount.getValue(key); - } - - /** - * return the specified version's value; - * - * @param key - * @param version - * @return return null if not exist; - */ - public BytesValue getBytes(String key, long version) { - return baseAccount.getValue(Bytes.fromString(key), version); - } - - /** - * return the specified version's value; - * - * @param key - * @param version - * @return return null if not exist; - */ - public BytesValue getBytes(Bytes key, long version) { - return baseAccount.getValue(key, version); - } - /** - * @param key - * @param version - * @return - */ - public KVDataEntry getDataEntry(String key, long version) { - return getDataEntry(Bytes.fromString(key), version); - } - /** - * @param key - * @param version - * @return - */ - public KVDataEntry getDataEntry(Bytes key, long version) { - BytesValue value = baseAccount.getValue(key, version); - if (value == null) { - return new KVDataObject(key.toUTF8String(), -1, null); - }else { - return new KVDataObject(key.toUTF8String(), version, value); - } - } - - /** - * return the specified index's KVDataEntry; - * - * @param fromIndex - * @param count - * @return return null if not exist; - */ - - public KVDataEntry[] getDataEntries(int fromIndex, int count) { - if (count == 0 || getDataEntriesTotalCount() == 0) { - return null; - } - - if (count == -1 || count > getDataEntriesTotalCount()) { - fromIndex = 0; - count = (int)getDataEntriesTotalCount(); - } - - if (fromIndex < 0 || fromIndex > getDataEntriesTotalCount() - 1) { - fromIndex = 0; - } - - KVDataEntry[] kvDataEntries = new KVDataEntry[count]; - byte[] value; - String key; - long ver; - for (int i = 0; i < count; i++) { - value = baseAccount.dataset.getValuesAtIndex(fromIndex); - key = baseAccount.dataset.getKeyAtIndex(fromIndex); - ver = baseAccount.dataset.getVersion(key); - BytesValue decodeData = BinaryProtocol.decode(value); - kvDataEntries[i] = new KVDataObject(key, ver, decodeData); - fromIndex++; - } - - return kvDataEntries; - } - - /** - * return the dataAccount's kv total count; - * - * @param - * @param - * @return return total count; - */ - public long getDataEntriesTotalCount() { - if(baseAccount == null){ - return 0; - } - return baseAccount.dataset.getDataCount(); - } +// /** +// * @param key +// * @param version +// * @return +// */ +// public KVDataEntry getDataEntry(String key, long version) { +// return getDataEntry(Bytes.fromString(key), version); +// } +// +// /** +// * @param key +// * @param version +// * @return +// */ +// public KVDataEntry getDataEntry(Bytes key, long version) { +// BytesValue value = baseAccount.getValue(key, version); +// if (value == null) { +// return new KVDataObject(key.toUTF8String(), -1, null); +// }else { +// return new KVDataObject(key.toUTF8String(), version, value); +// } +// } +// +// /** +// * return the specified index's KVDataEntry; +// * +// * @param fromIndex +// * @param count +// * @return return null if not exist; +// */ +// +// public KVDataEntry[] getDataEntries(int fromIndex, int count) { +// if (count == 0 || getDataEntriesTotalCount() == 0) { +// return null; +// } +// +// if (count == -1 || count > getDataEntriesTotalCount()) { +// fromIndex = 0; +// count = (int)getDataEntriesTotalCount(); +// } +// +// if (fromIndex < 0 || fromIndex > getDataEntriesTotalCount() - 1) { +// fromIndex = 0; +// } +// +// KVDataEntry[] kvDataEntries = new KVDataEntry[count]; +// byte[] value; +// String key; +// long ver; +// for (int i = 0; i < count; i++) { +// value = baseAccount.dataset.getValuesAtIndex(fromIndex); +// key = baseAccount.dataset.getKeyAtIndex(fromIndex); +// ver = baseAccount.dataset.getVersion(key); +// BytesValue decodeData = BinaryProtocol.decode(value); +// kvDataEntries[i] = new KVDataObject(key, ver, decodeData); +// fromIndex++; +// } +// +// return kvDataEntries; +// } +// +// /** +// * return the dataAccount's kv total count; +// * +// * @param +// * @param +// * @return return total count; +// */ +// public long getDataEntriesTotalCount() { +// if(baseAccount == null){ +// return 0; +// } +// 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/DataAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java index f693211b..e1c5caf3 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java @@ -2,7 +2,7 @@ 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.BlockchainIdentity; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.DigitalSignature; import com.jd.blockchain.ledger.MerkleProof; @@ -17,17 +17,18 @@ public class DataAccountSet implements Transactional, DataAccountQuery { public DataAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { - accountSet = new MerkleAccountSet(cryptoSetting, prefix, exStorage, verStorage, accessPolicy); + accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, accessPolicy); } public DataAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, AccountAccessPolicy accessPolicy) { - accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, prefix, exStorage, verStorage, readonly, accessPolicy); + accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, + readonly, accessPolicy); } @Override - public AccountHeader[] getHeaders(int fromIndex, int count) { + public BlockchainIdentity[] getHeaders(int fromIndex, int count) { return accountSet.getHeaders(fromIndex, count); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/EmptyAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/EmptyAccountSet.java index 879bf702..8cfdd7fc 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/EmptyAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/EmptyAccountSet.java @@ -1,13 +1,13 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.utils.Bytes; public class EmptyAccountSet implements AccountQuery { - private static final AccountHeader[] EMPTY = {}; + private static final BlockchainIdentity[] EMPTY = {}; @Override public HashDigest getRootHash() { @@ -20,7 +20,7 @@ public class EmptyAccountSet implements AccountQuery { } @Override - public AccountHeader[] getHeaders(int fromIndex, int count) { + public BlockchainIdentity[] getHeaders(int fromIndex, int count) { return EMPTY; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java deleted file mode 100644 index e374c08a..00000000 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/GenericAccount.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.jd.blockchain.ledger.core; - -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.AccountHeader; -import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.TypedBytesValue; -import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.MerkleProof; -import com.jd.blockchain.ledger.TypedBytesValue; -import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningMap; - -/** - * Super Type of concrete accounts, e.g. UserAccount, DataAccount, - * ContractAccount etc.; - * - * @author huanghaiquan - * - * @param Type of Account Header; - */ -public class GenericAccount implements MerkleAccountHeader, MerkleProvable, Transactional { - - private MerkleAccount merkleAccount; - - - /** - * 头部类型; - * - * @param headerType - */ - public GenericAccount(MerkleAccount merkleAccount) { - this.merkleAccount = merkleAccount; - } - - @Override - public HashDigest getRootHash() { - return merkleAccount.getRootHash(); - } - - @Override - public MerkleProof getProof(Bytes key) { - key = buildInnerKey(key); - return merkleAccount.getProof(key); - } - - - @Override - public BlockchainIdentity getID() { - return merkleAccount.getID(); - } - - public TypedMap getDataset() { - VersioningMap state = merkleAccount.getDataset(); - return new TypedMap(state); - } - - - @Override - public boolean isUpdated() { - return merkleAccount.isUpdated(); - } - - boolean isReadonly() { - return merkleAccount.isReadonly(); - } - - @Override - public void commit() { - merkleAccount.commit(); - } - - @Override - public void cancel() { - merkleAccount.cancel(); - } - - private Bytes buildInnerKey(Bytes key) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java index 55b989d5..267d8fbc 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java @@ -6,6 +6,7 @@ import java.util.List; import com.jd.blockchain.contract.ContractException; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.ContractInfo; import com.jd.blockchain.ledger.KVDataEntry; @@ -270,11 +271,11 @@ public class LedgerQueryService implements BlockchainQueryService { } @Override - public AccountHeader getDataAccount(HashDigest ledgerHash, String address) { + public BlockchainIdentity getDataAccount(HashDigest ledgerHash, String address) { checkLedgerHash(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getAccount(Bytes.fromBase58(address)); + return dataAccountSet.getAccount(Bytes.fromBase58(address)).getID(); } @Override @@ -292,12 +293,12 @@ public class LedgerQueryService implements BlockchainQueryService { for (int i = 0; i < entries.length; i++) { final String currKey = keys[i]; - ver = dataAccount == null ? -1 : dataAccount.getDataVersion(Bytes.fromString(currKey)); + ver = dataAccount == null ? -1 : dataAccount.getDataset().getVersion(Bytes.fromString(currKey)); if (ver < 0) { entries[i] = new KVDataObject(currKey, -1, null); } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(currKey), ver); + BytesValue value = dataAccount.getDataset().getValue(Bytes.fromString(currKey), ver); entries[i] = new KVDataObject(currKey, ver, value); } } @@ -344,7 +345,7 @@ public class LedgerQueryService implements BlockchainQueryService { if (ver < 0) { entries[i] = new KVDataObject(keys[i], -1, null); } else { - if (dataAccount.getDataEntriesTotalCount() == 0 + if (dataAccount.getDataset().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); @@ -388,7 +389,7 @@ public class LedgerQueryService implements BlockchainQueryService { } @Override - public AccountHeader[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { checkLedgerHash(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); UserAccountQuery userAccountSet = ledger.getUserAccountSet(block); @@ -397,7 +398,7 @@ public class LedgerQueryService implements BlockchainQueryService { } @Override - public AccountHeader[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { checkLedgerHash(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); @@ -406,7 +407,7 @@ public class LedgerQueryService implements BlockchainQueryService { } @Override - public AccountHeader[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { checkLedgerHash(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); ContractAccountQuery contractAccountSet = ledger.getContractAccountSet(block); diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java index a0973e12..63fcc445 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java @@ -10,7 +10,7 @@ import com.jd.blockchain.ledger.HashProof; import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.ledger.MerkleSnapshot; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; @@ -42,7 +42,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho private MerkleDatasetAdapter headerDS; private MerkleDatasetAdapter dataDS; - + protected long version; /** @@ -55,18 +55,17 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho * account's merkle dataset, but is stored by the outer invoker; * * @param accountID 身份; - * @param version 版本; * @param cryptoSetting 密码参数; * @param keyPrefix 数据前缀; * @param exStorage * @param verStorage */ - public MerkleAccount(BlockchainIdentity accountID, long version, CryptoSetting cryptoSetting, Bytes keyPrefix, + public MerkleAccount(BlockchainIdentity accountID, CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { - this(accountID.getAddress(), accountID.getPubKey(), version, null, cryptoSetting, keyPrefix, exStorage, - verStorage, false); + this(accountID.getAddress(), accountID.getPubKey(), -1, null, cryptoSetting, keyPrefix, exStorage, verStorage, + false); - savePubKey(accountID.getPubKey()); + initPubKey(accountID.getPubKey()); } /** @@ -89,14 +88,30 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho this(address, null, version, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); } - private MerkleAccount(Bytes address, PubKey pubKey, long version, HashDigest dataRootHash, - CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, - boolean readonly) { - this.accountID = new BlockchainIdentityProxy(address, pubKey); + /** + * 内部构造器; + * + * @param address 账户地址; + * @param pubKey 账户公钥; 如果为空,则会进行加载验证; + * @param version 账户版本; + * @param rootHash 账户根哈希; + * @param cryptoSetting 密码参数设置; + * @param keyPrefix 当前账户的 Key 前缀; + * @param exStorage 单键存储服务; + * @param verStorage 多版本存储服务; + * @param readonly 是否只读; + */ + private MerkleAccount(Bytes address, PubKey pubKey, long version, HashDigest rootHash, CryptoSetting cryptoSetting, + Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { + // 初始化账户的身份; + this.accountID = new AutoloadingID(address, pubKey); + this.version = version; - this.rootDS = new MerkleDataSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); - // 初始化数据; + // 加载“根数据集” + this.rootDS = new MerkleDataSet(rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + + // 初始化数据修改监听器; DataChangedListener dataChangedListener = new DataChangedListener() { @Override public void onChanged(Bytes key, BytesValue value, long newVersion) { @@ -104,17 +119,20 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho } }; + // 加载“头数据集”; HashDigest headerRoot = loadHeaderRoot(); Bytes headerPrefix = keyPrefix.concat(HEADER_PREFIX); MerkleDataSet headerDataset = new MerkleDataSet(headerRoot, cryptoSetting, headerPrefix, exStorage, verStorage, readonly); this.headerDS = new MerkleDatasetAdapter(headerDataset, dataChangedListener); + // 加载“主数据集” HashDigest dataRoot = loadDataRoot(); Bytes dataPrefix = keyPrefix.concat(DATA_PREFIX); MerkleDataSet dataDataset = new MerkleDataSet(dataRoot, cryptoSetting, dataPrefix, exStorage, verStorage, readonly); this.dataDS = new MerkleDatasetAdapter(dataDataset, dataChangedListener); + } private HashDigest loadHeaderRoot() { @@ -133,6 +151,14 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho return new HashDigest(hashBytes); } + private long getHeaderRootVersion() { + return rootDS.getVersion(KEY_HEADER_ROOT); + } + + private long getDataRootVersion() { + return rootDS.getVersion(KEY_DATA_ROOT); + } + public Bytes getAddress() { return accountID.getAddress(); } @@ -146,6 +172,10 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho return accountID; } + protected VersioningMap getHeaders() { + return headerDS; + } + @Override public VersioningMap getDataset() { return dataDS; @@ -190,12 +220,12 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho } /** - * 保存公钥; + * 初始化账户的公钥; * * @param pubKey */ - private void savePubKey(PubKey pubKey) { - long v = headerDS.setValue(KEY_PUBKEY, TypedBytesValue.fromPubKey(pubKey), -1); + private void initPubKey(PubKey pubKey) { + long v = headerDS.setValue(KEY_PUBKEY, TypedValue.fromPubKey(pubKey), -1); if (v < 0) { throw new LedgerException("PubKey storage conflict!"); } @@ -208,7 +238,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho */ private PubKey loadPubKey() { BytesValue bytesValue = headerDS.getValue(KEY_PUBKEY); - return TypedBytesValue.wrap(bytesValue).pubKeyValue(); + return TypedValue.wrap(bytesValue).pubKeyValue(); } /** @@ -221,6 +251,19 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho protected void onUpdated(Bytes key, BytesValue value, long newVersion) { } + /** + * 当账户数据提交后触发此方法;
+ * + * 此方法默认会返回新的账户版本号,等于当前版本号加 1 ; + * + * @param newRootHash + * @param currentVersion + * @return + */ + protected long onCommited(HashDigest newRootHash, long currentVersion) { + return currentVersion + 1; + } + @Override public boolean isUpdated() { return dataDS.getDataset().isUpdated() || headerDS.getDataset().isUpdated() || rootDS.isUpdated(); @@ -228,26 +271,39 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho @Override public void commit() { - dataDS.getDataset().commit(); - headerDS.getDataset().commit(); - - rootDS.setValue(key, value, version) - - baseDS.commit(); + if (headerDS.dataset.isUpdated()) { + headerDS.getDataset().commit(); + long version = getHeaderRootVersion(); + rootDS.setValue(KEY_HEADER_ROOT, headerDS.dataset.getRootHash().toBytes(), version); + } + if (dataDS.dataset.isUpdated()) { + long version = getDataRootVersion(); + dataDS.getDataset().commit(); + rootDS.setValue(KEY_DATA_ROOT, dataDS.dataset.getRootHash().toBytes(), version); + } + + if (rootDS.isUpdated()) { + rootDS.commit(); + this.version = onCommited(rootDS.getRootHash(), version); + } } @Override public void cancel() { - baseDS.cancel(); + headerDS.getDataset().cancel(); + dataDS.getDataset().cancel(); + rootDS.cancel(); } - private class BlockchainIdentityProxy implements BlockchainIdentity { + // ---------------------- + + private class AutoloadingID implements BlockchainIdentity { private Bytes address; private PubKey pubKey; - public BlockchainIdentityProxy(Bytes address, PubKey pubKey) { + public AutoloadingID(Bytes address, PubKey pubKey) { this.address = address; this.pubKey = pubKey; } @@ -267,8 +323,6 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho } - // ---------------------- - private static class MerkleDatasetAdapter implements VersioningMap { private static DataChangedListener NULL_LISTENER = new DataChangedListener() { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java index 0a833516..3768c13f 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java @@ -8,8 +8,8 @@ import com.jd.blockchain.binaryproto.DataContractRegistry; 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.BlockchainIdentity; +import com.jd.blockchain.ledger.BlockchainIdentityData; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.LedgerException; @@ -18,21 +18,19 @@ import com.jd.blockchain.ledger.MerkleSnapshot; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.RegionMap; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningMap; -public abstract class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery { +public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery { - private static final Bytes ACCOUNT_ROOT_PREFIX = Bytes.fromString("ROOT/"); +// private static final Bytes ACCOUNT_ROOT_PREFIX = Bytes.fromString("ROOT/"); static { DataContractRegistry.register(MerkleSnapshot.class); - DataContractRegistry.register(AccountHeader.class); + DataContractRegistry.register(BlockchainIdentity.class); } private final Bytes keyPrefix; - + /** * 账户根哈希的数据集; */ @@ -216,22 +214,14 @@ public abstract class MerkleAccountSet implements Transactional, MerkleProvable, } // Now, be sure that "acc == null", so get account from storage; - - byte[] bytes = merkleDataset.getValue(address, version); - if (bytes == null) { - return null; - } - // Set readonly for the old version account; boolean readonly = (version > -1 && version < latestVersion) || isReadonly(); - // String prefix = address.concat(LedgerConsts.KEY_SEPERATOR); - // ExPolicyKVStorage ss = PrefixAppender.prefix(prefix, baseExStorage); - // VersioningKVStorage vs = PrefixAppender.prefix(prefix, baseVerStorage); - // BaseAccount accDS = deserialize(bytes, cryptoSetting, ss, vs, readonly); - - Bytes prefix = keyPrefix.concat(address); - acc = deserialize(bytes, cryptoSetting, prefix, readonly, latestVersion); + // load account from storage; + acc = loadAccount(address, readonly, version); + if (acc == null) { + return null; + } if (!readonly) { // cache the latest version witch enable reading and writing; // readonly version of account not necessary to be cached; @@ -240,6 +230,10 @@ public abstract class MerkleAccountSet implements Transactional, MerkleProvable, return acc; } + public MerkleAccount register(Bytes address, PubKey pubKey) { + return register(new BlockchainIdentityData(address, pubKey)); + } + /** * 注册一个新账户;
* @@ -287,7 +281,7 @@ public abstract class MerkleAccountSet implements Transactional, MerkleProvable, // accExStorage, accVerStorage); Bytes prefix = keyPrefix.concat(address); - InnerMerkleAccount acc = createInstance(accountId, cryptoSetting, prefix, -1); + InnerMerkleAccount acc = createInstance(accountId, cryptoSetting, prefix); latestAccountsCache.put(address, acc); updated = true; @@ -301,24 +295,43 @@ public abstract class MerkleAccountSet implements Transactional, MerkleProvable, } } - private InnerMerkleAccount createInstance(BlockchainIdentity header, CryptoSetting cryptoSetting, Bytes keyPrefix, - long version) { - return new InnerMerkleAccount(header, version, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage); + private InnerMerkleAccount createInstance(BlockchainIdentity header, CryptoSetting cryptoSetting, Bytes keyPrefix) { + return new InnerMerkleAccount(header, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage); } - private InnerMerkleAccount deserialize(byte[] bytes, CryptoSetting cryptoSetting, Bytes keyPrefix, boolean readonly, - long version) { - BlockchainIdentity id = BinaryProtocol.decodeAs(bytes, BlockchainIdentity.class); + private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) { + // prefix; + Bytes prefix = keyPrefix.concat(address); + byte[] rootHashBytes = merkleDataset.getValue(address, version); + if (rootHashBytes == null) { + return null; + } + HashDigest rootHash = new HashDigest(rootHashBytes); - return new InnerMerkleAccount(header.getID(), version, header.getRootHash(), cryptoSetting, keyPrefix, - baseExStorage, baseVerStorage, readonly); + return new InnerMerkleAccount(address, version, rootHash, cryptoSetting, prefix, baseExStorage, baseVerStorage, + readonly); } - // TODO: 优化:区块链身份(地址+公钥)与其 Merkle - // 树根哈希分开独立存储;不必作为一个整块,避免状态数据写入时频繁重写公钥,尤其某些算法的公钥可能很大; - private byte[] serialize(MerkleAccountHeader account) { - return BinaryProtocol.encode(account, MerkleAccountHeader.class); + // TODO:优化:区块链身份(地址+公钥)与其Merkle树根哈希分开独立存储; + // 不必作为一个整块,避免状态数据写入时频繁重写公钥,尤其某些算法的公钥可能很大; + + /** + * 保存账户的根哈希,返回账户的新版本; + * + * @param account + * @return + */ + private long saveAccount(InnerMerkleAccount account) { + // 提交更改,更新哈希; + long version = account.version; + account.commit(); + long newVersion = merkleDataset.setValue(account.getAddress(), account.getRootHash().toBytes(), version); + if (newVersion < 0) { + // Update fail; + throw new LedgerException("Account updating fail! --[Address=" + account.getAddress() + "]"); + } + return newVersion; } @Override @@ -335,15 +348,7 @@ public abstract class MerkleAccountSet implements Transactional, MerkleProvable, for (InnerMerkleAccount acc : latestAccountsCache.values()) { // updated or new created; if (acc.isUpdated() || acc.version < 0) { - // 提交更改,更新哈希; - acc.commit(); - byte[] value = serialize(acc); - long ver = merkleDataset.setValue(acc.getID().getAddress(), value, acc.version); - if (ver < 0) { - // Update fail; - throw new LedgerException( - "Account updating fail! --[Address=" + acc.getID().getAddress() + "]"); - } + saveAccount(acc); } } merkleDataset.commit(); @@ -370,17 +375,22 @@ public abstract class MerkleAccountSet implements Transactional, MerkleProvable, updated = false; } + /** + * 内部实现的账户,监听和同步账户数据的变更; + * + * @author huanghaiquan + * + */ private class InnerMerkleAccount extends MerkleAccount { - public InnerMerkleAccount(BlockchainIdentity accountID, long version, CryptoSetting cryptoSetting, - Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { - super(accountID, version, cryptoSetting, keyPrefix, exStorage, verStorage); + public InnerMerkleAccount(BlockchainIdentity accountID, CryptoSetting cryptoSetting, Bytes keyPrefix, + ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { + super(accountID, cryptoSetting, keyPrefix, exStorage, verStorage); } - public InnerMerkleAccount(BlockchainIdentity accountID, long version, HashDigest dataRootHash, - CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, - VersioningKVStorage verStorage, boolean readonly) { - super(accountID, version, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + public InnerMerkleAccount(Bytes address, long version, HashDigest dataRootHash, CryptoSetting cryptoSetting, + Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { + super(address, version, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); } @Override diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java index d8adbcc2..dd3836f7 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java @@ -49,17 +49,17 @@ public class MerkleDataCluster implements Transactional, MerkleSnapshot { return rootDS.isUpdated(); } - public VersioningMap getPartition(Bytes name) { - return getPartition(name, false); - } - - public VersioningMap getPartition(Bytes name, boolean create) { - - } - - public VersioningMap createPartition(Bytes name) { - - } +// public VersioningMap getPartition(Bytes name) { +// return getPartition(name, false); +// } +// +// public VersioningMap getPartition(Bytes name, boolean create) { +// +// } +// +// public VersioningMap createPartition(Bytes name) { +// +// } @Override public void commit() { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/OpeningAccessPolicy.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/OpeningAccessPolicy.java index 6628aad3..8efd1d10 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/OpeningAccessPolicy.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/OpeningAccessPolicy.java @@ -1,7 +1,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.utils.Bytes; /** @@ -15,7 +15,7 @@ import com.jd.blockchain.utils.Bytes; public class OpeningAccessPolicy implements AccountAccessPolicy { @Override - public boolean checkDataWriting(AccountHeader account) { + public boolean checkDataWriting(BlockchainIdentity account) { return true; } 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 dbc077a8..bd629b8a 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 @@ -28,7 +28,7 @@ public class ParticipantDataset implements Transactional, MerkleProvable, Partic public ParticipantDataset(HashDigest merkleRootHash, CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, VersioningKVStorage verStorage, boolean readonly) { - dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, prefix, exPolicyStorage, verStorage, readonly); + dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, Bytes.fromString(prefix), exPolicyStorage, verStorage, readonly); } @Override diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java index 74d670c4..483b5667 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java @@ -30,7 +30,8 @@ public class RolePrivilegeDataset implements Transactional, MerkleProvable, Role public RolePrivilegeDataset(HashDigest merkleRootHash, CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, VersioningKVStorage verStorage, boolean readonly) { - dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, prefix, exPolicyStorage, verStorage, readonly); + dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, Bytes.fromString(prefix), exPolicyStorage, + verStorage, readonly); } @Override @@ -255,7 +256,7 @@ public class RolePrivilegeDataset implements Transactional, MerkleProvable, Role public RolePrivileges getRolePrivilege(String roleName) { // 只返回最新版本; Bytes key = encodeKey(roleName); - VersioningKVEntry kv = dataset.getDataEntry(key); + VersioningKVEntry kv = dataset.getDataEntry(key); if (kv == null) { return null; } @@ -265,7 +266,7 @@ public class RolePrivilegeDataset implements Transactional, MerkleProvable, Role @Override public RolePrivileges[] getRolePrivileges(int index, int count) { - VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); + VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); RolePrivileges[] pns = new RolePrivileges[kvEntries.length]; PrivilegeSet privilege; for (int i = 0; i < pns.length; i++) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java deleted file mode 100644 index 227c3dd7..00000000 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/StringKeyMap.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.jd.blockchain.ledger.core; - -import com.jd.blockchain.utils.VersioningMap; - -public interface StringKeyMap extends VersioningMap { - -} 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 28c6bff4..fe336005 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 @@ -88,7 +88,8 @@ public class TransactionSet implements Transactional, TransactionQuery { public TransactionSet(HashDigest txRootHash, CryptoSetting setting, String keyPrefix, ExPolicyKVStorage merkleTreeStorage, VersioningKVStorage dataStorage, boolean readonly) { this.txStatePrefix = Bytes.fromString(keyPrefix + TX_STATE_PREFIX); - this.txSet = new MerkleDataSet(txRootHash, setting, keyPrefix, merkleTreeStorage, dataStorage, readonly); + this.txSet = new MerkleDataSet(txRootHash, setting, Bytes.fromString(keyPrefix), merkleTreeStorage, dataStorage, + readonly); } /** 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 0e7dc692..2a3eda4f 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 @@ -1,12 +1,11 @@ package com.jd.blockchain.ledger.core; -import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.TypedBytesValue; import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.UserAccountHeader; +import com.jd.blockchain.ledger.LedgerException; +import com.jd.blockchain.ledger.TypedValue; +import com.jd.blockchain.ledger.UserInfo; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningMap; /** * 用户账户; @@ -14,34 +13,54 @@ import com.jd.blockchain.utils.VersioningMap; * @author huanghaiquan * */ -public class UserAccount extends MerkleAccount{ //implements UserInfo { +public class UserAccount extends AccountDecorator implements UserInfo { // implements UserInfo { private static final Bytes USER_INFO_PREFIX = Bytes.fromString("PROP" + LedgerConsts.KEY_SEPERATOR); private static final Bytes DATA_PUB_KEY = Bytes.fromString("DATA-PUBKEY"); -// private MerkleAccount baseAccount; + public UserAccount(MerkleAccount mklAccount) { + super(mklAccount); + } + + private PubKey dataPubKey; + - public UserAccount(VersioningMap baseAccount) { - this.baseAccount = baseAccount; + @Override + public Bytes getAddress() { + return getID().getAddress(); } + @Override + public PubKey getPubKey() { + return getID().getPubKey(); + } + + @Override public PubKey getDataPubKey() { - BytesValue pkBytes = baseAccount.getValue(DATA_PUB_KEY); - if (pkBytes == null) { - return null; + if (dataPubKey == null) { + BytesValue pkBytes = getHeaders().getValue(DATA_PUB_KEY); + if (pkBytes == null) { + return null; + } + dataPubKey = new PubKey(pkBytes.getValue().toBytes()); } - return new PubKey(pkBytes.getValue().toBytes()); + return dataPubKey; } - public long setDataPubKey(PubKey pubKey) { - byte[] pkBytes = pubKey.toBytes(); - return baseAccount.setValue(DATA_PUB_KEY, TypedBytesValue.fromBytes(pkBytes), -1); + public void setDataPubKey(PubKey pubKey) { + long version = getHeaders().getVersion(DATA_PUB_KEY); + setDataPubKey(pubKey, version); } - public long setDataPubKey(PubKey pubKey, long version) { - byte[] pkBytes = pubKey.toBytes(); - return baseAccount.setValue(DATA_PUB_KEY, TypedBytesValue.fromBytes(pkBytes), version); + public void setDataPubKey(PubKey pubKey, long version) { + TypedValue value = TypedValue.fromPubKey(dataPubKey); + long newVersion = getHeaders().setValue(DATA_PUB_KEY, value, version); + if (newVersion > -1) { + dataPubKey = pubKey; + } else { + throw new LedgerException("Data public key was updated failed!"); + } } public long setProperty(String key, String value, long version) { @@ -49,22 +68,22 @@ public class UserAccount extends MerkleAccount{ //implements UserInfo { } public long setProperty(Bytes key, String value, long version) { - return baseAccount.setValue(encodePropertyKey(key), TypedBytesValue.fromText(value), version); + return getHeaders().setValue(encodePropertyKey(key), TypedValue.fromText(value), version); } public String getProperty(Bytes key) { - BytesValue value = baseAccount.getValue(encodePropertyKey(key)); + BytesValue value = getHeaders().getValue(encodePropertyKey(key)); return value == null ? null : value.getValue().toUTF8String(); } public String getProperty(Bytes key, long version) { - BytesValue value = baseAccount.getValue(encodePropertyKey(key), version); + BytesValue value = getHeaders().getValue(encodePropertyKey(key), version); return value == null ? null : value.getValue().toUTF8String(); } private Bytes encodePropertyKey(Bytes key) { - // return key.concatTo(USER_INFO_PREFIX); return USER_INFO_PREFIX.concat(key); } + } \ No newline at end of file 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 700c0a49..24958c77 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 @@ -2,7 +2,7 @@ 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.BlockchainIdentity; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.ledger.MerkleProof; @@ -10,7 +10,6 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningMap; /** * @author huanghaiquan @@ -22,19 +21,20 @@ public class UserAccountSet implements Transactional, UserAccountQuery { public UserAccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage simpleStorage, VersioningKVStorage versioningStorage, AccountAccessPolicy accessPolicy) { - accountSet = new MerkleAccountSet(cryptoSetting, keyPrefix, simpleStorage, versioningStorage, accessPolicy); + accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(keyPrefix), simpleStorage, versioningStorage, + accessPolicy); } public UserAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, AccountAccessPolicy accessPolicy) { - accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly, - accessPolicy); + accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(keyPrefix), exStorage, + verStorage, readonly, accessPolicy); } @Override - public AccountHeader[] getHeaders(int fromIndex, int count) { - return accountSet.getHeaders(fromIndex,count); + public BlockchainIdentity[] getHeaders(int fromIndex, int count) { + return accountSet.getHeaders(fromIndex, count); } /** @@ -50,7 +50,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { public boolean isReadonly() { return accountSet.isReadonly(); } - + void setReadonly() { accountSet.setReadonly(); } @@ -64,7 +64,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { public MerkleProof getProof(Bytes key) { return accountSet.getProof(key); } - + @Override public UserAccount getAccount(String address) { return getAccount(Bytes.fromBase58(address)); @@ -72,7 +72,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { @Override public UserAccount getAccount(Bytes address) { - VersioningMap baseAccount = accountSet.getAccount(address); + MerkleAccount baseAccount = accountSet.getAccount(address); return new UserAccount(baseAccount); } @@ -83,7 +83,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { @Override public UserAccount getAccount(Bytes address, long version) { - VersioningMap baseAccount = accountSet.getAccount(address, version); + MerkleAccount baseAccount = accountSet.getAccount(address, version); return new UserAccount(baseAccount); } @@ -94,14 +94,12 @@ public class UserAccountSet implements Transactional, UserAccountQuery { * * 如果指定的地址和公钥不匹配,则会引发 {@link LedgerException} 异常; * - * @param address - * 区块链地址; - * @param pubKey - * 公钥; + * @param address 区块链地址; + * @param pubKey 公钥; * @return 注册成功的用户对象; */ public UserAccount register(Bytes address, PubKey pubKey) { - VersioningMap baseAccount = accountSet.register(address, pubKey); + MerkleAccount baseAccount = accountSet.register(address, pubKey); return new UserAccount(baseAccount); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java index 84d71347..e4eb37cc 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java @@ -35,7 +35,7 @@ public class UserRoleDataset implements Transactional, MerkleProvable, UserAutho public UserRoleDataset(HashDigest merkleRootHash, CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, VersioningKVStorage verStorage, boolean readonly) { - dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, prefix, exPolicyStorage, verStorage, readonly); + dataset = new MerkleDataSet(merkleRootHash, cryptoSetting, Bytes.fromString(prefix), exPolicyStorage, verStorage, readonly); } @Override @@ -168,7 +168,7 @@ public class UserRoleDataset implements Transactional, MerkleProvable, UserAutho @Override public UserRoles getUserRoles(Bytes userAddress) { // 只返回最新版本; - VersioningKVEntry kv = dataset.getDataEntry(userAddress); + VersioningKVEntry kv = dataset.getDataEntry(userAddress); if (kv == null) { return null; } @@ -178,7 +178,7 @@ public class UserRoleDataset implements Transactional, MerkleProvable, UserAutho @Override public UserRoles[] getUserRoles() { - VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); + VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); UserRoles[] pns = new UserRoles[kvEntries.length]; RoleSet roleset; for (int i = 0; i < pns.length; i++) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java index 5c22a7dc..e86747db 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java @@ -5,7 +5,24 @@ import java.util.List; import com.jd.blockchain.contract.LedgerContext; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.*; +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.ContractInfo; +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.LedgerAdminInfo; +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.TypedValue; +import com.jd.blockchain.ledger.UserInfo; +import com.jd.blockchain.ledger.UserRegisterOperation; import com.jd.blockchain.ledger.core.OperationHandleContext; import com.jd.blockchain.transaction.BlockchainQueryService; import com.jd.blockchain.transaction.DataAccountKVSetOperationBuilder; @@ -150,7 +167,7 @@ public class ContractLedgerContext implements LedgerContext { } @Override - public AccountHeader getDataAccount(HashDigest ledgerHash, String address) { + public BlockchainIdentity getDataAccount(HashDigest ledgerHash, String address) { return innerQueryService.getDataAccount(ledgerHash, address); } @@ -182,17 +199,17 @@ public class ContractLedgerContext implements LedgerContext { // ---------------------------user()---------------------------- @Override - public AccountHeader[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { return innerQueryService.getUsers(ledgerHash, fromIndex, count); } @Override - public AccountHeader[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { return innerQueryService.getDataAccounts(ledgerHash, fromIndex, count); } @Override - public AccountHeader[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { return innerQueryService.getContractAccounts(ledgerHash, fromIndex, count); } @@ -268,7 +285,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromText(value); + BytesValue bytesValue = TypedValue.fromText(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -276,7 +293,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromBytes(value); + BytesValue bytesValue = TypedValue.fromBytes(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -284,7 +301,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromInt64(value); + BytesValue bytesValue = TypedValue.fromInt64(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -301,7 +318,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromJSON(value); + BytesValue bytesValue = TypedValue.fromJSON(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -309,7 +326,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromXML(value); + BytesValue bytesValue = TypedValue.fromXML(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -317,7 +334,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromBytes(value); + BytesValue bytesValue = TypedValue.fromBytes(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -325,7 +342,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromImage(value); + BytesValue bytesValue = TypedValue.fromImage(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; @@ -333,7 +350,7 @@ public class ContractLedgerContext implements LedgerContext { @Override public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromTimestamp(value); + BytesValue bytesValue = TypedValue.fromTimestamp(value); this.op = new SingleKVSetOpTemplate(key, bytesValue, expVersion); handle(op); return this; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java index 0f9fdb2b..a6758fb0 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java @@ -37,7 +37,7 @@ public class DataAccountKVSetOperationHandle extends AbstractLedgerOperationHand KVWriteEntry[] writeSet = kvWriteOp.getWriteSet(); long v = -1L; for (KVWriteEntry kvw : writeSet) { - v = account.setBytes(Bytes.fromString(kvw.getKey()), kvw.getValue(), kvw.getExpectedVersion()); + v = account.getDataset().setValue(Bytes.fromString(kvw.getKey()), kvw.getValue(), kvw.getExpectedVersion()); if (v < 0) { throw new DataVersionConflictException(); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java index 812a8758..1c05e28c 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java @@ -19,6 +19,7 @@ import com.jd.blockchain.ledger.core.MerkleAccount; import com.jd.blockchain.ledger.core.CryptoConfig; import com.jd.blockchain.ledger.core.OpeningAccessPolicy; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; +import com.jd.blockchain.utils.Bytes; public class AccountSetTest { @@ -43,7 +44,7 @@ public class AccountSetTest { cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); String keyPrefix = ""; - MerkleAccountSet accset = new MerkleAccountSet(cryptoConf, keyPrefix, storage, storage, accessPolicy); + MerkleAccountSet accset = new MerkleAccountSet(cryptoConf, Bytes.fromString(keyPrefix), storage, storage, accessPolicy); BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); accset.register(userKey.getAddress(), userKey.getPubKey()); @@ -56,7 +57,7 @@ public class AccountSetTest { HashDigest rootHash = accset.getRootHash(); assertNotNull(rootHash); - MerkleAccountSet reloadAccSet = new MerkleAccountSet(rootHash, cryptoConf, keyPrefix, storage, storage, true, accessPolicy); + MerkleAccountSet reloadAccSet = new MerkleAccountSet(rootHash, cryptoConf, Bytes.fromString(keyPrefix), storage, storage, true, accessPolicy); MerkleAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress()); assertNotNull(reloadUserAcc); assertTrue(reloadAccSet.contains(userKey.getAddress())); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java index 8ca0fe9f..25a9091f 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java @@ -2,6 +2,7 @@ package test.com.jd.blockchain.ledger.core; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -12,9 +13,9 @@ 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.TypedBytesValue; -import com.jd.blockchain.ledger.core.MerkleAccount; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.core.CryptoConfig; +import com.jd.blockchain.ledger.core.MerkleAccount; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.utils.Bytes; @@ -48,38 +49,39 @@ public class BaseAccountTest { BlockchainKeypair bck = BlockchainKeyGenerator.getInstance().generate(); // 新建账户; - MerkleAccount baseAccount = new MerkleAccount(bck.getIdentity(), cryptoConf, keyPrefix, testStorage, testStorage); - assertFalse(baseAccount.isUpdated());// 空的账户; + MerkleAccount baseAccount = new MerkleAccount(bck.getIdentity(), cryptoConf, Bytes.fromString(keyPrefix), + testStorage, testStorage); + assertTrue(baseAccount.isUpdated());//初始化新账户时,先写入PubKey; assertFalse(baseAccount.isReadonly()); // 在空白状态下写入数据; - long v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A"), 0); + long v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A"), 0); // 预期失败; assertEquals(-1, v); - v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A"), 1); + v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A"), 1); // 预期失败; assertEquals(-1, v); - v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A"), -1); + v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A"), -1); // 预期成功; assertEquals(0, v); - v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A-1"), -1); + v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A-1"), -1); // 已经存在版本,指定版本号-1,预期导致失败; assertEquals(-1, v); baseAccount.commit(); v = 0; for (int i = 0; i < 10; i++) { - long s = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A_" + i), v); + long s = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A_" + i), v); baseAccount.commit(); // 预期成功; assertEquals(v + 1, s); v++; } - v = baseAccount.setValue(Bytes.fromString("A"), TypedBytesValue.fromText("VALUE_A_" + v), v + 1); + v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A_" + v), v + 1); // 预期成功; assertEquals(-1, v); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java index 57711c42..4e91c1fb 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java @@ -16,14 +16,36 @@ import static org.mockito.Mockito.when; import java.io.InputStream; import java.util.Random; -import com.jd.blockchain.utils.io.BytesUtils; -import com.jd.blockchain.ledger.*; import org.junit.Test; import org.mockito.Mockito; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.BlockchainKeyGenerator; +import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.DataAccountRegisterOperation; +import com.jd.blockchain.ledger.EndpointRequest; +import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.LedgerBlock; +import com.jd.blockchain.ledger.LedgerInitSetting; +import com.jd.blockchain.ledger.LedgerPermission; +import com.jd.blockchain.ledger.LedgerTransaction; +import com.jd.blockchain.ledger.NodeRequest; +import com.jd.blockchain.ledger.OperationResult; +import com.jd.blockchain.ledger.ParticipantNode; +import com.jd.blockchain.ledger.ParticipantRegisterOperation; +import com.jd.blockchain.ledger.ParticipantStateUpdateOperation; +import com.jd.blockchain.ledger.TransactionContent; +import com.jd.blockchain.ledger.TransactionContentBody; +import com.jd.blockchain.ledger.TransactionPermission; +import com.jd.blockchain.ledger.TransactionRequest; +import com.jd.blockchain.ledger.TransactionRequestBuilder; +import com.jd.blockchain.ledger.TransactionResponse; +import com.jd.blockchain.ledger.TransactionState; +import com.jd.blockchain.ledger.TypedValue; +import com.jd.blockchain.ledger.UserRegisterOperation; import com.jd.blockchain.ledger.core.DefaultOperationHandleRegisteration; import com.jd.blockchain.ledger.core.LedgerDataQuery; import com.jd.blockchain.ledger.core.LedgerDataset; @@ -43,6 +65,7 @@ import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.transaction.BooleanValueHolder; import com.jd.blockchain.transaction.TxBuilder; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.io.BytesUtils; import test.com.jd.blockchain.ledger.TxTestContract; import test.com.jd.blockchain.ledger.TxTestContractImpl; @@ -132,7 +155,7 @@ public class ContractInvokingTest { assertEquals(1, opResults.length); assertEquals(0, opResults[0].getIndex()); - byte[] expectedRetnBytes = BinaryProtocol.encode(TypedBytesValue.fromInt64(issueAmount), BytesValue.class); + byte[] expectedRetnBytes = BinaryProtocol.encode(TypedValue.fromInt64(issueAmount), BytesValue.class); byte[] reallyRetnBytes = BinaryProtocol.encode(opResults[0].getResult(), BytesValue.class); assertArrayEquals(expectedRetnBytes, reallyRetnBytes); @@ -218,7 +241,7 @@ public class ContractInvokingTest { TransactionBatchResultHandle txResultHandle = txbatchProcessor.prepare(); txResultHandle.commit(); - BytesValue latestValue = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getValue(key, + BytesValue latestValue = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getValue(key, -1); System.out.printf("latest value=[%s] %s \r\n", latestValue.getType(), latestValue.getValue().toUTF8String()); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java index 45d049ae..fcc530de 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AccountHeader.java @@ -1,20 +1,20 @@ -package com.jd.blockchain.ledger; - -import com.jd.blockchain.binaryproto.DataContract; -import com.jd.blockchain.binaryproto.DataField; -import com.jd.blockchain.binaryproto.PrimitiveType; -import com.jd.blockchain.consts.DataCodes; -import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.utils.Bytes; - -@DataContract(code= DataCodes.ACCOUNT_HEADER) -public interface AccountHeader { //extends MerkleSnapshot{ - - @DataField(order=1, primitiveType = PrimitiveType.BYTES) - Bytes getAddress(); - - @DataField(order=2, primitiveType = PrimitiveType.BYTES) - PubKey getPubKey(); - - -} +//package com.jd.blockchain.ledger; +// +//import com.jd.blockchain.binaryproto.DataContract; +//import com.jd.blockchain.binaryproto.DataField; +//import com.jd.blockchain.binaryproto.PrimitiveType; +//import com.jd.blockchain.consts.DataCodes; +//import com.jd.blockchain.crypto.PubKey; +//import com.jd.blockchain.utils.Bytes; +// +//@Deprecated +//@DataContract(code= DataCodes.ACCOUNT_HEADER) +//public interface AccountHeader { //extends MerkleSnapshot{ +// +// @DataField(order = 1, primitiveType = PrimitiveType.BYTES) +// Bytes getAddress(); +// +// @DataField(order = 2, primitiveType=PrimitiveType.BYTES) +// PubKey getPubKey(); +// +//} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesDataList.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesDataList.java index 7aa87c82..a7541a41 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesDataList.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesDataList.java @@ -14,18 +14,18 @@ public class BytesDataList implements BytesValueList { } public static BytesValueList singleText(String value) { - return new BytesDataList(TypedBytesValue.fromText(value)); + return new BytesDataList(TypedValue.fromText(value)); } public static BytesValueList singleLong(long value) { - return new BytesDataList(TypedBytesValue.fromInt64(value)); + return new BytesDataList(TypedValue.fromInt64(value)); } public static BytesValueList singleInt(int value) { - return new BytesDataList(TypedBytesValue.fromInt32(value)); + return new BytesDataList(TypedValue.fromInt32(value)); } public static BytesValueList singleBoolean(boolean value) { - return new BytesDataList(TypedBytesValue.fromBoolean(value)); + return new BytesDataList(TypedValue.fromBoolean(value)); } } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java index 3315c511..6579f1c4 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java @@ -68,7 +68,7 @@ public class BytesValueEncoding { } // 将对象序列化 byte[] serialBytes = BinaryProtocol.encode(value, type); - return TypedBytesValue.fromType(DataType.DATA_CONTRACT, serialBytes); + return TypedValue.fromType(DataType.DATA_CONTRACT, serialBytes); } BytesValueResolver bytesValueResolver = CLASS_RESOLVER_MAP.get(type); if (bytesValueResolver == null) { diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java index 9ee1a75b..4683f9ca 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java @@ -6,7 +6,7 @@ import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.consts.DataCodes; @DataContract(code= DataCodes.CONTRACT_ACCOUNT_HEADER) -public interface ContractInfo extends AccountHeader { +public interface ContractInfo extends BlockchainIdentity { @DataField(order=4, primitiveType= PrimitiveType.BYTES) byte[] getChainCode(); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedBytesValue.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java similarity index 78% rename from source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedBytesValue.java rename to source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java index 6436f816..333badaa 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedBytesValue.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java @@ -15,29 +15,29 @@ import com.jd.blockchain.utils.io.BytesUtils; * @author huanghaiquan * */ -public class TypedBytesValue implements BytesValue { +public class TypedValue implements BytesValue { - public static final BytesValue NIL = new TypedBytesValue(); + public static final BytesValue NIL = new TypedValue(); private DataType type; private Bytes value; - private TypedBytesValue(DataType type, byte[] bytes) { + private TypedValue(DataType type, byte[] bytes) { this.type = type; this.value = new Bytes(bytes); } - private TypedBytesValue(DataType type, Bytes bytes) { + private TypedValue(DataType type, Bytes bytes) { this.type = type; this.value = bytes; } - private TypedBytesValue(BytesValue bytesValue) { + private TypedValue(BytesValue bytesValue) { this.type = bytesValue.getType(); this.value = bytesValue.getValue(); } - private TypedBytesValue() { + private TypedValue() { this.type = DataType.NIL; } @@ -383,28 +383,28 @@ public class TypedBytesValue implements BytesValue { return new SignatureDigest(toBytesArray()); } - public static TypedBytesValue wrap(BytesValue value) { - return new TypedBytesValue(value); + public static TypedValue wrap(BytesValue value) { + return new TypedValue(value); } - public static TypedBytesValue fromType(DataType type, byte[] value) { - return new TypedBytesValue(type, value); + public static TypedValue fromType(DataType type, byte[] value) { + return new TypedValue(type, value); } - public static TypedBytesValue fromBytes(byte[] value) { - return new TypedBytesValue(DataType.BYTES, value); + public static TypedValue fromBytes(byte[] value) { + return new TypedValue(DataType.BYTES, value); } - public static TypedBytesValue fromBytes(Bytes value) { - return new TypedBytesValue(DataType.BYTES, value); + public static TypedValue fromBytes(Bytes value) { + return new TypedValue(DataType.BYTES, value); } - public static TypedBytesValue fromImage(byte[] value) { - return new TypedBytesValue(DataType.IMG, value); + public static TypedValue fromImage(byte[] value) { + return new TypedValue(DataType.IMG, value); } - public static TypedBytesValue fromImage(Bytes value) { - return new TypedBytesValue(DataType.IMG, value); + public static TypedValue fromImage(Bytes value) { + return new TypedValue(DataType.IMG, value); } /** @@ -413,43 +413,43 @@ public class TypedBytesValue implements BytesValue { * @param value * @return */ - public static TypedBytesValue fromText(String value) { - return new TypedBytesValue(DataType.TEXT, BytesUtils.toBytes(value)); + public static TypedValue fromText(String value) { + return new TypedValue(DataType.TEXT, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromJSON(String value) { - return new TypedBytesValue(DataType.JSON, BytesUtils.toBytes(value)); + public static TypedValue fromJSON(String value) { + return new TypedValue(DataType.JSON, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromXML(String value) { - return new TypedBytesValue(DataType.XML, BytesUtils.toBytes(value)); + public static TypedValue fromXML(String value) { + return new TypedValue(DataType.XML, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromInt32(int value) { - return new TypedBytesValue(DataType.INT32, BytesUtils.toBytes(value)); + public static TypedValue fromInt32(int value) { + return new TypedValue(DataType.INT32, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromInt64(long value) { - return new TypedBytesValue(DataType.INT64, BytesUtils.toBytes(value)); + public static TypedValue fromInt64(long value) { + return new TypedValue(DataType.INT64, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromInt16(short value) { - return new TypedBytesValue(DataType.INT16, BytesUtils.toBytes(value)); + public static TypedValue fromInt16(short value) { + return new TypedValue(DataType.INT16, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromInt8(byte value) { - return new TypedBytesValue(DataType.INT8, BytesUtils.toBytes(value)); + public static TypedValue fromInt8(byte value) { + return new TypedValue(DataType.INT8, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromTimestamp(long value) { - return new TypedBytesValue(DataType.TIMESTAMP, BytesUtils.toBytes(value)); + public static TypedValue fromTimestamp(long value) { + return new TypedValue(DataType.TIMESTAMP, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromBoolean(boolean value) { - return new TypedBytesValue(DataType.BOOLEAN, BytesUtils.toBytes(value)); + public static TypedValue fromBoolean(boolean value) { + return new TypedValue(DataType.BOOLEAN, BytesUtils.toBytes(value)); } - public static TypedBytesValue fromPubKey(PubKey pubKey) { - return new TypedBytesValue(DataType.PUB_KEY, pubKey.toBytes()); + public static TypedValue fromPubKey(PubKey pubKey) { + return new TypedValue(DataType.PUB_KEY, pubKey.toBytes()); } } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java index 0fcfd9ef..8fc0e7a5 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAccountHeader.java @@ -5,7 +5,7 @@ import com.jd.blockchain.consts.DataCodes; import com.jd.blockchain.crypto.PubKey; @DataContract(code= DataCodes.USER_ACCOUNT_HEADER) -public interface UserAccountHeader extends AccountHeader { +public interface UserAccountHeader extends BlockchainIdentity { PubKey getDataPubKey(); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java index bcc688cf..69285395 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BooleanToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class BooleanToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return TypedBytesValue.fromBoolean((boolean) value); + return TypedValue.fromBoolean((boolean) value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java index d455e471..fe71eee7 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,9 +21,9 @@ public class BytesToBytesValueResolver extends AbstractBytesValueResolver { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } if (type.equals(byte[].class)) { - return TypedBytesValue.fromBytes((byte[]) value); + return TypedValue.fromBytes((byte[]) value); } - return TypedBytesValue.fromBytes((Bytes) value); + return TypedValue.fromBytes((Bytes) value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java index 6eec5e6f..075d1f76 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class IntegerToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return TypedBytesValue.fromInt32((int) value); + return TypedValue.fromInt32((int) value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java index 9ae9910e..ce6dbaf9 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class LongToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return TypedBytesValue.fromInt64((long)value); + return TypedValue.fromInt64((long)value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java index 220d6121..ddbed5fb 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -21,7 +21,7 @@ public class ShortToBytesValueResolver extends AbstractBytesValueResolver { if (!isSupport(type)) { throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName())); } - return TypedBytesValue.fromInt16((short)value); + return TypedValue.fromInt16((short)value); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java index 56da60bf..0f08442e 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.resolver; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataType; import com.jd.blockchain.utils.Bytes; @@ -26,10 +26,10 @@ public class StringToBytesValueResolver extends AbstractBytesValueResolver { // 类型判断 String valString = (String)value; if (JSONSerializeUtils.isJSON(valString)) { - return TypedBytesValue.fromJSON(valString); + return TypedValue.fromJSON(valString); } // 暂不处理XML格式 - return TypedBytesValue.fromText(valString); + return TypedValue.fromText(valString); } @Override diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java index 9710b50d..9d8f5fa8 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java @@ -3,7 +3,7 @@ package com.jd.blockchain.transaction; import org.springframework.cglib.core.Block; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.ContractInfo; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.KVInfoVO; @@ -250,7 +250,7 @@ public interface BlockchainQueryService { * @param address * @return */ - AccountHeader getDataAccount(HashDigest ledgerHash, String address); + BlockchainIdentity getDataAccount(HashDigest ledgerHash, String address); /** * 返回数据账户中指定的键的最新值;
@@ -306,7 +306,7 @@ public interface BlockchainQueryService { * @param count * @return */ - AccountHeader[] getUsers(HashDigest ledgerHash, int fromIndex, int count); + BlockchainIdentity[] getUsers(HashDigest ledgerHash, int fromIndex, int count); /** * get data accounts by ledgerHash and its range; @@ -316,7 +316,7 @@ public interface BlockchainQueryService { * @param count * @return */ - AccountHeader[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count); + BlockchainIdentity[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count); /** * get contract accounts by ledgerHash and its range; @@ -326,5 +326,5 @@ public interface BlockchainQueryService { * @param count * @return */ - AccountHeader[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count); + BlockchainIdentity[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count); } 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 f0e1a18b..cec540c9 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 @@ -1,7 +1,7 @@ package com.jd.blockchain.transaction; import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.utils.Bytes; @@ -26,14 +26,14 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe @Override public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromBytes(value); + BytesValue bytesValue = TypedValue.fromBytes(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromImage(value); + BytesValue bytesValue = TypedValue.fromImage(value); operation.set(key, bytesValue, expVersion); return this; } @@ -45,42 +45,42 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe @Override public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromText(value); + BytesValue bytesValue = TypedValue.fromText(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromBytes(value); + BytesValue bytesValue = TypedValue.fromBytes(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromInt64(value); + BytesValue bytesValue = TypedValue.fromInt64(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromJSON(value); + BytesValue bytesValue = TypedValue.fromJSON(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromXML(value); + BytesValue bytesValue = TypedValue.fromXML(value); operation.set(key, bytesValue, expVersion); return this; } @Override public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) { - BytesValue bytesValue = TypedBytesValue.fromTimestamp(value); + BytesValue bytesValue = TypedValue.fromTimestamp(value); operation.set(key, bytesValue, expVersion); return this; } diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java index 271063ec..506d86d4 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ContractEventSendOpTemplateTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.BytesDataList; import com.jd.blockchain.ledger.BytesValueList; import com.jd.blockchain.ledger.ContractEventSendOperation; @@ -41,7 +41,7 @@ public class ContractEventSendOpTemplateTest { DataContractRegistry.register(ContractEventSendOperation.class); DataContractRegistry.register(Operation.class); String contractAddress = "zhangsan-address", event = "zhangsan-event"; - BytesValueList args = new BytesDataList(TypedBytesValue.fromText("zhangsan-args")); + BytesValueList args = new BytesDataList(TypedValue.fromText("zhangsan-args")); data = new ContractEventSendOpTemplate(Bytes.fromString(contractAddress), event, args); } diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java index c75eeed7..a3faea12 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; @@ -41,11 +41,11 @@ public class DataAccountKVSetOpTemplateTest { String accountAddress = "zhangsandhakhdkah"; data = new DataAccountKVSetOpTemplate(Bytes.fromString(accountAddress)); KVData kvData1 = - new KVData("test1", TypedBytesValue.fromText("zhangsan"), 9999L); + new KVData("test1", TypedValue.fromText("zhangsan"), 9999L); KVData kvData2 = - new KVData("test2", TypedBytesValue.fromText("lisi"), 9990L); + new KVData("test2", TypedValue.fromText("lisi"), 9990L); KVData kvData3 = - new KVData("test3", TypedBytesValue.fromText("wangwu"), 1990L); + new KVData("test3", TypedValue.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/KVDataTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java index 8a914f7f..bcadfc1e 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.ledger.TypedBytesValue; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; import com.jd.blockchain.transaction.KVData; @@ -38,7 +38,7 @@ public class KVDataTest { byte[] value = "test-value".getBytes(); long expectedVersion = 9999L; - kvData = new KVData(key, TypedBytesValue.fromBytes(value), expectedVersion); + kvData = new KVData(key, TypedValue.fromBytes(value), expectedVersion); } @Test 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 ad5f3aeb..64b7bbef 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 @@ -326,7 +326,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts/address/{address}") @Override - public AccountHeader getDataAccount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity getDataAccount(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @PathVariable(name = "address") String address) { LedgerQuery ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); @@ -350,11 +350,11 @@ public class LedgerQueryController implements BlockchainQueryService { KVDataEntry[] entries = new KVDataEntry[keys.length]; long ver; for (int i = 0; i < entries.length; i++) { - ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); + ver = dataAccount.getDataset().getVersion(Bytes.fromString(keys[i])); if (ver < 0) { entries[i] = new KVDataObject(keys[i], -1, null); } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + BytesValue value = dataAccount.getDataset().getValue(Bytes.fromString(keys[i]), ver); entries[i] = new KVDataObject(keys[i], ver, value); } } @@ -405,11 +405,11 @@ public class LedgerQueryController implements BlockchainQueryService { entries[i] = new KVDataObject(keys[i], -1, null); } else { if (dataAccount.getDataEntriesTotalCount() == 0 - || dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null) { + || dataAccount.getDataset().getValue(Bytes.fromString(keys[i]), ver) == null) { // is the address is not exist; the result is null; entries[i] = new KVDataObject(keys[i], -1, null); } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + BytesValue value = dataAccount.getDataset().getValue(Bytes.fromString(keys[i]), ver); entries[i] = new KVDataObject(keys[i], ver, value); } } @@ -468,7 +468,7 @@ public class LedgerQueryController implements BlockchainQueryService { */ @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/users") @Override - public AccountHeader[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { LedgerQuery ledger = ledgerService.getLedger(ledgerHash); @@ -488,7 +488,7 @@ public class LedgerQueryController implements BlockchainQueryService { */ @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts") @Override - public AccountHeader[] getDataAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity[] getDataAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { LedgerQuery ledger = ledgerService.getLedger(ledgerHash); @@ -500,7 +500,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts") @Override - public AccountHeader[] getContractAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public BlockchainIdentity[] getContractAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { LedgerQuery ledger = ledgerService.getLedger(ledgerHash); diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java index ef63137f..895010f3 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java @@ -151,7 +151,7 @@ public class ClientResolveUtil { String realValBase58 = valueObj.getJSONObject("value").getString("value"); String key = currWriteSetObj.getString("key"); DataType dataType = DataType.valueOf(typeStr); - BytesValue bytesValue = TypedBytesValue.fromType(dataType, Base58Utils.decode(realValBase58)); + BytesValue bytesValue = TypedValue.fromType(dataType, Base58Utils.decode(realValBase58)); KVData kvData = new KVData(key, bytesValue, expectedVersion); kvOperation.set(kvData); } diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java index ff1c9176..4949a777 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java @@ -1,7 +1,7 @@ package com.jd.blockchain.sdk.proxy; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.ContractInfo; import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.KVInfoVO; @@ -156,7 +156,7 @@ public abstract class BlockchainServiceProxy implements BlockchainService { } @Override - public AccountHeader getDataAccount(HashDigest ledgerHash, String address) { + public BlockchainIdentity getDataAccount(HashDigest ledgerHash, String address) { return getQueryService(ledgerHash).getDataAccount(ledgerHash, address); } @@ -189,17 +189,17 @@ public abstract class BlockchainServiceProxy implements BlockchainService { } @Override - public AccountHeader[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getUsers(HashDigest ledgerHash, int fromIndex, int count) { return getQueryService(ledgerHash).getUsers(ledgerHash, fromIndex, count); } @Override - public AccountHeader[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count) { return getQueryService(ledgerHash).getDataAccounts(ledgerHash, fromIndex, count); } @Override - public AccountHeader[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { + public BlockchainIdentity[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count) { return getQueryService(ledgerHash).getContractAccounts(ledgerHash, fromIndex, count); } } diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java index ccd5ceec..56127820 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java @@ -487,7 +487,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService */ @HttpAction(method=HttpMethod.GET, path="ledgers/{ledgerHash}/accounts/address/{address}") @Override - AccountHeader getDataAccount(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, + BlockchainIdentity getDataAccount(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, @PathParam(name="address") String address); /** @@ -569,7 +569,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService */ @HttpAction(method = HttpMethod.GET, path = "ledgers/{ledgerHash}/users") @Override - AccountHeader[] getUsers(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, + BlockchainIdentity[] getUsers(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, @RequestParam(name="fromIndex", required = false) int fromIndex, @RequestParam(name="count", required = false) int count); @@ -582,7 +582,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService */ @HttpAction(method = HttpMethod.GET, path = "ledgers/{ledgerHash}/accounts") @Override - AccountHeader[] getDataAccounts(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, + BlockchainIdentity[] getDataAccounts(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, @RequestParam(name="fromIndex", required = false) int fromIndex, @RequestParam(name="count", required = false) int count); @@ -595,7 +595,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService */ @HttpAction(method = HttpMethod.GET, path = "ledgers/{ledgerHash}/contracts") @Override - AccountHeader[] getContractAccounts(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, + BlockchainIdentity[] getContractAccounts(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, @RequestParam(name="fromIndex", required = false) int fromIndex, @RequestParam(name="count", required = false) int count); diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java index 3851d6a7..346aae79 100644 --- a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java +++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java @@ -19,7 +19,7 @@ import com.jd.blockchain.crypto.HashFunction; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.crypto.SignatureDigest; import com.jd.blockchain.crypto.SignatureFunction; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.DigitalSignature; @@ -98,7 +98,7 @@ public class SDK_GateWay_Query_Test_ { System.out.println("contractCount=" + count); count = service.getContractCount(ledgerHash, hashDigest); System.out.println("contractCount=" + count); - AccountHeader contract = service.getContract(ledgerHash, "12345678"); + BlockchainIdentity contract = service.getContract(ledgerHash, "12345678"); System.out.println(contract); LedgerBlock block = service.getBlock(ledgerHash, hashDigest); @@ -109,7 +109,7 @@ public class SDK_GateWay_Query_Test_ { count = service.getDataAccountCount(ledgerHash, hashDigest); System.out.println("dataAccountCount=" + count); - AccountHeader dataAccount = service.getDataAccount(ledgerHash, "1245633"); + BlockchainIdentity dataAccount = service.getDataAccount(ledgerHash, "1245633"); System.out.println(dataAccount.getAddress()); count = service.getTransactionCount(ledgerHash, hashDigest); 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 70ca67b7..421dfd89 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 @@ -21,7 +21,7 @@ import com.jd.blockchain.crypto.KeyGenUtils; import com.jd.blockchain.crypto.PrivKey; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.BytesValue; @@ -420,7 +420,7 @@ public class IntegrationTest { UserInfo userInfo = blockchainService.getUser(ledgerHash, userAddress.toString()); // getDataAccount - AccountHeader accountHeader = blockchainService.getDataAccount(ledgerHash, dataAddress.toString()); + BlockchainIdentity accountHeader = blockchainService.getDataAccount(ledgerHash, dataAddress.toString()); // getDataEntries @@ -660,9 +660,9 @@ public class IntegrationTest { LedgerQuery ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); LedgerBlock block = ledgerOfNode0.getBlock(txResp.getBlockHeight()); BytesValue val1InDb = ledgerOfNode0.getDataAccountSet(block).getAccount(contractDataKey.getAddress()) - .getBytes("A"); + .getDataset().getValue("A"); BytesValue val2InDb = ledgerOfNode0.getDataAccountSet(block).getAccount(contractDataKey.getAddress()) - .getBytes(KEY_TOTAL); + .getDataset().getValue(KEY_TOTAL); } /** diff --git a/source/test/test-ledger/src/main/java/test/perf/com/jd/blockchain/ledger/MerkleDatasetPerformanceTester.java b/source/test/test-ledger/src/main/java/test/perf/com/jd/blockchain/ledger/MerkleDatasetPerformanceTester.java index 7b5faffb..a71efcee 100644 --- a/source/test/test-ledger/src/main/java/test/perf/com/jd/blockchain/ledger/MerkleDatasetPerformanceTester.java +++ b/source/test/test-ledger/src/main/java/test/perf/com/jd/blockchain/ledger/MerkleDatasetPerformanceTester.java @@ -14,6 +14,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.storage.service.impl.redis.RedisConnectionFactory; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; +import com.jd.blockchain.utils.Bytes; public class MerkleDatasetPerformanceTester { @@ -156,12 +157,12 @@ public class MerkleDatasetPerformanceTester { for (int i = 0; i < round; i++) { for (int j = 0; j < batchCount; j++) { key = "data_" + startTs + "_" + randomId + "_" + (i * batchCount + j); - long v = mds.getVersion(key); - mds.setValue(key, data, v); + long v = mds.getVersion(Bytes.fromString(key)); + mds.setValue(Bytes.fromString(key), data, v); } mds.commit(); rootHash = mds.getRootHash(); - mds = new MerkleDataSet(rootHash, cryptoConfig, MKL_KEY_PREFIX, exStorage, verStorage, false); + mds = new MerkleDataSet(rootHash, cryptoConfig, Bytes.fromString(MKL_KEY_PREFIX), exStorage, verStorage, false); } long elapsedTs = System.currentTimeMillis() - startTs; From e3436dfb2514d300dc759e9d3df79c0dc6a637cd Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Thu, 24 Oct 2019 10:16:07 +0800 Subject: [PATCH 5/9] Refactored dataset of accounts; --- .../ledger/core/AccountDecorator.java | 8 +- .../ledger/core/ContractAccount.java | 16 +- .../blockchain/ledger/core/LedgerAccount.java | 7 +- .../ledger/core/LedgerQueryService.java | 20 +- .../blockchain/ledger/core/MerkleAccount.java | 462 ++++++++++-------- .../ledger/core/MerkleAccountSet.java | 85 ++-- .../ledger/core/MerkleDataCluster.java | 2 +- .../ledger/core/MerkleDataEntry.java | 4 +- .../blockchain/ledger/core/MerkleDataSet.java | 95 ++-- .../ledger/core/RolePrivilegeDataset.java | 6 +- .../blockchain/ledger/core/UserAccount.java | 16 +- .../ledger/core/UserRoleDataset.java | 6 +- .../DataAccountKVSetOperationHandle.java | 3 +- .../ledger/core/AccountSetTest.java | 4 +- .../ledger/core/BaseAccountTest.java | 12 +- .../ledger/core/ContractInvokingTest.java | 2 +- .../ledger/core/LedgerAccountTest.java | 50 +- .../ledger/core/LedgerEditorTest.java | 14 +- .../ledger/core/MerkleDataSetTest.java | 81 +-- .../core/TransactionBatchProcessorTest.java | 16 +- .../impl/redis/RedisVerioningStorage.java | 6 +- .../rocksdb/RocksDBVersioningStorage.java | 6 +- .../storage/service/VersioningKVStorage.java | 4 +- .../service/utils/BufferedKVStorage.java | 8 +- .../service/utils/MemoryKVStorage.java | 4 +- .../service/utils/VersioningKVData.java | 4 +- .../service/utils/VersioningKVStorageMap.java | 6 +- .../intgr/IntegrationTestAll4Redis.java | 70 ++- .../com/jd/blockchain/utils/DataEntry.java | 17 + .../{VersioningMap.java => Dataset.java} | 8 +- .../jd/blockchain/utils/DatasetHelper.java | 301 ++++++++++++ .../com/jd/blockchain/utils/RegionMap.java | 122 ----- .../blockchain/utils/VersioningKVEntry.java | 17 - 33 files changed, 878 insertions(+), 604 deletions(-) create mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataEntry.java rename source/utils/utils-common/src/main/java/com/jd/blockchain/utils/{VersioningMap.java => Dataset.java} (95%) create mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java delete mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java delete mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java index a0fddbe1..8e30be95 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java @@ -2,11 +2,11 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.HashProof; import com.jd.blockchain.ledger.MerkleSnapshot; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningMap; +import com.jd.blockchain.utils.Dataset; public class AccountDecorator implements LedgerAccount, HashProvable, MerkleSnapshot{ @@ -16,7 +16,7 @@ public class AccountDecorator implements LedgerAccount, HashProvable, MerkleSnap this.mklAccount = mklAccount; } - protected VersioningMap getHeaders() { + protected Dataset getHeaders() { return mklAccount.getHeaders(); } @@ -37,7 +37,7 @@ public class AccountDecorator implements LedgerAccount, HashProvable, MerkleSnap } @Override - public VersioningMap getDataset() { + public Dataset getDataset() { return mklAccount.getDataset(); } 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 514ddf0f..b0f8104d 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 @@ -8,9 +8,9 @@ import com.jd.blockchain.utils.Bytes; public class ContractAccount extends AccountDecorator implements ContractInfo { - private static final Bytes CONTRACT_INFO_PREFIX = Bytes.fromString("INFO" + LedgerConsts.KEY_SEPERATOR); + private static final String CONTRACT_INFO_PREFIX = "INFO" + LedgerConsts.KEY_SEPERATOR; - private static final Bytes CHAIN_CODE_KEY = Bytes.fromString("CHAIN-CODE"); + private static final String CHAIN_CODE_KEY = "CHAIN-CODE"; public ContractAccount(MerkleAccount mklAccount) { super(mklAccount); @@ -35,7 +35,7 @@ public class ContractAccount extends AccountDecorator implements ContractInfo { // } public long setChaincode(byte[] chaincode, long version) { - BytesValue bytesValue = TypedValue.fromBytes(chaincode); + TypedValue bytesValue = TypedValue.fromBytes(chaincode); return getHeaders().setValue(CHAIN_CODE_KEY, bytesValue, version); } @@ -51,22 +51,22 @@ public class ContractAccount extends AccountDecorator implements ContractInfo { return getHeaders().getVersion(CHAIN_CODE_KEY); } - public long setProperty(Bytes key, String value, long version) { - BytesValue bytesValue = TypedValue.fromText(value); + public long setProperty(String key, String value, long version) { + TypedValue bytesValue = TypedValue.fromText(value); return getHeaders().setValue(encodePropertyKey(key), bytesValue, version); } - public String getProperty(Bytes key) { + public String getProperty(String key) { BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key)); return TypedValue.wrap(bytesValue).stringValue(); } - public String getProperty(Bytes key, long version) { + public String getProperty(String key, long version) { BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key), version); return TypedValue.wrap(bytesValue).stringValue(); } - private Bytes encodePropertyKey(Bytes key) { + private String encodePropertyKey(String key) { return CONTRACT_INFO_PREFIX.concat(key); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java index 02d6c7a1..f57777ed 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java @@ -1,14 +1,13 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningMap; +import com.jd.blockchain.ledger.TypedValue; +import com.jd.blockchain.utils.Dataset; public interface LedgerAccount { BlockchainIdentity getID(); - VersioningMap getDataset(); + Dataset getDataset(); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java index 267d8fbc..b965f842 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java @@ -29,16 +29,16 @@ import com.jd.blockchain.utils.QueryUtil; public class LedgerQueryService implements BlockchainQueryService { private static final KVDataEntry[] EMPTY_ENTRIES = new KVDataEntry[0]; - + private HashDigest[] ledgerHashs; private LedgerQuery ledger; public LedgerQueryService(LedgerQuery ledger) { this.ledger = ledger; - this.ledgerHashs = new HashDigest[] {ledger.getHash()}; + this.ledgerHashs = new HashDigest[] { ledger.getHash() }; } - + private void checkLedgerHash(HashDigest ledgerHash) { if (!ledgerHashs[0].equals(ledgerHash)) { throw new LedgerException("Unsupport cross chain query!"); @@ -59,7 +59,7 @@ public class LedgerQueryService implements BlockchainQueryService { ledgerInfo.setLatestBlockHeight(ledger.getLatestBlockHeight()); return ledgerInfo; } - + @Override public LedgerAdminInfo getLedgerAdminInfo(HashDigest ledgerHash) { checkLedgerHash(ledgerHash); @@ -345,12 +345,12 @@ public class LedgerQueryService implements BlockchainQueryService { if (ver < 0) { entries[i] = new KVDataObject(keys[i], -1, null); } else { - if (dataAccount.getDataset().getDataEntriesTotalCount() == 0 - || dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null) { + if (dataAccount.getDataset().getDataCount() == 0 + || dataAccount.getDataset().getValue(keys[i], ver) == null) { // is the address is not exist; the result is null; entries[i] = new KVDataObject(keys[i], -1, null); } else { - BytesValue value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); + BytesValue value = dataAccount.getDataset().getValue(keys[i], ver); entries[i] = new KVDataObject(keys[i], ver, value); } } @@ -366,8 +366,8 @@ public class LedgerQueryService implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataEntriesTotalCount()); - return dataAccount.getDataEntries(pages[0], pages[1]); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataset().getDataCount()); + return dataAccount.getDataset()..getDataEntries(pages[0], pages[1]); } @Override @@ -377,7 +377,7 @@ public class LedgerQueryService implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - return dataAccount.getDataEntriesTotalCount(); + return dataAccount.getDataset().getDataCount(); } @Override diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java index 63fcc445..384b39bd 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java @@ -14,9 +14,11 @@ import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.Dataset; +import com.jd.blockchain.utils.DatasetHelper; +import com.jd.blockchain.utils.DatasetHelper.DataChangedListener; +import com.jd.blockchain.utils.DatasetHelper.TypeMapper; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningKVEntry; -import com.jd.blockchain.utils.VersioningMap; /** * 事务性的基础账户; @@ -29,21 +31,25 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho private static final Bytes HEADER_PREFIX = Bytes.fromString("HD/"); private static final Bytes DATA_PREFIX = Bytes.fromString("DT/"); - private static final Bytes KEY_PUBKEY = Bytes.fromString("PUBKEY"); - private static final Bytes KEY_HEADER_ROOT = Bytes.fromString("HEADER"); private static final Bytes KEY_DATA_ROOT = Bytes.fromString("DATA"); + private static final String KEY_PUBKEY = "PUBKEY"; + private BlockchainIdentity accountID; - private MerkleDataSet rootDS; + private MerkleDataSet rootDataset; + + private MerkleDataSet headerDataset; - private MerkleDatasetAdapter headerDS; + private MerkleDataSet dataDataset; - private MerkleDatasetAdapter dataDS; + private Dataset typedHeader; - protected long version; + private Dataset typedData; + + private long version; /** * Create a new Account with the specified address and pubkey;
@@ -103,40 +109,58 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho */ private MerkleAccount(Bytes address, PubKey pubKey, long version, HashDigest rootHash, CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { - // 初始化账户的身份; - this.accountID = new AutoloadingID(address, pubKey); - this.version = version; // 加载“根数据集” - this.rootDS = new MerkleDataSet(rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + this.rootDataset = new MerkleDataSet(rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); // 初始化数据修改监听器; - DataChangedListener dataChangedListener = new DataChangedListener() { + DataChangedListener dataChangedListener = new DataChangedListener() { + @Override + public void onChanged(String key, TypedValue value, long expectedVersion, long newVersion) { + onUpdated(key, value, expectedVersion, newVersion); + } + }; + + TypeMapper valueMapper = new TypeMapper() { + + @Override + public byte[] encode(TypedValue t2) { + return BinaryProtocol.encode(t2, BytesValue.class); + } + @Override - public void onChanged(Bytes key, BytesValue value, long newVersion) { - onUpdated(keyPrefix, value, newVersion); + public TypedValue decode(byte[] t1) { + BytesValue v = BinaryProtocol.decodeAs(t1, BytesValue.class); + return TypedValue.wrap(v); } }; // 加载“头数据集”; HashDigest headerRoot = loadHeaderRoot(); Bytes headerPrefix = keyPrefix.concat(HEADER_PREFIX); - MerkleDataSet headerDataset = new MerkleDataSet(headerRoot, cryptoSetting, headerPrefix, exStorage, verStorage, + this.headerDataset = new MerkleDataSet(headerRoot, cryptoSetting, headerPrefix, exStorage, verStorage, readonly); - this.headerDS = new MerkleDatasetAdapter(headerDataset, dataChangedListener); + this.typedHeader = DatasetHelper.listen(DatasetHelper.map(headerDataset, valueMapper), dataChangedListener); // 加载“主数据集” HashDigest dataRoot = loadDataRoot(); Bytes dataPrefix = keyPrefix.concat(DATA_PREFIX); - MerkleDataSet dataDataset = new MerkleDataSet(dataRoot, cryptoSetting, dataPrefix, exStorage, verStorage, - readonly); - this.dataDS = new MerkleDatasetAdapter(dataDataset, dataChangedListener); + this.dataDataset = new MerkleDataSet(dataRoot, cryptoSetting, dataPrefix, exStorage, verStorage, readonly); + this.typedData = DatasetHelper.listen(DatasetHelper.map(dataDataset, valueMapper), dataChangedListener); + // 初始化账户的身份; + if (pubKey == null) { + if (version < 0) { + throw new IllegalArgumentException("Specified a null PubKey for newly Account!"); + } + pubKey = loadPubKey(); + } + this.accountID = new AccountID(address, pubKey); } private HashDigest loadHeaderRoot() { - byte[] hashBytes = rootDS.getValue(KEY_HEADER_ROOT); + byte[] hashBytes = rootDataset.getValue(KEY_HEADER_ROOT); if (hashBytes == null) { return null; } @@ -144,7 +168,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho } private HashDigest loadDataRoot() { - byte[] hashBytes = rootDS.getValue(KEY_DATA_ROOT); + byte[] hashBytes = rootDataset.getValue(KEY_DATA_ROOT); if (hashBytes == null) { return null; } @@ -152,11 +176,11 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho } private long getHeaderRootVersion() { - return rootDS.getVersion(KEY_HEADER_ROOT); + return rootDataset.getVersion(KEY_HEADER_ROOT); } private long getDataRootVersion() { - return rootDS.getVersion(KEY_DATA_ROOT); + return rootDataset.getVersion(KEY_DATA_ROOT); } public Bytes getAddress() { @@ -172,13 +196,13 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho return accountID; } - protected VersioningMap getHeaders() { - return headerDS; + protected Dataset getHeaders() { + return typedHeader; } @Override - public VersioningMap getDataset() { - return dataDS; + public Dataset getDataset() { + return typedData; } /* @@ -188,16 +212,16 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho */ @Override public HashDigest getRootHash() { - return rootDS.getRootHash(); + return rootDataset.getRootHash(); } @Override public HashProof getProof(Bytes key) { - MerkleProof dataProof = dataDS.getDataset().getProof(key); + MerkleProof dataProof = dataDataset.getProof(key); if (dataProof == null) { return null; } - MerkleProof rootProof = rootDS.getProof(KEY_DATA_ROOT); + MerkleProof rootProof = rootDataset.getProof(KEY_DATA_ROOT); if (rootProof == null) { return null; } @@ -212,11 +236,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho * @return */ public boolean isReadonly() { - return dataDS.getDataset().isReadonly(); - } - - public long getDataCount() { - return dataDS.getDataset().getDataCount(); + return dataDataset.isReadonly() || headerDataset.isReadonly(); } /** @@ -225,7 +245,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho * @param pubKey */ private void initPubKey(PubKey pubKey) { - long v = headerDS.setValue(KEY_PUBKEY, TypedValue.fromPubKey(pubKey), -1); + long v = typedHeader.setValue(KEY_PUBKEY, TypedValue.fromPubKey(pubKey), -1); if (v < 0) { throw new LedgerException("PubKey storage conflict!"); } @@ -237,8 +257,8 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho * @return */ private PubKey loadPubKey() { - BytesValue bytesValue = headerDS.getValue(KEY_PUBKEY); - return TypedValue.wrap(bytesValue).pubKeyValue(); + TypedValue value = typedHeader.getValue(KEY_PUBKEY); + return value.pubKeyValue(); } /** @@ -248,7 +268,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho * @param value * @param newVersion */ - protected void onUpdated(Bytes key, BytesValue value, long newVersion) { + protected void onUpdated(String key, TypedValue value, long expectedVersion, long newVersion) { } /** @@ -266,44 +286,44 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho @Override public boolean isUpdated() { - return dataDS.getDataset().isUpdated() || headerDS.getDataset().isUpdated() || rootDS.isUpdated(); + return headerDataset.isUpdated() || dataDataset.isUpdated() || rootDataset.isUpdated(); } @Override public void commit() { - if (headerDS.dataset.isUpdated()) { - headerDS.getDataset().commit(); + if (headerDataset.isUpdated()) { + headerDataset.commit(); long version = getHeaderRootVersion(); - rootDS.setValue(KEY_HEADER_ROOT, headerDS.dataset.getRootHash().toBytes(), version); + rootDataset.setValue(KEY_HEADER_ROOT, headerDataset.getRootHash().toBytes(), version); } - if (dataDS.dataset.isUpdated()) { + if (dataDataset.isUpdated()) { long version = getDataRootVersion(); - dataDS.getDataset().commit(); - rootDS.setValue(KEY_DATA_ROOT, dataDS.dataset.getRootHash().toBytes(), version); + dataDataset.commit(); + rootDataset.setValue(KEY_DATA_ROOT, dataDataset.getRootHash().toBytes(), version); } - if (rootDS.isUpdated()) { - rootDS.commit(); - this.version = onCommited(rootDS.getRootHash(), version); + if (rootDataset.isUpdated()) { + rootDataset.commit(); + this.version = onCommited(rootDataset.getRootHash(), version); } } @Override public void cancel() { - headerDS.getDataset().cancel(); - dataDS.getDataset().cancel(); - rootDS.cancel(); + headerDataset.cancel(); + dataDataset.cancel(); + rootDataset.cancel(); } // ---------------------- - private class AutoloadingID implements BlockchainIdentity { + private class AccountID implements BlockchainIdentity { private Bytes address; private PubKey pubKey; - public AutoloadingID(Bytes address, PubKey pubKey) { + public AccountID(Bytes address, PubKey pubKey) { this.address = address; this.pubKey = pubKey; } @@ -315,155 +335,201 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho @Override public PubKey getPubKey() { - if (pubKey == null) { - pubKey = loadPubKey(); - } return pubKey; } } - private static class MerkleDatasetAdapter implements VersioningMap { - - private static DataChangedListener NULL_LISTENER = new DataChangedListener() { - @Override - public void onChanged(Bytes key, BytesValue value, long newVersion) { - } - }; - - private DataChangedListener changedListener; - - private MerkleDataSet dataset; - - public MerkleDataSet getDataset() { - return dataset; - } - - public MerkleDatasetAdapter(MerkleDataSet dataset) { - this(dataset, NULL_LISTENER); - } - - public MerkleDatasetAdapter(MerkleDataSet dataset, DataChangedListener listener) { - this.dataset = dataset; - this.changedListener = listener == null ? NULL_LISTENER : listener; - } - - @Override - public VersioningKVEntry getDataEntry(Bytes key) { - return new VersioningKVEntryWraper(dataset.getDataEntry(key)); - } - - @Override - public VersioningKVEntry getDataEntry(Bytes key, long version) { - return new VersioningKVEntryWraper(dataset.getDataEntry(key, version)); - } - - /** - * Create or update the value associated the specified key if the version - * checking is passed.
- * - * The value of the key will be updated only if it's latest version equals the - * specified version argument.
- * If the key doesn't exist, the version checking will be ignored, and key will - * be created with a new sequence number as id.
- * It also could specify the version argument to -1 to ignore the version - * checking. - *

- * 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. - * @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;
- * If this operation fail by version checking or other reason, then - * return -1; - */ - @Override - public long setValue(Bytes key, BytesValue value, long version) { - byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); - long v = dataset.setValue(key, bytesValue, version); - if (v > -1) { - changedListener.onChanged(key, value, v); - } - return v; - } - - /** - * Return the latest version entry associated the specified key; If the key - * doesn't exist, then return -1; - * - * @param key - * @return - */ - @Override - public long getVersion(Bytes key) { - return dataset.getVersion(key); - } - - /** - * return the latest version's value; - * - * @param key - * @return return null if not exist; - */ - @Override - public BytesValue getValue(Bytes key) { - byte[] bytesValue = dataset.getValue(key); - if (bytesValue == null) { - return null; - } - return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); - } - - /** - * Return the specified version's value; - * - * @param key - * @param version - * @return return null if not exist; - */ - @Override - public BytesValue getValue(Bytes key, long version) { - byte[] bytesValue = dataset.getValue(key, version); - if (bytesValue == null) { - return null; - } - return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); - } - } - - private static interface DataChangedListener { - - void onChanged(Bytes key, BytesValue value, long newVersion); - + public long getVersion() { + return version; } - private static class VersioningKVEntryWraper implements VersioningKVEntry { - - private VersioningKVEntry kv; - - public VersioningKVEntryWraper(VersioningKVEntry kv) { - this.kv = kv; - } - - @Override - public Bytes getKey() { - return kv.getKey(); - } - - @Override - public long getVersion() { - return kv.getVersion(); - } - - @Override - public BytesValue getValue() { - return BinaryProtocol.decodeAs(kv.getValue(), BytesValue.class); - } - - } +// private static class MerkleDatasetAdapter implements Dataset { +// +// private static DataChangedListener NULL_LISTENER = new DataChangedListener() { +// @Override +// public void onChanged(Bytes key, BytesValue value, long newVersion) { +// } +// }; +// +// private DataChangedListener changedListener; +// +// private MerkleDataSet dataset; +// +// public MerkleDataSet getDataset() { +// return dataset; +// } +// +// @SuppressWarnings("unused") +// public MerkleDatasetAdapter(MerkleDataSet dataset) { +// this(dataset, NULL_LISTENER); +// } +// +// public MerkleDatasetAdapter(MerkleDataSet dataset, DataChangedListener listener) { +// this.dataset = dataset; +// this.changedListener = listener == null ? NULL_LISTENER : listener; +// } +// +// @Override +// public DataEntry getDataEntry(String key) { +// return new VersioningKVEntryWraper(dataset.getDataEntry(Bytes.fromString(key))); +// } +// +// @Override +// public DataEntry getDataEntry(String key, long version) { +// return new VersioningKVEntryWraper(dataset.getDataEntry(Bytes.fromString(key), version)); +// } +// +// /** +// * Create or update the value associated the specified key if the version +// * checking is passed.
+// * +// * The value of the key will be updated only if it's latest version equals the +// * specified version argument.
+// * If the key doesn't exist, the version checking will be ignored, and key will +// * be created with a new sequence number as id.
+// * It also could specify the version argument to -1 to ignore the version +// * checking. +// *

+// * 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. +// * @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;
+// * If this operation fail by version checking or other reason, then +// * return -1; +// */ +// @Override +// public long setValue(Bytes key, BytesValue value, long version) { +// byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); +// long v = dataset.setValue(key, bytesValue, version); +// if (v > -1) { +// changedListener.onChanged(key, value, v); +// } +// return v; +// } +// +// /** +// * Return the latest version entry associated the specified key; If the key +// * doesn't exist, then return -1; +// * +// * @param key +// * @return +// */ +// @Override +// public long getVersion(Bytes key) { +// return dataset.getVersion(key); +// } +// +// /** +// * return the latest version's value; +// * +// * @param key +// * @return return null if not exist; +// */ +// @Override +// public BytesValue getValue(Bytes key) { +// byte[] bytesValue = dataset.getValue(key); +// if (bytesValue == null) { +// return null; +// } +// return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); +// } +// +// /** +// * Return the specified version's value; +// * +// * @param key +// * @param version +// * @return return null if not exist; +// */ +// @Override +// public BytesValue getValue(Bytes key, long version) { +// byte[] bytesValue = dataset.getValue(key, version); +// if (bytesValue == null) { +// return null; +// } +// return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); +// } +// +// @Override +// public long getDataCount() { +// return dataset.getDataCount(); +// } +// +// @Override +// public long setValue(String key, BytesValue value, long version) { +// byte[] bytesValue = BinaryProtocol.encode(value, BytesValue.class); +// return dataset.setValue(key, bytesValue, version); +// } +// +// @Override +// public BytesValue getValue(String key, long version) { +// byte[] bytesValue = dataset.getValue(key, version); +// if (bytesValue == null) { +// return null; +// } +// return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); +// } +// +// @Override +// public BytesValue getValue(String key) { +// byte[] bytesValue = dataset.getValue(key); +// if (bytesValue == null) { +// return null; +// } +// return BinaryProtocol.decodeAs(bytesValue, BytesValue.class); +// } +// +// @Override +// public long getVersion(String key) { +// return dataset.getVersion(key); +// } +// +// @Override +// public DataEntry getDataEntry(String key) { +// return new VersioningKVEntryWraper(dataset.getDataEntry(key)); +// } +// +// @Override +// public DataEntry getDataEntry(String key, long version) { +// return new VersioningKVEntryWraper(dataset.getDataEntry(key, version)); +// } +// } + +// private static interface DataChangedListener { +// +// void onChanged(Bytes key, BytesValue value, long newVersion); +// +// } + +// private static class VersioningKVEntryWraper implements DataEntry { +// +// private DataEntry kv; +// +// public VersioningKVEntryWraper(DataEntry kv) { +// this.kv = kv; +// } +// +// @Override +// public String getKey() { +// return kv.getKey().toUTF8String(); +// } +// +// @Override +// public long getVersion() { +// return kv.getVersion(); +// } +// +// @Override +// public BytesValue getValue() { +// return BinaryProtocol.decodeAs(kv.getValue(), BytesValue.class); +// } +// +// } } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java index 3768c13f..6952c89e 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java @@ -3,27 +3,25 @@ package com.jd.blockchain.ledger.core; import java.util.HashMap; import java.util.Map; -import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.PubKey; 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.ledger.LedgerException; import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.ledger.MerkleSnapshot; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.DataEntry; import com.jd.blockchain.utils.Transactional; public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery { -// private static final Bytes ACCOUNT_ROOT_PREFIX = Bytes.fromString("ROOT/"); - static { DataContractRegistry.register(MerkleSnapshot.class); DataContractRegistry.register(BlockchainIdentity.class); @@ -92,28 +90,14 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ @Override public BlockchainIdentity[] getHeaders(int fromIndex, int count) { - byte[][] results = merkleDataset.getLatestValues(fromIndex, count); + DataEntry[] results = merkleDataset.getLatestDataEntries(fromIndex, count); - BlockchainIdentity[] accounts = new BlockchainIdentity[results.length]; + BlockchainIdentity[] ids = new BlockchainIdentity[results.length]; for (int i = 0; i < results.length; i++) { - accounts[i] = deserialize(results[i]); + InnerMerkleAccount account = createAccount(results[i].getKey(), new HashDigest(results[i].getValue()), results[i].getVersion(), true); + ids[i] = account.getID(); } - return accounts; - } - - // private VersioningAccount deserialize(byte[] txBytes) { - //// return BinaryEncodingUtils.decode(txBytes, null, Account.class); - // AccountHeaderData accInfo = BinaryEncodingUtils.decode(txBytes); - //// return new BaseAccount(accInfo.getAddress(), accInfo.getPubKey(), null, - // cryptoSetting, - //// baseExStorage, baseVerStorage, true, accessPolicy); - // return new VersioningAccount(accInfo.getAddress(), accInfo.getPubKey(), - // accInfo.getRootHash(), cryptoSetting, - // keyPrefix, baseExStorage, baseVerStorage, true, accessPolicy, accInfo.); - // } - - private BlockchainIdentity deserialize(byte[] txBytes) { - return BinaryProtocol.decodeAs(txBytes, BlockchainIdentity.class); + return ids; } /** @@ -158,9 +142,9 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ /** * 返回指定账户的版本;
* 如果账户已经注册,则返回该账户的最新版本,值大于等于 0;
- * 如果账户不存在,则返回 -1;
- * 如果指定的账户已经注册(通过 {@link #register(String, PubKey)} 方法),但尚未提交(通过 - * {@link #commit()} 方法),此方法对该账户仍然返回 0; + * 如果账户不存在,则返回 -1;
+ * 如果账户已经注册(通过 {@link #register(String, PubKey)} 方法),但尚未提交(通过 {@link #commit()} + * 方法),则返回 -1;
* * @param address * @return @@ -169,7 +153,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ InnerMerkleAccount acc = latestAccountsCache.get(address); if (acc != null) { // 已注册尚未提交,也返回 -1; - return acc.version == -1 ? 0 : acc.version; + return acc.getVersion(); } return merkleDataset.getVersion(address); @@ -189,7 +173,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ InnerMerkleAccount acc = latestAccountsCache.get(address); if (acc != null && version == -1) { return acc; - } else if (acc != null && acc.version == version) { + } else if (acc != null && acc.getVersion() == version) { return acc; } @@ -203,7 +187,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ } // 如果是不存在的,或者刚刚新增未提交的账户,则前面一步查询到的 latestVersion 小于 0, 代码不会执行到此; - if (acc != null && acc.version != latestVersion) { + if (acc != null && acc.getVersion() != latestVersion) { // 当执行到此处时,并且缓冲列表中缓存了最新的版本, // 如果当前缓存的最新账户的版本和刚刚从存储中检索得到的最新版本不一致,可能存在外部的并发更新,这超出了系统设计的逻辑; @@ -256,7 +240,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ InnerMerkleAccount cachedAcc = latestAccountsCache.get(address); if (cachedAcc != null) { - if (cachedAcc.version < 0) { + if (cachedAcc.getVersion() < 0) { // 同一个新账户已经注册,但尚未提交,所以重复注册不会引起任何变化; return cachedAcc; } @@ -272,14 +256,6 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ throw new LedgerException("Account Registering was rejected for the access policy!"); } - // String prefix = address.concat(LedgerConsts.KEY_SEPERATOR); - // ExPolicyKVStorage accExStorage = PrefixAppender.prefix(prefix, - // baseExStorage); - // VersioningKVStorage accVerStorage = PrefixAppender.prefix(prefix, - // baseVerStorage); - // BaseAccount accDS = createInstance(address, pubKey, cryptoSetting, - // accExStorage, accVerStorage); - Bytes prefix = keyPrefix.concat(address); InnerMerkleAccount acc = createInstance(accountId, cryptoSetting, prefix); latestAccountsCache.put(address, acc); @@ -300,17 +276,21 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ } private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) { - // prefix; - Bytes prefix = keyPrefix.concat(address); byte[] rootHashBytes = merkleDataset.getValue(address, version); if (rootHashBytes == null) { return null; } HashDigest rootHash = new HashDigest(rootHashBytes); + return createAccount(address, rootHash, version, readonly); + } + + private InnerMerkleAccount createAccount(Bytes address,HashDigest rootHash, long version, boolean readonly) { + // prefix; + Bytes prefix = keyPrefix.concat(address); + return new InnerMerkleAccount(address, version, rootHash, cryptoSetting, prefix, baseExStorage, baseVerStorage, readonly); - } // TODO:优化:区块链身份(地址+公钥)与其Merkle树根哈希分开独立存储; @@ -324,14 +304,9 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ */ private long saveAccount(InnerMerkleAccount account) { // 提交更改,更新哈希; - long version = account.version; account.commit(); - long newVersion = merkleDataset.setValue(account.getAddress(), account.getRootHash().toBytes(), version); - if (newVersion < 0) { - // Update fail; - throw new LedgerException("Account updating fail! --[Address=" + account.getAddress() + "]"); - } - return newVersion; + + return account.getVersion(); } @Override @@ -347,7 +322,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ try { for (InnerMerkleAccount acc : latestAccountsCache.values()) { // updated or new created; - if (acc.isUpdated() || acc.version < 0) { + if (acc.isUpdated() || acc.getVersion() < 0) { saveAccount(acc); } } @@ -394,10 +369,20 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ } @Override - protected void onUpdated(Bytes key, BytesValue value, long newVersion) { + protected void onUpdated(String key, TypedValue value, long expectedVersion, long newVersion) { updated = true; } + @Override + protected long onCommited(HashDigest newRootHash, long currentVersion) { + long newVersion = merkleDataset.setValue(this.getAddress(), newRootHash.toBytes(), currentVersion); + if (newVersion < 0) { + // Update fail; + throw new LedgerException("Account updating fail! --[Address=" + this.getAddress() + "]"); + } + return newVersion; + } + } } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java index dd3836f7..5865c3fd 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java @@ -10,7 +10,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningMap; +import com.jd.blockchain.utils.Dataset; public class MerkleDataCluster implements Transactional, MerkleSnapshot { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java index 75894d0f..15de35b5 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataEntry.java @@ -2,11 +2,11 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; public interface MerkleDataEntry { - VersioningKVEntry getData(); + DataEntry getData(); MerkleProof getProof(); } 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 896a8f37..2e31c27e 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 @@ -12,8 +12,8 @@ import com.jd.blockchain.storage.service.utils.BufferedKVStorage; import com.jd.blockchain.storage.service.utils.VersioningKVData; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningKVEntry; -import com.jd.blockchain.utils.VersioningMap; +import com.jd.blockchain.utils.DataEntry; +import com.jd.blockchain.utils.Dataset; import com.jd.blockchain.utils.io.BytesUtils; /** @@ -24,7 +24,7 @@ import com.jd.blockchain.utils.io.BytesUtils; * @author huanghaiquan * */ -public class MerkleDataSet implements Transactional, MerkleProvable, VersioningMap { +public class MerkleDataSet implements Transactional, MerkleProvable, Dataset { /** * 4 MB MaxSize of value; @@ -70,6 +70,18 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM */ public MerkleDataSet(CryptoSetting setting, String keyPrefix, ExPolicyKVStorage exPolicyStorage, VersioningKVStorage versioningStorage) { + this(setting, Bytes.fromString(keyPrefix), exPolicyStorage, versioningStorage); + } + + /** + * 创建一个新的 MerkleDataSet; + * + * @param setting 密码设置; + * @param exPolicyStorage 默克尔树的存储; + * @param versioningStorage 数据的存储; + */ + public MerkleDataSet(CryptoSetting setting, Bytes keyPrefix, ExPolicyKVStorage exPolicyStorage, + VersioningKVStorage versioningStorage) { // 缓冲对KV的写入; this.bufferedStorage = new BufferedKVStorage(exPolicyStorage, versioningStorage, false); @@ -78,20 +90,34 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM // bufferedStorage); // this.snStorage = PrefixAppender.prefix(SN_PREFIX, (ExPolicyKVStorage) // bufferedStorage); - snKeyPrefix = Bytes.fromString(keyPrefix + SN_PREFIX); - dataKeyPrefix = Bytes.fromString(keyPrefix + DATA_PREFIX); + snKeyPrefix = keyPrefix.concat(SN_PREFIX); + dataKeyPrefix = keyPrefix.concat(DATA_PREFIX); this.valueStorage = bufferedStorage; this.snStorage = bufferedStorage; // MerkleTree 本身是可缓冲的; // ExPolicyKVStorage merkleTreeStorage = // PrefixAppender.prefix(MERKLE_TREE_PREFIX, exPolicyStorage); - merkleKeyPrefix = Bytes.fromString(keyPrefix + MERKLE_TREE_PREFIX); + merkleKeyPrefix = keyPrefix.concat(MERKLE_TREE_PREFIX); ExPolicyKVStorage merkleTreeStorage = exPolicyStorage; this.merkleTree = new MerkleTree(setting, merkleKeyPrefix, merkleTreeStorage); this.snGenerator = new MerkleSequenceSNGenerator(merkleTree); } + /** + * 从指定的 Merkle 根构建的 MerkleDataSet; + * + * @param dataStorage + * @param defaultMerkleHashAlgorithm + * @param verifyMerkleHashOnLoad + * @param merkleTreeStorage + * @param snGenerator + */ + public MerkleDataSet(HashDigest merkleRootHash, CryptoSetting setting, String keyPrefix, + ExPolicyKVStorage exPolicyStorage, VersioningKVStorage versioningStorage, boolean readonly) { + this(merkleRootHash, setting, Bytes.fromString(keyPrefix), exPolicyStorage, versioningStorage, readonly); + } + /** * 从指定的 Merkle 根构建的 MerkleDataSet; * @@ -131,6 +157,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM this.readonly = true; } + @Override public long getDataCount() { return merkleTree.getDataCount(); } @@ -155,7 +182,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM return values; } - public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) { + public DataEntry[] getLatestDataEntries(int fromIndex, int count) { if (count > LedgerConsts.MAX_LIST_COUNT) { throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!"); } @@ -163,7 +190,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM throw new IllegalArgumentException("Index out of bound!"); } @SuppressWarnings("unchecked") - VersioningKVEntry[] values = new VersioningKVEntry[count]; + DataEntry[] values = new DataEntry[count]; byte[] bytesValue; for (int i = 0; i < count; i++) { MerkleDataNode dataNode = merkleTree.getData(fromIndex + i); @@ -194,7 +221,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM */ public String getKeyAtIndex(int fromIndex) { MerkleDataNode dataNode = merkleTree.getData(fromIndex); - //TODO: 未去掉前缀; + // TODO: 未去掉前缀; return dataNode.getKey().toUTF8String(); } @@ -428,8 +455,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM return getMerkleVersion(key); } -// public VersioningKVEntry getDataEntry(String key) { -// return getDataEntry(Bytes.fromString(key)); +// @Override +// public VersioningKVEntry getDataEntry(String key) { +// return getDataEntry(key, -1); // } /** @@ -438,21 +466,30 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM * @return Null if the key doesn't exist! */ @Override - public VersioningKVEntry getDataEntry(Bytes key) { - long latestVersion = getMerkleVersion(key); - if (latestVersion < 0) { - return null; - } - Bytes dataKey = encodeDataKey(key); - byte[] value = valueStorage.get(dataKey, latestVersion); - if (value == null) { - return null; - } - return new VersioningKVData(key, latestVersion, value); + public DataEntry getDataEntry(Bytes key) { + return getDataEntry(key, -1); } +// @Override +// public VersioningKVEntry getDataEntry(String key, long version) { +// Bytes keyBytes = Bytes.fromString(key); +// long latestVersion = getMerkleVersion(keyBytes); +// if (latestVersion < 0 || version > latestVersion) { +// // key not exist, or the specified version is out of the latest version indexed +// // by the current merkletree; +// return null; +// } +// version = version < 0 ? latestVersion : version; +// Bytes dataKey = encodeDataKey(keyBytes); +// byte[] value = valueStorage.get(dataKey, version); +// if (value == null) { +// return null; +// } +// return new VersioningKVData(key, version, value); +// } + @Override - public VersioningKVEntry getDataEntry(Bytes key, long version) { + public DataEntry getDataEntry(Bytes key, long version) { long latestVersion = getMerkleVersion(key); if (latestVersion < 0 || version > latestVersion) { // key not exist, or the specified version is out of the latest version indexed @@ -469,7 +506,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM } public MerkleDataEntry getMerkleEntry(Bytes key, long version) { - VersioningKVEntry dataEntry = getDataEntry(key, version); + DataEntry dataEntry = getDataEntry(key, version); if (dataEntry == null) { return null; } @@ -478,7 +515,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM } public MerkleDataEntry getMerkleEntry(Bytes key) { - VersioningKVEntry dataEntry = getDataEntry(key); + DataEntry dataEntry = getDataEntry(key); if (dataEntry == null) { return null; } @@ -505,23 +542,23 @@ public class MerkleDataSet implements Transactional, MerkleProvable, VersioningM } /** - * A wrapper for {@link VersioningKVEntry} and {@link MerkleProof}; + * A wrapper for {@link DataEntry} and {@link MerkleProof}; * * @author huanghaiquan * */ private static class MerkleDataEntryWrapper implements MerkleDataEntry { - private VersioningKVEntry data; + private DataEntry data; private MerkleProof proof; - public MerkleDataEntryWrapper(VersioningKVEntry data, MerkleProof proof) { + public MerkleDataEntryWrapper(DataEntry data, MerkleProof proof) { this.data = data; this.proof = proof; } @Override - public VersioningKVEntry getData() { + public DataEntry getData() { return data; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java index 483b5667..220b519c 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataset.java @@ -17,7 +17,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; public class RolePrivilegeDataset implements Transactional, MerkleProvable, RolePrivilegeSettings { @@ -256,7 +256,7 @@ public class RolePrivilegeDataset implements Transactional, MerkleProvable, Role public RolePrivileges getRolePrivilege(String roleName) { // 只返回最新版本; Bytes key = encodeKey(roleName); - VersioningKVEntry kv = dataset.getDataEntry(key); + DataEntry kv = dataset.getDataEntry(key); if (kv == null) { return null; } @@ -266,7 +266,7 @@ public class RolePrivilegeDataset implements Transactional, MerkleProvable, Role @Override public RolePrivileges[] getRolePrivileges(int index, int count) { - VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); + DataEntry[] kvEntries = dataset.getLatestDataEntries(index, count); RolePrivileges[] pns = new RolePrivileges[kvEntries.length]; PrivilegeSet privilege; for (int i = 0; i < pns.length; i++) { 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 2a3eda4f..df3231c4 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 @@ -15,9 +15,9 @@ import com.jd.blockchain.utils.Bytes; */ public class UserAccount extends AccountDecorator implements UserInfo { // implements UserInfo { - private static final Bytes USER_INFO_PREFIX = Bytes.fromString("PROP" + LedgerConsts.KEY_SEPERATOR); + private static final String USER_INFO_PREFIX = "PROP" + LedgerConsts.KEY_SEPERATOR; - private static final Bytes DATA_PUB_KEY = Bytes.fromString("DATA-PUBKEY"); + private static final String DATA_PUB_KEY = "DATA-PUBKEY"; public UserAccount(MerkleAccount mklAccount) { super(mklAccount); @@ -64,25 +64,21 @@ public class UserAccount extends AccountDecorator implements UserInfo { // imple } public long setProperty(String key, String value, long version) { - return setProperty(Bytes.fromString(key), value, version); - } - - public long setProperty(Bytes key, String value, long version) { return getHeaders().setValue(encodePropertyKey(key), TypedValue.fromText(value), version); } - public String getProperty(Bytes key) { + public String getProperty(String key) { BytesValue value = getHeaders().getValue(encodePropertyKey(key)); return value == null ? null : value.getValue().toUTF8String(); } - public String getProperty(Bytes key, long version) { + public String getProperty(String key, long version) { BytesValue value = getHeaders().getValue(encodePropertyKey(key), version); return value == null ? null : value.getValue().toUTF8String(); } - private Bytes encodePropertyKey(Bytes key) { - return USER_INFO_PREFIX.concat(key); + private String encodePropertyKey(String key) { + return USER_INFO_PREFIX+key; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java index e4eb37cc..8aa45ebc 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataset.java @@ -16,7 +16,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; /** * User-Role authorization data set; @@ -168,7 +168,7 @@ public class UserRoleDataset implements Transactional, MerkleProvable, UserAutho @Override public UserRoles getUserRoles(Bytes userAddress) { // 只返回最新版本; - VersioningKVEntry kv = dataset.getDataEntry(userAddress); + DataEntry kv = dataset.getDataEntry(userAddress); if (kv == null) { return null; } @@ -178,7 +178,7 @@ public class UserRoleDataset implements Transactional, MerkleProvable, UserAutho @Override public UserRoles[] getUserRoles() { - VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); + DataEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); UserRoles[] pns = new UserRoles[kvEntries.length]; RoleSet roleset; for (int i = 0; i < pns.length; i++) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java index a6758fb0..dfab3f1c 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/DataAccountKVSetOperationHandle.java @@ -5,6 +5,7 @@ import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.ledger.DataAccountKVSetOperation.KVWriteEntry; import com.jd.blockchain.ledger.DataVersionConflictException; import com.jd.blockchain.ledger.LedgerPermission; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.core.DataAccount; import com.jd.blockchain.ledger.core.LedgerDataset; import com.jd.blockchain.ledger.core.LedgerQuery; @@ -37,7 +38,7 @@ public class DataAccountKVSetOperationHandle extends AbstractLedgerOperationHand KVWriteEntry[] writeSet = kvWriteOp.getWriteSet(); long v = -1L; for (KVWriteEntry kvw : writeSet) { - v = account.getDataset().setValue(Bytes.fromString(kvw.getKey()), kvw.getValue(), kvw.getExpectedVersion()); + v = account.getDataset().setValue(kvw.getKey(), TypedValue.wrap(kvw.getValue()), kvw.getExpectedVersion()); if (v < 0) { throw new DataVersionConflictException(); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java index 1c05e28c..6a99be27 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java @@ -14,9 +14,9 @@ import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; -import com.jd.blockchain.ledger.core.MerkleAccountSet; -import com.jd.blockchain.ledger.core.MerkleAccount; import com.jd.blockchain.ledger.core.CryptoConfig; +import com.jd.blockchain.ledger.core.MerkleAccount; +import com.jd.blockchain.ledger.core.MerkleAccountSet; import com.jd.blockchain.ledger.core.OpeningAccessPolicy; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.utils.Bytes; diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java index 25a9091f..9d55b19e 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/BaseAccountTest.java @@ -55,33 +55,33 @@ public class BaseAccountTest { assertFalse(baseAccount.isReadonly()); // 在空白状态下写入数据; - long v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A"), 0); + long v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A"), 0); // 预期失败; assertEquals(-1, v); - v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A"), 1); + v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A"), 1); // 预期失败; assertEquals(-1, v); - v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A"), -1); + v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A"), -1); // 预期成功; assertEquals(0, v); - v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A-1"), -1); + v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A-1"), -1); // 已经存在版本,指定版本号-1,预期导致失败; assertEquals(-1, v); baseAccount.commit(); v = 0; for (int i = 0; i < 10; i++) { - long s = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A_" + i), v); + long s = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A_" + i), v); baseAccount.commit(); // 预期成功; assertEquals(v + 1, s); v++; } - v = baseAccount.getDataset().setValue(Bytes.fromString("A"), TypedValue.fromText("VALUE_A_" + v), v + 1); + v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A_" + v), v + 1); // 预期成功; assertEquals(-1, v); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java index 4e91c1fb..4af4c707 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java @@ -301,7 +301,7 @@ public class ContractInvokingTest { } }); // 预期数据都能够正常写入; - KVDataEntry kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataEntry("K1", + KVDataEntry kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", 0); KVDataEntry kv2 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataEntry("K2", 0); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerAccountTest.java index a50cd41e..53e9eb4d 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerAccountTest.java @@ -1,22 +1,12 @@ package test.com.jd.blockchain.ledger.core; -import static org.junit.Assert.assertEquals; - import java.util.Random; import org.junit.Before; -import org.junit.Test; -import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; -import com.jd.blockchain.crypto.service.sm.SMAlgorithm; -import com.jd.blockchain.ledger.AccountHeader; +import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.UserInfo; -import com.jd.blockchain.ledger.core.MerkleAccountSet; -import com.jd.blockchain.utils.Bytes; /** * Created by zhangshuang3 on 2018/9/3. @@ -35,27 +25,27 @@ public class LedgerAccountTest { rand.nextBytes(seed); rand.nextBytes(settingValue); rand.nextBytes(rawDigestBytes); - DataContractRegistry.register(AccountHeader.class); + DataContractRegistry.register(BlockchainIdentity.class); DataContractRegistry.register(UserInfo.class); } - @Test - public void testSerialize_AccountHeader() { - String address = "xxxxxxxxxxxx"; - PubKey pubKey = new PubKey(SMAlgorithm.SM2, rawDigestBytes); - HashDigest hashDigest = new HashDigest(ClassicAlgorithm.SHA256, rawDigestBytes); - MerkleAccountSet.AccountHeaderData accountHeaderData = new MerkleAccountSet.AccountHeaderData(Bytes.fromString(address), - pubKey, hashDigest); - - // encode and decode - byte[] encodeBytes = BinaryProtocol.encode(accountHeaderData, AccountHeader.class); - AccountHeader deAccountHeaderData = BinaryProtocol.decode(encodeBytes); - - // verify start - assertEquals(accountHeaderData.getAddress(), deAccountHeaderData.getAddress()); - assertEquals(accountHeaderData.getPubKey(), deAccountHeaderData.getPubKey()); - assertEquals(accountHeaderData.getRootHash(), deAccountHeaderData.getRootHash()); - - } +// @Test +// public void testSerialize_AccountHeader() { +// String address = "xxxxxxxxxxxx"; +// PubKey pubKey = new PubKey(SMAlgorithm.SM2, rawDigestBytes); +// HashDigest hashDigest = new HashDigest(ClassicAlgorithm.SHA256, rawDigestBytes); +// MerkleAccountSet.AccountHeaderData accountHeaderData = new MerkleAccountSet.AccountHeaderData(Bytes.fromString(address), +// pubKey, hashDigest); +// +// // encode and decode +// byte[] encodeBytes = BinaryProtocol.encode(accountHeaderData, AccountHeader.class); +// AccountHeader deAccountHeaderData = BinaryProtocol.decode(encodeBytes); +// +// // verify start +// assertEquals(accountHeaderData.getAddress(), deAccountHeaderData.getAddress()); +// assertEquals(accountHeaderData.getPubKey(), deAccountHeaderData.getPubKey()); +// assertEquals(accountHeaderData.getRootHash(), deAccountHeaderData.getRootHash()); + +// } } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java index 97979205..0bd470a7 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java @@ -8,12 +8,9 @@ import org.junit.Before; import org.junit.Test; import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.Crypto; -import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.SignatureFunction; -import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; @@ -25,7 +22,7 @@ import com.jd.blockchain.ledger.LedgerInitSetting; import com.jd.blockchain.ledger.LedgerTransaction; import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionState; -import com.jd.blockchain.ledger.core.CryptoConfig; +import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.ledger.core.DataAccount; import com.jd.blockchain.ledger.core.LedgerDataset; import com.jd.blockchain.ledger.core.LedgerEditor; @@ -33,11 +30,6 @@ import com.jd.blockchain.ledger.core.LedgerTransactionContext; import com.jd.blockchain.ledger.core.LedgerTransactionalEditor; import com.jd.blockchain.ledger.core.UserAccount; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; -import com.jd.blockchain.transaction.ConsensusParticipantData; -import com.jd.blockchain.transaction.LedgerInitData; -import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; -import com.jd.blockchain.utils.net.NetworkAddress; public class LedgerEditorTest { @@ -102,7 +94,7 @@ public class LedgerEditorTest { DataAccount dataAccount = ldgDS.getDataAccountSet().register(dataKP.getAddress(), dataKP.getPubKey(), null); - dataAccount.setBytes(Bytes.fromString("A"), "abc", -1); + dataAccount.getDataset().setValue("A", TypedValue.fromText("abc"), -1); LedgerTransaction tx = genisisTxCtx.commit(TransactionState.SUCCESS); LedgerBlock block = ldgEdt.prepare(); @@ -115,7 +107,7 @@ public class LedgerEditorTest { assertEquals(0, block.getHeight()); // 验证数据读写的一致性; - BytesValue bytes = dataAccount.getBytes("A"); + BytesValue bytes = dataAccount.getDataset().getValue("A"); assertEquals(DataType.TEXT, bytes.getType()); String textValue = bytes.getValue().toUTF8String(); assertEquals("abc", textValue); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java index 46ae96ae..a8ab595b 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleDataSetTest.java @@ -25,7 +25,9 @@ import com.jd.blockchain.ledger.core.CryptoConfig; import com.jd.blockchain.ledger.core.MerkleDataSet; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; +import com.jd.blockchain.utils.Dataset; +import com.jd.blockchain.utils.DatasetHelper; import com.jd.blockchain.utils.io.BytesUtils; public class MerkleDataSetTest { @@ -53,9 +55,9 @@ public class MerkleDataSetTest { MemoryKVStorage storage = new MemoryKVStorage(); MerkleDataSet mds = new MerkleDataSet(cryptoConfig, keyPrefix, storage, storage); - mds.setValue("A", "A".getBytes(), -1); - mds.setValue("B", "B".getBytes(), -1); - mds.setValue("C", "C".getBytes(), -1); + mds.setValue(Bytes.fromString("A"), "A".getBytes(), -1); + mds.setValue(Bytes.fromString("B"), "B".getBytes(), -1); + mds.setValue(Bytes.fromString("C"), "C".getBytes(), -1); mds.commit(); @@ -85,22 +87,23 @@ public class MerkleDataSetTest { MemoryKVStorage storage = new MemoryKVStorage(); MerkleDataSet mds = new MerkleDataSet(cryptoConfig, keyPrefix, storage, storage); - mds.setValue("A", "A".getBytes(), -1); - mds.setValue("B", "B".getBytes(), -1); - mds.setValue("C", "C".getBytes(), -1); + Dataset ds = DatasetHelper.map(mds); + ds.setValue("A", "A".getBytes(), -1); + ds.setValue("B", "B".getBytes(), -1); + ds.setValue("C", "C".getBytes(), -1); mds.commit(); - byte[] va = mds.getValue("A"); + byte[] va = ds.getValue("A"); assertNotNull(va); assertEquals("A", new String(va)); - byte[] vc = mds.getValue("C"); - VersioningKVEntry ventry = mds.getDataEntry("C"); + byte[] vc = ds.getValue("C"); + DataEntry ventry = ds.getDataEntry("C"); assertNotNull(vc); assertNotNull(ventry); assertEquals("C", new String(vc)); - assertEquals("C", ventry.getKey().toUTF8String()); + assertEquals("C", ventry.getKey()); HashDigest root1 = mds.getRootHash(); @@ -111,8 +114,8 @@ public class MerkleDataSetTest { int expStorageCount = 10; assertEquals(expStorageCount, storage.getStorageCount()); - mds.setValue("B", "B".getBytes(), 0); - mds.setValue("C", "C".getBytes(), 0); + ds.setValue("B", "B".getBytes(), 0); + ds.setValue("C", "C".getBytes(), 0); mds.commit(); HashDigest root2 = mds.getRootHash(); assertNotEquals(root1, root2); @@ -122,7 +125,7 @@ public class MerkleDataSetTest { expStorageCount = expStorageCount + 3; assertEquals(expStorageCount, storage.getStorageCount()); - mds.setValue("D", "DValue".getBytes(), -1); + ds.setValue("D", "DValue".getBytes(), -1); mds.commit(); HashDigest root3 = mds.getRootHash(); assertNotEquals(root2, root3); @@ -135,31 +138,31 @@ public class MerkleDataSetTest { assertEquals(expStorageCount, storage.getStorageCount()); // Check rollback function: Add some keys, and then rollback; - long v = mds.setValue("E", "E-values".getBytes(), -1); + long v = ds.setValue("E", "E-values".getBytes(), -1); assertEquals(v, 0); - String expEValue = new String(mds.getValue("E")); + String expEValue = new String(ds.getValue("E")); assertEquals(expEValue, "E-values"); - v = mds.setValue("F", "F-values".getBytes(), -1); + v = ds.setValue("F", "F-values".getBytes(), -1); assertEquals(v, 0); - String expFValue = new String(mds.getValue("F")); + String expFValue = new String(ds.getValue("F")); assertEquals(expFValue, "F-values"); - v = mds.setValue("E", "E-values-1".getBytes(), 0); + v = ds.setValue("E", "E-values-1".getBytes(), 0); assertEquals(v, 1); - expEValue = new String(mds.getValue("E")); + expEValue = new String(ds.getValue("E")); assertEquals(expEValue, "E-values-1"); mds.cancel(); - byte[] bv = mds.getValue("E"); + byte[] bv = ds.getValue("E"); assertNull(bv); - bv = mds.getValue("F"); + bv = ds.getValue("F"); assertNull(bv); - v = mds.getVersion("E"); + v = ds.getVersion("E"); assertEquals(-1, v); - v = mds.getVersion("F"); + v = ds.getVersion("F"); assertEquals(-1, v); // Expect that states has been recover; @@ -194,10 +197,11 @@ public class MerkleDataSetTest { MemoryKVStorage storage = new MemoryKVStorage(); MerkleDataSet mds = new MerkleDataSet(cryptoConfig, keyPrefix, storage, storage); + Dataset ds = DatasetHelper.map(mds); // 初始的时候没有任何数据,总是返回 null; - VersioningKVEntry verKVEntry = mds.getDataEntry("NULL_KEY"); - byte[] vbytes = mds.getValue("NULL_KEY"); + DataEntry verKVEntry = ds.getDataEntry("NULL_KEY"); + byte[] vbytes = ds.getValue("NULL_KEY"); assertNull(verKVEntry); assertNull(vbytes); @@ -217,7 +221,7 @@ public class MerkleDataSetTest { for (int i = 0; i < count; i++) { key = "data" + i; rand.nextBytes(data); - v = mds.setValue(key, data, -1); + v = ds.setValue(key, data, -1); dataVersions.put(key, v); dataValues.put(key + "_" + v, data); assertEquals(v, 0); @@ -237,7 +241,7 @@ public class MerkleDataSetTest { KeySnapshot ks = new KeySnapshot(); ks.proof = proof; - ks.maxVersion = mds.getVersion(key); + ks.maxVersion = ds.getVersion(key); snapshot.put(key, ks); } @@ -271,7 +275,7 @@ public class MerkleDataSetTest { key = "data" + i; rand.nextBytes(data); expVer = dataVersions.get(key); - v = mds.setValue(key, data, expVer); + v = ds.setValue(key, data, expVer); assertEquals(v, expVer + 1); @@ -300,7 +304,7 @@ public class MerkleDataSetTest { KeySnapshot ks = new KeySnapshot(); ks.proof = proof; - ks.maxVersion = mds.getVersion(key); + ks.maxVersion = ds.getVersion(key); snapshot.put(key, ks); } history.put(rootHash, snapshot); @@ -316,6 +320,7 @@ public class MerkleDataSetTest { MerkleDataSet mdsReload = new MerkleDataSet(hisRootHash, cryptoConfig, keyPrefix, storage, storage, true); + Dataset dsReload = DatasetHelper.map(mdsReload); assertEquals(hisRootHash, mdsReload.getRootHash()); // verify every keys; @@ -323,7 +328,7 @@ public class MerkleDataSetTest { key = "data" + i; // 最新版本一致; long expLatestVersion = snapshot.get(key).maxVersion; - long actualLatestVersion = mdsReload.getVersion(key); + long actualLatestVersion = dsReload.getVersion(key); assertEquals(expLatestVersion, actualLatestVersion); // 数据证明一致; @@ -339,7 +344,7 @@ public class MerkleDataSetTest { for (long j = 0; j < actualLatestVersion; j++) { String keyver = key + "_" + j; byte[] expValue = dataValues.get(keyver); - byte[] actualValue = mdsReload.getValue(key, j); + byte[] actualValue = dsReload.getValue(key, j); assertTrue(BytesUtils.equals(expValue, actualValue)); } } @@ -365,10 +370,11 @@ public class MerkleDataSetTest { MemoryKVStorage storage = new MemoryKVStorage(); MerkleDataSet mds = new MerkleDataSet(cryptoConfig, keyPrefix, storage, storage); + Dataset ds = DatasetHelper.map(mds); // 初始的时候没有任何数据,总是返回 null; - VersioningKVEntry verKVEntry = mds.getDataEntry("NULL_KEY"); - byte[] vbytes = mds.getValue("NULL_KEY"); + DataEntry verKVEntry = ds.getDataEntry("NULL_KEY"); + byte[] vbytes = ds.getValue("NULL_KEY"); assertNull(verKVEntry); assertNull(vbytes); @@ -388,7 +394,7 @@ public class MerkleDataSetTest { MerkleProof proof; for (int i = 0; i < count; i++) { key = "data" + i; - v = mds.setValue(key, data, -1); + v = ds.setValue(key, data, -1); dataVersions.put(key, v); // dataValues.put(key + "_" + v, data); assertEquals(v, 0); @@ -408,7 +414,7 @@ public class MerkleDataSetTest { KeySnapshot ks = new KeySnapshot(); ks.proof = proof; - ks.maxVersion = mds.getVersion(key); + ks.maxVersion = ds.getVersion(key); snapshot.put(key, ks); } @@ -418,6 +424,7 @@ public class MerkleDataSetTest { // verify; { MerkleDataSet mdsReload = new MerkleDataSet(rootHash, cryptoConfig, keyPrefix, storage, storage, true); + Dataset dsReload = DatasetHelper.map(mdsReload); // verify every keys; Map snapshot = history.get(rootHash); MerkleProof expProof; @@ -429,7 +436,7 @@ public class MerkleDataSetTest { expProof = snapshot.get(key).proof; assertEquals(expProof.toString(), proof.toString()); - byte[] value = mdsReload.getValue(key); + byte[] value = dsReload.getValue(key); assertTrue(BytesUtils.equals(data, value)); } } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java index ff4d160f..e1442bc3 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java @@ -332,13 +332,13 @@ public class TransactionBatchProcessorTest { newBlock = newBlockEditor.prepare(); newBlockEditor.commit(); - BytesValue v1_0 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K1", + BytesValue v1_0 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K1", 0); - BytesValue v1_1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K1", + BytesValue v1_1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K1", 1); - BytesValue v2 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K2", + BytesValue v2 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K2", 0); - BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K3", + BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K3", 0); assertNotNull(v1_0); @@ -376,16 +376,16 @@ public class TransactionBatchProcessorTest { newBlock = newBlockEditor.prepare(); newBlockEditor.commit(); - BytesValue v1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K1"); - v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getValue("K3"); + BytesValue v1 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K1"); + v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K3"); // k1 的版本仍然为1,没有更新; long k1_version = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()) - .getDataVersion("K1"); + .getDataset().getVersion("K1"); assertEquals(1, k1_version); long k3_version = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()) - .getDataVersion("K3"); + .getDataset().getVersion("K3"); assertEquals(1, k3_version); assertNotNull(v1); diff --git a/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java b/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java index da809c0a..000bb20e 100644 --- a/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java +++ b/source/storage/storage-redis/src/main/java/com/jd/blockchain/storage/service/impl/redis/RedisVerioningStorage.java @@ -2,7 +2,7 @@ package com.jd.blockchain.storage.service.impl.redis; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; @@ -45,7 +45,7 @@ public class RedisVerioningStorage implements VersioningKVStorage { } @Override - public VersioningKVEntry getEntry(Bytes key, long version) { + public DataEntry getEntry(Bytes key, long version) { byte[] value = get(key, version); if (value == null) { return null; @@ -101,7 +101,7 @@ public class RedisVerioningStorage implements VersioningKVStorage { } - private static class VersioningKVData implements VersioningKVEntry{ + private static class VersioningKVData implements DataEntry{ private Bytes key; diff --git a/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java b/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java index 40dba131..98c47325 100644 --- a/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java +++ b/source/storage/storage-rocksdb/src/main/java/com/jd/blockchain/storage/service/impl/rocksdb/RocksDBVersioningStorage.java @@ -9,7 +9,7 @@ import org.rocksdb.*; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; import com.jd.blockchain.utils.io.BytesUtils; /** @@ -127,7 +127,7 @@ public class RocksDBVersioningStorage implements VersioningKVStorage { } @Override - public VersioningKVEntry getEntry(Bytes key, long version) { + public DataEntry getEntry(Bytes key, long version) { byte[] value = get(key, version); if (value == null) { return null; @@ -226,7 +226,7 @@ public class RocksDBVersioningStorage implements VersioningKVStorage { } } - private static class VersioningKVData implements VersioningKVEntry { + private static class VersioningKVData implements DataEntry { private Bytes key; diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java index dfa26404..980cc32c 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/VersioningKVStorage.java @@ -1,7 +1,7 @@ package com.jd.blockchain.storage.service; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; /** * Versioning Key-Value Storage @@ -41,7 +41,7 @@ public interface VersioningKVStorage extends BatchStorageService { * @param version * @return */ - VersioningKVEntry getEntry(Bytes key, long version); + DataEntry getEntry(Bytes key, long version); /** * Return the specified verson's value;
diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java index 8f334ca3..b038a87e 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/BufferedKVStorage.java @@ -10,7 +10,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; /** * {@link BufferedKVStorage} 缓冲写入的KV存储;
@@ -79,7 +79,7 @@ public class BufferedKVStorage implements VersioningKVStorage, ExPolicyKVStorage } @Override - public VersioningKVEntry getEntry(Bytes key, long version) { + public DataEntry getEntry(Bytes key, long version) { VersioningWritingSet ws = versioningCache.get(key); if (ws == null) { return origVersioningStorage.getEntry(key, version); @@ -484,7 +484,7 @@ public class BufferedKVStorage implements VersioningKVStorage, ExPolicyKVStorage return startingVersion; } - public VersioningKVEntry getEntry(long version) { + public DataEntry getEntry(long version) { byte[] value = get(version); if (value == null) { return null; @@ -505,7 +505,7 @@ public class BufferedKVStorage implements VersioningKVStorage, ExPolicyKVStorage } } - private static class VersioningKVData implements VersioningKVEntry { + private static class VersioningKVData implements DataEntry { private Bytes key; diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java index 8bce7e32..a0f36c0d 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java @@ -7,7 +7,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.KVStorageService; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; import com.jd.blockchain.utils.io.BytesMap; public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, KVStorageService, BytesMap { @@ -21,7 +21,7 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, } @Override - public VersioningKVEntry getEntry(Bytes key, long version) { + public DataEntry getEntry(Bytes key, long version) { return verStorage.getEntry(key, version); } diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java index 4d1e1509..73816055 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java @@ -1,8 +1,8 @@ package com.jd.blockchain.storage.service.utils; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; -public class VersioningKVData implements VersioningKVEntry { +public class VersioningKVData implements DataEntry { private K key; diff --git a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java index e9aee04b..1c6b8def 100644 --- a/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java @@ -7,7 +7,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.VersioningKVEntry; +import com.jd.blockchain.utils.DataEntry; import com.jd.blockchain.utils.io.BytesMap; public class VersioningKVStorageMap implements VersioningKVStorage, BytesMap { @@ -42,7 +42,7 @@ public class VersioningKVStorageMap implements VersioningKVStorage, BytesMap { + + public K getKey(); + + public long getVersion(); + + public V getValue(); + +} \ No newline at end of file diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningMap.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java similarity index 95% rename from source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningMap.java rename to source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java index 84d198a9..33ad1f7c 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningMap.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java @@ -1,8 +1,8 @@ package com.jd.blockchain.utils; -public interface VersioningMap { +public interface Dataset { -// long getDataCount(); + long getDataCount(); // /** // * Create or update the value associated the specified key if the version @@ -109,8 +109,8 @@ public interface VersioningMap { * @param key * @return Null if the key doesn't exist! */ - VersioningKVEntry getDataEntry(K key); + DataEntry getDataEntry(K key); - VersioningKVEntry getDataEntry(K key, long version); + DataEntry getDataEntry(K key, long version); } \ No newline at end of file diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java new file mode 100644 index 00000000..de96f665 --- /dev/null +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java @@ -0,0 +1,301 @@ +package com.jd.blockchain.utils; + +public class DatasetHelper { + + + + public static final TypeMapper UTF8_STRING_BYTES_MAPPER = new TypeMapper() { + + @Override + public Bytes encode(String t2) { + return Bytes.fromString(t2); + } + + @Override + public String decode(Bytes t1) { + return t1.toUTF8String(); + } + }; + + public static final TypeMapper BYTES_UTF8_STRING_MAPPER = new TypeMapper() { + + @Override + public String encode(Bytes t1) { + return t1.toUTF8String(); + } + + @Override + public Bytes decode(String t2) { + return Bytes.fromString(t2); + } + }; + + /** + * 适配两个不同类型参数的数据集; + * + * @param 适配输入的 键 类型; + * @param 适配输出的 键 类型; + * @param 适配输入的 值 类型; + * @param 适配输出的 值 类型; + * @param dataset 数据集; + * @param keyMapper 键的映射配置; + * @param valueMapper 值的映射配置; + * @return + */ + public static Dataset map(Dataset dataset) { + return new TypeAdapter(dataset, UTF8_STRING_BYTES_MAPPER, new EmptyMapper()); + } + + /** + * 适配两个不同类型参数的数据集; + * + * @param 适配输入的 键 类型; + * @param 适配输出的 键 类型; + * @param 适配输入的 值 类型; + * @param 适配输出的 值 类型; + * @param dataset 数据集; + * @param keyMapper 键的映射配置; + * @param valueMapper 值的映射配置; + * @return + */ + public static Dataset map(Dataset dataset, TypeMapper valueMapper) { + return new TypeAdapter(dataset, UTF8_STRING_BYTES_MAPPER, valueMapper); + } + + /** + * 适配两个不同类型参数的数据集; + * + * @param 适配输入的 键 类型; + * @param 适配输出的 键 类型; + * @param 适配输入的 值 类型; + * @param 适配输出的 值 类型; + * @param dataset 数据集; + * @param keyMapper 键的映射配置; + * @param valueMapper 值的映射配置; + * @return + */ + public static Dataset map(Dataset dataset, TypeMapper keyMapper, + TypeMapper valueMapper) { + return new TypeAdapter(dataset, keyMapper, valueMapper); + } + + /** + * 监听对数据集的变更; + * + * @param 键 类型; + * @param 值 类型; + * @param dataset 要监听的数据集; + * @param listener 要植入的监听器; + * @return 植入监听器的数据集实例; + */ + public static Dataset listen(Dataset dataset, DataChangedListener listener) { + return new DatasetUpdatingMonitor(dataset, listener); + } + + /** + * 数据修改监听器; + * + * @author huanghaiquan + * + * @param + * @param + */ + public static interface DataChangedListener { + + void onChanged(K key, V value, long expectedVersion, long newVersion); + + } + + /** + * 类型映射接口; + * + * @author huanghaiquan + * + * @param + * @param + */ + public static interface TypeMapper { + + T1 encode(T2 t2); + + T2 decode(T1 t1); + + } + + private static class EmptyMapper implements TypeMapper{ + + @Override + public T encode(T t) { + return t; + } + + @Override + public T decode(T t) { + return t; + } + + } + + private static class DatasetUpdatingMonitor implements Dataset { + + private Dataset dataset; + + private DataChangedListener listener; + + public DatasetUpdatingMonitor(Dataset dataset, DataChangedListener listener) { + this.dataset = dataset; + this.listener = listener; + } + + @Override + public long getDataCount() { + return dataset.getDataCount(); + } + + @Override + public long setValue(K key, V value, long version) { + long newVersion = dataset.setValue(key, value, version); + if (newVersion > -1) { + listener.onChanged(key, value, version, newVersion); + } + return newVersion; + } + + @Override + public V getValue(K key, long version) { + return dataset.getValue(key, version); + } + + @Override + public V getValue(K key) { + return dataset.getValue(key); + } + + @Override + public long getVersion(K key) { + return dataset.getVersion(key); + } + + @Override + public DataEntry getDataEntry(K key) { + return dataset.getDataEntry(key); + } + + @Override + public DataEntry getDataEntry(K key, long version) { + return dataset.getDataEntry(key, version); + } + + } + + /** + * 类型适配器; + * + * @author huanghaiquan + * + * @param + * @param + * @param + * @param + */ + private static class TypeAdapter implements Dataset { + private Dataset dataset; + private TypeMapper keyMapper; + private TypeMapper valueMapper; + + public TypeAdapter(Dataset dataset, TypeMapper keyMapper, TypeMapper valueMapper) { + this.dataset = dataset; + this.keyMapper = keyMapper; + this.valueMapper = valueMapper; + } + + @Override + public long getDataCount() { + return dataset.getDataCount(); + } + + @Override + public long setValue(K2 key, V2 value, long version) { + K1 key1 = keyMapper.encode(key); + V1 value1 = valueMapper.encode(value); + return dataset.setValue(key1, value1, version); + } + + @Override + public V2 getValue(K2 key, long version) { + K1 k = keyMapper.encode(key); + V1 v = dataset.getValue(k, version); + if (v == null) { + return null; + } + return valueMapper.decode(v); + } + + @Override + public V2 getValue(K2 key) { + K1 k = keyMapper.encode(key); + V1 v = dataset.getValue(k); + if (v == null) { + return null; + } + return valueMapper.decode(v); + } + + @Override + public long getVersion(K2 key) { + K1 k = keyMapper.encode(key); + return dataset.getVersion(k); + } + + @Override + public DataEntry getDataEntry(K2 key) { + K1 k = keyMapper.encode(key); + DataEntry entry = dataset.getDataEntry(k); + if (entry == null) { + return null; + } + V2 v = valueMapper.decode(entry.getValue()); + return new KeyValueEntry(key, v, entry.getVersion()); + } + + @Override + public DataEntry getDataEntry(K2 key, long version) { + K1 k = keyMapper.encode(key); + DataEntry entry = dataset.getDataEntry(k, version); + if (entry == null) { + return null; + } + V2 v = valueMapper.decode(entry.getValue()); + return new KeyValueEntry(key, v, entry.getVersion()); + } + + } + + private static class KeyValueEntry implements DataEntry { + + private K key; + + private V value; + + private long version; + + public KeyValueEntry(K key, V value, long version) { + this.key = key; + this.value = value; + this.version = version; + } + + public K getKey() { + return key; + } + + public long getVersion() { + return version; + } + + public V getValue() { + return value; + } + + } +} diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java deleted file mode 100644 index 20b3da6f..00000000 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/RegionMap.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.jd.blockchain.utils; - -public abstract class RegionMap implements VersioningMap { - - private K region; - - private VersioningMap dataMap; - - public RegionMap(K region, VersioningMap dataMap) { - this.region = region; - this.dataMap = dataMap; - } - - @Override - public long setValue(K key, V value, long version) { - K dataKey = concatKey(region, key); - return dataMap.setValue(dataKey, value, version); - } - - @Override - public V getValue(K key, long version) { - K dataKey = concatKey(region, key); - return dataMap.getValue(dataKey, version); - } - - @Override - public V getValue(K key) { - K dataKey = concatKey(region, key); - return dataMap.getValue(dataKey); - } - - @Override - public long getVersion(K key) { - K dataKey = concatKey(region, key); - return dataMap.getVersion(dataKey); - } - - @Override - public VersioningKVEntry getDataEntry(K key) { - K dataKey = concatKey(region, key); - VersioningKVEntry entry = dataMap.getDataEntry(dataKey); - return new KVEntryWrapper(key, entry); - } - - @Override - public VersioningKVEntry getDataEntry(K key, long version) { - K dataKey = concatKey(region, key); - VersioningKVEntry entry = dataMap.getDataEntry(dataKey, version); - return new KVEntryWrapper(key, entry); - } - - /** - * 以指定的前缀组成新的key; - * - * @param prefix - * @param key - * @return - */ - protected abstract K concatKey(K prefix, K key); - - public static VersioningMap newRegion(Bytes region, VersioningMap dataMap) { - return new BytesKeyRegionMap(region, dataMap); - } - - public static VersioningMap newRegion(String region, VersioningMap dataMap) { - return new StringKeyRegionMap(region, dataMap); - } - - private static class BytesKeyRegionMap extends RegionMap { - - public BytesKeyRegionMap(Bytes region, VersioningMap dataMap) { - super(region, dataMap); - } - - @Override - protected Bytes concatKey(Bytes prefix, Bytes key) { - return prefix.concat(key); - } - - } - - private static class StringKeyRegionMap extends RegionMap { - - public StringKeyRegionMap(String region, VersioningMap dataMap) { - super(region, dataMap); - } - - @Override - protected String concatKey(String prefix, String key) { - return prefix + key; - } - - } - - private static class KVEntryWrapper implements VersioningKVEntry { - - private K key; - - private VersioningKVEntry entry; - - public KVEntryWrapper(K key, VersioningKVEntry entry) { - this.key = key; - this.entry = entry; - } - - @Override - public K getKey() { - return key; - } - - @Override - public long getVersion() { - return entry.getVersion(); - } - - @Override - public V getValue() { - return entry.getValue(); - } - - } -} diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java deleted file mode 100644 index b92eda41..00000000 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/VersioningKVEntry.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.jd.blockchain.utils; - -/** - * 版本化的键值数据项; - * - * @author huanghaiquan - * - */ -public interface VersioningKVEntry{ - - K getKey(); - - long getVersion(); - - V getValue(); - -} \ No newline at end of file From ae9d4aaa7b3904d42d9bc9814df0acc81903cb34 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Thu, 24 Oct 2019 11:34:49 +0800 Subject: [PATCH 6/9] Refactored MerkleAccount; --- .../ledger/core/ContractAccount.java | 4 +- .../ledger/core/LedgerQueryService.java | 5 +- .../blockchain/ledger/core/MerkleAccount.java | 103 +++++++----------- .../ledger/core/MerkleAccountSet.java | 25 +++-- .../blockchain/ledger/core/UserAccount.java | 6 +- .../ledger/core/ContractInvokingTest.java | 16 +-- .../ledger/core/LedgerEditorTest.java | 2 +- .../core/TransactionBatchProcessorTest.java | 12 +- .../ledger/core/TransactionSetTest.java | 4 +- .../com/jd/blockchain/ledger/BytesValue.java | 2 +- .../jd/blockchain/ledger/KVDataObject.java | 28 ++--- .../com/jd/blockchain/ledger/TypedValue.java | 6 +- .../resolver/AbstractBytesValueResolver.java | 2 +- .../ledger/BytesToBytesValueResolverTest.java | 2 +- .../ledger/BytesValueEncodingTest.java | 4 +- .../DataAccountKVSetOpTemplateTest.java | 2 +- .../IntegerToBytesValueResolverTest.java | 6 +- .../com/jd/blockchain/ledger/KVDataTest.java | 2 +- .../ledger/LongToBytesValueResolverTest.java | 6 +- .../ledger/ShortToBytesValueResolverTest.java | 2 +- .../StringToBytesValueResolverTest.java | 4 +- .../blockchain/ledger/TxContentBlobTest.java | 8 +- .../peer/web/LedgerQueryController.java | 16 +-- .../sdk/converters/ClientResolveUtil.java | 2 +- .../intgr/IntegrationTestAll4Redis.java | 14 +-- .../java/com/jd/blockchain/utils/Dataset.java | 22 ---- 26 files changed, 136 insertions(+), 169 deletions(-) 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 b0f8104d..0d288d7b 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 @@ -40,11 +40,11 @@ public class ContractAccount extends AccountDecorator implements ContractInfo { } public byte[] getChainCode() { - return getHeaders().getValue(CHAIN_CODE_KEY).getValue().toBytes(); + return getHeaders().getValue(CHAIN_CODE_KEY).getBytes().toBytes(); } public byte[] getChainCode(long version) { - return getHeaders().getValue(CHAIN_CODE_KEY, version).getValue().toBytes(); + return getHeaders().getValue(CHAIN_CODE_KEY, version).getBytes().toBytes(); } public long getChaincodeVersion() { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java index b965f842..2c9e92de 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java @@ -5,7 +5,6 @@ import java.util.List; import com.jd.blockchain.contract.ContractException; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.AccountHeader; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.ContractInfo; @@ -293,12 +292,12 @@ public class LedgerQueryService implements BlockchainQueryService { for (int i = 0; i < entries.length; i++) { final String currKey = keys[i]; - ver = dataAccount == null ? -1 : dataAccount.getDataset().getVersion(Bytes.fromString(currKey)); + ver = dataAccount == null ? -1 : dataAccount.getDataset().getVersion(currKey); if (ver < 0) { entries[i] = new KVDataObject(currKey, -1, null); } else { - BytesValue value = dataAccount.getDataset().getValue(Bytes.fromString(currKey), ver); + BytesValue value = dataAccount.getDataset().getValue(currKey, ver); entries[i] = new KVDataObject(currKey, ver, value); } } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java index 384b39bd..6b59dacc 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java @@ -49,68 +49,60 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho private Dataset typedData; - private long version; +// private long version; /** - * Create a new Account with the specified address and pubkey;
+ * Create a new Account with the specified identity(address and pubkey);
* * At the same time, a empty merkle dataset is also created for this account, * which is used for storing data of this account.
+ * + * This new account will be writable.
* - * Note that, the blockchain identity of the account is not stored in the - * account's merkle dataset, but is stored by the outer invoker; - * - * @param accountID 身份; - * @param cryptoSetting 密码参数; - * @param keyPrefix 数据前缀; - * @param exStorage - * @param verStorage + * @param accountID Identity of this new account; + * @param cryptoSetting Settings about crypto operations; + * @param keyPrefix Prefix of all keys in this account's dataset; + * @param exStorage The base storage for existance operation; + * @param verStorage The base storage for versioning operation; */ public MerkleAccount(BlockchainIdentity accountID, CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { - this(accountID.getAddress(), accountID.getPubKey(), -1, null, cryptoSetting, keyPrefix, exStorage, verStorage, - false); + // 初始化数据集; + initializeDatasets(null, cryptoSetting, keyPrefix, exStorage, verStorage, false); initPubKey(accountID.getPubKey()); + this.accountID = accountID; } /** - * Create a account instance with the specified address and pubkey and load it's + * Create a account instance with the specified address and root hash; load it's * merkle dataset from the specified root hash. This merkle dateset is used for * storing data of this account.
* - * @param accountID identity of this account; - * @param version - * @param dataRootHash merkle root hash of account's data; if set to a null - * value, an empty merkle dataset is created; - * @param cryptoSetting - * @param keyPrefix - * @param exStorage - * @param verStorage - * @param readonly + * @param address Address of this account; + * @param rootHash Merkle root hash of this account; It can not be null; + * @param cryptoSetting Settings about crypto operations; + * @param keyPrefix Prefix of all keys in this account's dataset; + * @param exStorage The base storage for existance operation; + * @param verStorage The base storage for versioning operation; + * @param readonly Readonly about this account's dataset; */ - public MerkleAccount(Bytes address, long version, HashDigest dataRootHash, CryptoSetting cryptoSetting, - Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { - this(address, null, version, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); - } + public MerkleAccount(Bytes address, HashDigest rootHash, CryptoSetting cryptoSetting, Bytes keyPrefix, + ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { + if (rootHash == null) { + throw new IllegalArgumentException("Specified a null root hash for account[" + address.toBase58() + "]!"); + } - /** - * 内部构造器; - * - * @param address 账户地址; - * @param pubKey 账户公钥; 如果为空,则会进行加载验证; - * @param version 账户版本; - * @param rootHash 账户根哈希; - * @param cryptoSetting 密码参数设置; - * @param keyPrefix 当前账户的 Key 前缀; - * @param exStorage 单键存储服务; - * @param verStorage 多版本存储服务; - * @param readonly 是否只读; - */ - private MerkleAccount(Bytes address, PubKey pubKey, long version, HashDigest rootHash, CryptoSetting cryptoSetting, - Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { - this.version = version; + // 初始化数据集; + initializeDatasets(rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + + // 初始化账户的身份; + PubKey pubKey = loadPubKey(); + this.accountID = new AccountID(address, pubKey); + } + private void initializeDatasets(HashDigest rootHash, CryptoSetting cryptoSetting, Bytes keyPrefix, + ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { // 加载“根数据集” this.rootDataset = new MerkleDataSet(rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); @@ -148,15 +140,6 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho Bytes dataPrefix = keyPrefix.concat(DATA_PREFIX); this.dataDataset = new MerkleDataSet(dataRoot, cryptoSetting, dataPrefix, exStorage, verStorage, readonly); this.typedData = DatasetHelper.listen(DatasetHelper.map(dataDataset, valueMapper), dataChangedListener); - - // 初始化账户的身份; - if (pubKey == null) { - if (version < 0) { - throw new IllegalArgumentException("Specified a null PubKey for newly Account!"); - } - pubKey = loadPubKey(); - } - this.accountID = new AccountID(address, pubKey); } private HashDigest loadHeaderRoot() { @@ -258,6 +241,9 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho */ private PubKey loadPubKey() { TypedValue value = typedHeader.getValue(KEY_PUBKEY); + if (value == null) { + return null; + } return value.pubKeyValue(); } @@ -276,12 +262,10 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho * * 此方法默认会返回新的账户版本号,等于当前版本号加 1 ; * - * @param newRootHash - * @param currentVersion - * @return + * @param previousRootHash 提交前的根哈希;如果是新账户的首次提交,则为 null; + * @param newRootHash 新的根哈希; */ - protected long onCommited(HashDigest newRootHash, long currentVersion) { - return currentVersion + 1; + protected void onCommited(HashDigest previousRootHash, HashDigest newRootHash) { } @Override @@ -303,8 +287,9 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho } if (rootDataset.isUpdated()) { + HashDigest previousRootHash = rootDataset.getRootHash(); rootDataset.commit(); - this.version = onCommited(rootDataset.getRootHash(), version); + onCommited(previousRootHash, rootDataset.getRootHash()); } } @@ -340,10 +325,6 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho } - public long getVersion() { - return version; - } - // private static class MerkleDatasetAdapter implements Dataset { // // private static DataChangedListener NULL_LISTENER = new DataChangedListener() { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java index 6952c89e..73696c27 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java @@ -94,7 +94,8 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ BlockchainIdentity[] ids = new BlockchainIdentity[results.length]; for (int i = 0; i < results.length; i++) { - InnerMerkleAccount account = createAccount(results[i].getKey(), new HashDigest(results[i].getValue()), results[i].getVersion(), true); + InnerMerkleAccount account = createAccount(results[i].getKey(), new HashDigest(results[i].getValue()), + results[i].getVersion(), true); ids[i] = account.getID(); } return ids; @@ -284,11 +285,11 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ return createAccount(address, rootHash, version, readonly); } - - private InnerMerkleAccount createAccount(Bytes address,HashDigest rootHash, long version, boolean readonly) { + + private InnerMerkleAccount createAccount(Bytes address, HashDigest rootHash, long version, boolean readonly) { // prefix; Bytes prefix = keyPrefix.concat(address); - + return new InnerMerkleAccount(address, version, rootHash, cryptoSetting, prefix, baseExStorage, baseVerStorage, readonly); } @@ -358,14 +359,18 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ */ private class InnerMerkleAccount extends MerkleAccount { + private long version; + public InnerMerkleAccount(BlockchainIdentity accountID, CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { super(accountID, cryptoSetting, keyPrefix, exStorage, verStorage); + this.version = -1; } public InnerMerkleAccount(Bytes address, long version, HashDigest dataRootHash, CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { - super(address, version, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + super(address, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); + this.version = version; } @Override @@ -374,13 +379,17 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ } @Override - protected long onCommited(HashDigest newRootHash, long currentVersion) { - long newVersion = merkleDataset.setValue(this.getAddress(), newRootHash.toBytes(), currentVersion); + protected void onCommited(HashDigest previousRootHash, HashDigest newRootHash) { + long newVersion = merkleDataset.setValue(this.getAddress(), newRootHash.toBytes(), version); if (newVersion < 0) { // Update fail; throw new LedgerException("Account updating fail! --[Address=" + this.getAddress() + "]"); } - return newVersion; + this.version = newVersion; + } + + public long getVersion() { + return version; } } 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 df3231c4..1ac4b4fe 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 @@ -43,7 +43,7 @@ public class UserAccount extends AccountDecorator implements UserInfo { // imple if (pkBytes == null) { return null; } - dataPubKey = new PubKey(pkBytes.getValue().toBytes()); + dataPubKey = new PubKey(pkBytes.getBytes().toBytes()); } return dataPubKey; } @@ -69,12 +69,12 @@ public class UserAccount extends AccountDecorator implements UserInfo { // imple public String getProperty(String key) { BytesValue value = getHeaders().getValue(encodePropertyKey(key)); - return value == null ? null : value.getValue().toUTF8String(); + return value == null ? null : value.getBytes().toUTF8String(); } public String getProperty(String key, long version) { BytesValue value = getHeaders().getValue(encodePropertyKey(key), version); - return value == null ? null : value.getValue().toUTF8String(); + return value == null ? null : value.getBytes().toUTF8String(); } private String encodePropertyKey(String key) { diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java index 4af4c707..14e29d65 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java @@ -27,7 +27,6 @@ import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.DataAccountRegisterOperation; import com.jd.blockchain.ledger.EndpointRequest; -import com.jd.blockchain.ledger.KVDataEntry; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInitSetting; import com.jd.blockchain.ledger.LedgerPermission; @@ -65,6 +64,7 @@ import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.transaction.BooleanValueHolder; import com.jd.blockchain.transaction.TxBuilder; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.DataEntry; import com.jd.blockchain.utils.io.BytesUtils; import test.com.jd.blockchain.ledger.TxTestContract; @@ -243,7 +243,7 @@ public class ContractInvokingTest { BytesValue latestValue = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getValue(key, -1); - System.out.printf("latest value=[%s] %s \r\n", latestValue.getType(), latestValue.getValue().toUTF8String()); + System.out.printf("latest value=[%s] %s \r\n", latestValue.getType(), latestValue.getBytes().toUTF8String()); boolean readable = readableHolder.get(); assertTrue(readable); @@ -301,9 +301,9 @@ public class ContractInvokingTest { } }); // 预期数据都能够正常写入; - KVDataEntry kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", + DataEntry kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", 0); - KVDataEntry kv2 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataEntry("K2", + DataEntry kv2 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K2", 0); assertEquals(0, kv1.getVersion()); assertEquals(0, kv2.getVersion()); @@ -322,8 +322,8 @@ public class ContractInvokingTest { } }); // 预期数据都能够正常写入; - kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataEntry("K1", 1); - kv2 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataEntry("K2", 1); + kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", 1); + kv2 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K2", 1); assertEquals(1, kv1.getVersion()); assertEquals(1, kv2.getVersion()); assertEquals("V1-1", kv1.getValue()); @@ -341,10 +341,10 @@ public class ContractInvokingTest { } }); // 预期数据都能够正常写入; - kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataEntry("K1", 1); + kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", 1); assertEquals(1, kv1.getVersion()); assertEquals("V1-1", kv1.getValue()); - kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataEntry("K1", 2); + kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", 2); assertEquals(-1, kv1.getVersion()); assertEquals(null, kv1.getValue()); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java index 0bd470a7..78f04762 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerEditorTest.java @@ -109,7 +109,7 @@ public class LedgerEditorTest { // 验证数据读写的一致性; BytesValue bytes = dataAccount.getDataset().getValue("A"); assertEquals(DataType.TEXT, bytes.getType()); - String textValue = bytes.getValue().toUTF8String(); + String textValue = bytes.getBytes().toUTF8String(); assertEquals("abc", textValue); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java index e1442bc3..a9f09845 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java @@ -346,10 +346,10 @@ public class TransactionBatchProcessorTest { assertNotNull(v2); assertNotNull(v3); - assertEquals("V-1-1", v1_0.getValue().toUTF8String()); - assertEquals("V-1-2", v1_1.getValue().toUTF8String()); - assertEquals("V-2-1", v2.getValue().toUTF8String()); - assertEquals("V-3-1", v3.getValue().toUTF8String()); + assertEquals("V-1-1", v1_0.getBytes().toUTF8String()); + assertEquals("V-1-2", v1_1.getBytes().toUTF8String()); + assertEquals("V-2-1", v2.getBytes().toUTF8String()); + assertEquals("V-3-1", v3.getBytes().toUTF8String()); // 提交多笔数据写入的交易,包含存在数据版本冲突的交易,验证交易是否正确回滚; // 先写一笔正确的交易; k3 的版本将变为 1 ; @@ -390,8 +390,8 @@ public class TransactionBatchProcessorTest { assertNotNull(v1); assertNotNull(v3); - assertEquals("V-1-2", v1.getValue().toUTF8String()); - assertEquals("V-3-2", v3.getValue().toUTF8String()); + assertEquals("V-1-2", v1.getBytes().toUTF8String()); + assertEquals("V-3-2", v3.getBytes().toUTF8String()); // // 验证正确性; // ledgerManager = new LedgerManager(); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionSetTest.java index cd5ebc9f..63ee3e64 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionSetTest.java @@ -164,8 +164,8 @@ public class TransactionSetTest { for (int i = 0; i < acutualKVWriteSet.length; i++) { assertEquals(expKVWriteSet[i].getKey(), acutualKVWriteSet[i].getKey()); assertEquals(expKVWriteSet[i].getExpectedVersion(), acutualKVWriteSet[i].getExpectedVersion()); - assertTrue(BytesUtils.equals(expKVWriteSet[i].getValue().getValue().toBytes(), - acutualKVWriteSet[i].getValue().getValue().toBytes())); + assertTrue(BytesUtils.equals(expKVWriteSet[i].getValue().getBytes().toBytes(), + acutualKVWriteSet[i].getValue().getBytes().toBytes())); } ContractCodeDeployOperation actualContractDplOp = (ContractCodeDeployOperation) actualOperations[3]; 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 6e7b9b46..47d4ad16 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 @@ -29,6 +29,6 @@ public interface BytesValue { * @return */ @DataField(order = 1, primitiveType = PrimitiveType.BYTES) - Bytes getValue(); + Bytes getBytes(); } 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 1e8247ee..a19d9fff 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 @@ -72,15 +72,15 @@ public class KVDataObject implements KVDataEntry { case NIL: return null; case TEXT: - return bytesValue.getValue().toUTF8String(); + return bytesValue.getBytes().toUTF8String(); case BYTES: - return ByteArray.toHex(bytesValue.getValue().toBytes()); + return ByteArray.toHex(bytesValue.getBytes().toBytes()); case INT64: - return BytesUtils.toLong(bytesValue.getValue().toBytes()); + return BytesUtils.toLong(bytesValue.getBytes().toBytes()); case JSON: - return bytesValue.getValue().toUTF8String(); + return bytesValue.getBytes().toUTF8String(); case XML: - return bytesValue.getValue().toUTF8String(); + return bytesValue.getBytes().toUTF8String(); default: throw new IllegalStateException("Unsupported value type[" + getType() + "] to resolve!"); @@ -106,7 +106,7 @@ public class KVDataObject implements KVDataEntry { * @return */ Bytes bytesArray() { - return bytesValue.getValue(); + return bytesValue.getBytes(); } /** @@ -122,7 +122,7 @@ public class KVDataObject implements KVDataEntry { */ public byte tinyValue() { if (DataType.INT8 == getType()) { - return bytesValue.getValue().toBytes()[0]; + return bytesValue.getBytes().toBytes()[0]; } throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT8, getType())); } @@ -140,7 +140,7 @@ public class KVDataObject implements KVDataEntry { */ public short shortValue() { if (DataType.INT16 == getType()) { - return BytesUtils.toShort(bytesValue.getValue().toBytes(), 0); + return BytesUtils.toShort(bytesValue.getBytes().toBytes(), 0); } throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT16, getType())); } @@ -158,7 +158,7 @@ public class KVDataObject implements KVDataEntry { */ public int intValue() { if (DataType.INT32 == getType()) { - return BytesUtils.toInt(bytesValue.getValue().toBytes(), 0); + return BytesUtils.toInt(bytesValue.getBytes().toBytes(), 0); } throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT32, getType())); } @@ -176,7 +176,7 @@ public class KVDataObject implements KVDataEntry { */ public long longValue() { if (DataType.INT64 == getType()) { - return BytesUtils.toLong(bytesValue.getValue().toBytes(), 0); + return BytesUtils.toLong(bytesValue.getBytes().toBytes(), 0); } throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT64, getType())); @@ -195,7 +195,7 @@ public class KVDataObject implements KVDataEntry { */ public BigInteger bigIntValue() { if (DataType.BIG_INT == getType()) { - return new BigInteger(bytesValue.getValue().toBytes()); + return new BigInteger(bytesValue.getBytes().toBytes()); } throw new IllegalStateException( String.format("Expected type [%s], but [%s]", DataType.BIG_INT, getType())); @@ -214,7 +214,7 @@ public class KVDataObject implements KVDataEntry { */ public boolean boolValue() { if (DataType.BOOLEAN == getType()) { - return BytesUtils.toBoolean(bytesValue.getValue().toBytes()[0]); + return BytesUtils.toBoolean(bytesValue.getBytes().toBytes()[0]); } throw new IllegalStateException( String.format("Expected type [%s], but [%s]", DataType.BOOLEAN, getType())); @@ -233,7 +233,7 @@ public class KVDataObject implements KVDataEntry { */ public Date datetimeValue() { if (DataType.TIMESTAMP == getType()) { - long ts = BytesUtils.toLong(bytesValue.getValue().toBytes()); + long ts = BytesUtils.toLong(bytesValue.getBytes().toBytes()); return new Date(ts); } throw new IllegalStateException( @@ -255,7 +255,7 @@ public class KVDataObject implements KVDataEntry { public String stringValue() { DataType type = getType(); if (DataType.TEXT == type || DataType.JSON == type || DataType.XML == type) { - return bytesValue.getValue().toUTF8String(); + return bytesValue.getBytes().toUTF8String(); } throw new IllegalStateException(String.format("Expected type [%s] or [%s] or [%s] , but [%s]", PrimitiveType.TEXT, DataType.JSON, DataType.XML, type)); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java index 333badaa..e2c0c9d5 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java @@ -34,7 +34,7 @@ public class TypedValue implements BytesValue { private TypedValue(BytesValue bytesValue) { this.type = bytesValue.getType(); - this.value = bytesValue.getValue(); + this.value = bytesValue.getBytes(); } private TypedValue() { @@ -48,11 +48,11 @@ public class TypedValue implements BytesValue { } @Override - public Bytes getValue() { + public Bytes getBytes() { return this.value; } - public Object getTypedValue() { + public Object getValue() { if (isNil()) { return null; } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/AbstractBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/AbstractBytesValueResolver.java index 995d5522..d6ee0b98 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/AbstractBytesValueResolver.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/AbstractBytesValueResolver.java @@ -47,7 +47,7 @@ public abstract class AbstractBytesValueResolver implements BytesValueResolver { if (!isSupport(dataType)) { throw new IllegalStateException(String.format("Un-support encode DataType[%s] Object !!!", dataType.name())); } - return decode(value.getValue()); + return decode(value.getBytes()); } protected abstract Object decode(Bytes value); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesToBytesValueResolverTest.java index 3635743c..2dfa0dbd 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesToBytesValueResolverTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesToBytesValueResolverTest.java @@ -26,7 +26,7 @@ public class BytesToBytesValueResolverTest { assertEquals(bytesValue.getType(), DataType.BYTES); - assertEquals(bytesObj, bytesValue.getValue()); + assertEquals(bytesObj, bytesValue.getBytes()); Bytes resolveBytesObj = (Bytes)resolver.decode(bytesValue); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesValueEncodingTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesValueEncodingTest.java index e5b624c9..f572a831 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesValueEncodingTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/BytesValueEncodingTest.java @@ -28,9 +28,9 @@ public class BytesValueEncodingTest { BytesValue longBytesVal2 = BytesValueEncoding.encodeSingle(longVal, long.class); BytesValue longBytesVal3 = BytesValueEncoding.encodeSingle(longVal, Long.class); - assertEquals(longBytesVal1.getValue(), longBytesVal2.getValue()); + assertEquals(longBytesVal1.getBytes(), longBytesVal2.getBytes()); assertEquals(longBytesVal1.getType(), longBytesVal2.getType()); - assertEquals(longBytesVal2.getValue(), longBytesVal3.getValue()); + assertEquals(longBytesVal2.getBytes(), longBytesVal3.getBytes()); assertEquals(longBytesVal2.getType(), longBytesVal3.getType()); long resolveLongVal1 = (long)BytesValueEncoding.decode(longBytesVal1); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java index a3faea12..6c1d4f57 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/DataAccountKVSetOpTemplateTest.java @@ -63,7 +63,7 @@ public class DataAccountKVSetOpTemplateTest { assertEquals(dataKv.length, resolvedKv.length); for (int i = 0; i < dataKv.length; i++) { assertEquals(dataKv[i].getKey(), resolvedKv[i].getKey()); - assertArrayEquals(dataKv[i].getValue().getValue().toBytes(), resolvedKv[i].getValue().getValue().toBytes()); + assertArrayEquals(dataKv[i].getValue().getBytes().toBytes(), resolvedKv[i].getValue().getBytes().toBytes()); assertEquals(dataKv[i].getValue().getType().CODE, resolvedKv[i].getValue().getType().CODE); assertEquals(dataKv[i].getExpectedVersion(), resolvedKv[i].getExpectedVersion()); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/IntegerToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/IntegerToBytesValueResolverTest.java index 8e39aa85..dd9d4632 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/IntegerToBytesValueResolverTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/IntegerToBytesValueResolverTest.java @@ -22,13 +22,13 @@ public class IntegerToBytesValueResolverTest { BytesValue intBytesValue2 = resolver.encode(intVal, Integer.class); - assertEquals(intBytesValue.getValue(), intBytesValue1.getValue()); + assertEquals(intBytesValue.getBytes(), intBytesValue1.getBytes()); - assertEquals(intBytesValue.getValue(), intBytesValue2.getValue()); + assertEquals(intBytesValue.getBytes(), intBytesValue2.getBytes()); Bytes intBytes = Bytes.fromInt(intVal); - assertEquals(intBytes, intBytesValue.getValue()); + assertEquals(intBytes, intBytesValue.getBytes()); assertEquals(intBytesValue.getType(), DataType.INT32); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java index bcadfc1e..3d54f16c 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/KVDataTest.java @@ -48,7 +48,7 @@ public class KVDataTest { System.out.println("------Assert start ------"); assertEquals(resolvedKvData.getKey(), kvData.getKey()); assertEquals(resolvedKvData.getExpectedVersion(), kvData.getExpectedVersion()); - assertArrayEquals(resolvedKvData.getValue().getValue().toBytes(), kvData.getValue().getValue().toBytes()); + assertArrayEquals(resolvedKvData.getValue().getBytes().toBytes(), kvData.getValue().getBytes().toBytes()); System.out.println("------Assert OK ------"); } } \ No newline at end of file diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/LongToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/LongToBytesValueResolverTest.java index 899a6415..b4d20b4c 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/LongToBytesValueResolverTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/LongToBytesValueResolverTest.java @@ -23,13 +23,13 @@ public class LongToBytesValueResolverTest { BytesValue longBytesValue2 = resolver.encode(longVal, Long.class); - assertEquals(longBytesValue.getValue(), longBytesValue1.getValue()); + assertEquals(longBytesValue.getBytes(), longBytesValue1.getBytes()); - assertEquals(longBytesValue.getValue(), longBytesValue2.getValue()); + assertEquals(longBytesValue.getBytes(), longBytesValue2.getBytes()); Bytes longBytes = Bytes.fromLong(longVal); - assertEquals(longBytes, longBytesValue.getValue()); + assertEquals(longBytes, longBytesValue.getBytes()); assertEquals(longBytesValue.getType(), DataType.INT64); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ShortToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ShortToBytesValueResolverTest.java index b35cedd7..2e8e46be 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ShortToBytesValueResolverTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/ShortToBytesValueResolverTest.java @@ -21,7 +21,7 @@ public class ShortToBytesValueResolverTest { Bytes shortBytes = new Bytes(BytesUtils.toBytes(shortVal)); - assertEquals(shortBytes, shortBytesValue.getValue()); + assertEquals(shortBytes, shortBytesValue.getBytes()); assertEquals(shortBytesValue.getType(), DataType.INT16); diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/StringToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/StringToBytesValueResolverTest.java index 17dd0c04..544f06bb 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/StringToBytesValueResolverTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/StringToBytesValueResolverTest.java @@ -20,7 +20,7 @@ public class StringToBytesValueResolverTest { BytesValue textBytesValue = resolver.encode(textVal); - assertEquals(Bytes.fromString(textVal), textBytesValue.getValue()); + assertEquals(Bytes.fromString(textVal), textBytesValue.getBytes()); assertEquals(textBytesValue.getType(), DataType.TEXT); @@ -43,7 +43,7 @@ public class StringToBytesValueResolverTest { Person person = new Person("zhangsan", 80); String personJson = JSON.toJSONString(person); BytesValue textBytesValue = resolver.encode(personJson); - assertEquals(Bytes.fromString(personJson), textBytesValue.getValue()); + assertEquals(Bytes.fromString(personJson), textBytesValue.getBytes()); assertEquals(textBytesValue.getType(), DataType.JSON); } diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/TxContentBlobTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/TxContentBlobTest.java index 0404ee38..c8d8c313 100644 --- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/TxContentBlobTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/TxContentBlobTest.java @@ -77,8 +77,8 @@ public class TxContentBlobTest { for (int j = 0; j < dataKv.length; j++) { assertEquals(dataKv[i].getKey(), resolvedKv[i].getKey()); assertEquals(dataKv[i].getExpectedVersion(), resolvedKv[i].getExpectedVersion()); - assertArrayEquals(dataKv[i].getValue().getValue().toBytes(), - resolvedKv[i].getValue().getValue().toBytes()); + assertArrayEquals(dataKv[i].getValue().getBytes().toBytes(), + resolvedKv[i].getValue().getBytes().toBytes()); } } } @@ -108,8 +108,8 @@ public class TxContentBlobTest { for (int j = 0; j < dataKv.length; j++) { assertEquals(dataKv[i].getKey(), resolvedKv[i].getKey()); assertEquals(dataKv[i].getExpectedVersion(), resolvedKv[i].getExpectedVersion()); - assertArrayEquals(dataKv[i].getValue().getValue().toBytes(), - resolvedKv[i].getValue().getValue().toBytes()); + assertArrayEquals(dataKv[i].getValue().getBytes().toBytes(), + resolvedKv[i].getValue().getBytes().toBytes()); } } } 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 64b7bbef..8bbada7f 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 @@ -331,7 +331,7 @@ public class LedgerQueryController implements BlockchainQueryService { LedgerQuery ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); - return dataAccountSet.getAccount(Bytes.fromBase58(address)); + return dataAccountSet.getAccount(Bytes.fromBase58(address)).getID(); } @RequestMapping(method = { RequestMethod.GET, @@ -350,11 +350,11 @@ public class LedgerQueryController implements BlockchainQueryService { KVDataEntry[] entries = new KVDataEntry[keys.length]; long ver; for (int i = 0; i < entries.length; i++) { - ver = dataAccount.getDataset().getVersion(Bytes.fromString(keys[i])); + ver = dataAccount.getDataset().getVersion(keys[i]); if (ver < 0) { entries[i] = new KVDataObject(keys[i], -1, null); } else { - BytesValue value = dataAccount.getDataset().getValue(Bytes.fromString(keys[i]), ver); + BytesValue value = dataAccount.getDataset().getValue(keys[i], ver); entries[i] = new KVDataObject(keys[i], ver, value); } } @@ -404,12 +404,12 @@ public class LedgerQueryController implements BlockchainQueryService { if (ver < 0) { entries[i] = new KVDataObject(keys[i], -1, null); } else { - if (dataAccount.getDataEntriesTotalCount() == 0 - || dataAccount.getDataset().getValue(Bytes.fromString(keys[i]), ver) == null) { + if (dataAccount.getDataset().getDataCount() == 0 + || dataAccount.getDataset().getValue(keys[i], ver) == null) { // is the address is not exist; the result is null; entries[i] = new KVDataObject(keys[i], -1, null); } else { - BytesValue value = dataAccount.getDataset().getValue(Bytes.fromString(keys[i]), ver); + BytesValue value = dataAccount.getDataset().getValue(keys[i], ver); entries[i] = new KVDataObject(keys[i], ver, value); } } @@ -431,7 +431,7 @@ public class LedgerQueryController implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataEntriesTotalCount()); + int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataset().getDataCount()); return dataAccount.getDataEntries(pages[0], pages[1]); } @@ -445,7 +445,7 @@ public class LedgerQueryController implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - return dataAccount.getDataEntriesTotalCount(); + return dataAccount.getDataset().getDataCount(); } @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/address/{address}") diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java index 895010f3..cc6d41a7 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java @@ -108,7 +108,7 @@ public class ClientResolveUtil { public static Object readValueByBytesValue(BytesValue bytesValue) { DataType dataType = bytesValue.getType(); - Bytes saveVal = bytesValue.getValue(); + Bytes saveVal = bytesValue.getBytes(); Object showVal; switch (dataType) { case BYTES: 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 72e6f3f2..86b70840 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 @@ -236,13 +236,13 @@ public class IntegrationTestAll4Redis { assertEquals(ledgerRepository.retrieveLatestBlockHeight(), txResp.getBlockHeight()); assertEquals("Value_A_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getAccount(dataKey.getAddress()).getDataset().getValue("A").getValue().toUTF8String()); + .getAccount(dataKey.getAddress()).getDataset().getValue("A").getBytes().toUTF8String()); assertEquals("Value_B_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getAccount(dataKey.getAddress()).getDataset().getValue("B").getValue().toUTF8String()); + .getAccount(dataKey.getAddress()).getDataset().getValue("B").getBytes().toUTF8String()); assertEquals("Value_C_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getAccount(dataKey.getAddress()).getDataset().getValue("C").getValue().toUTF8String()); + .getAccount(dataKey.getAddress()).getDataset().getValue("C").getBytes().toUTF8String()); assertEquals("Value_D_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) - .getAccount(dataKey.getAddress()).getDataset().getValue("D").getValue().toUTF8String()); + .getAccount(dataKey.getAddress()).getDataset().getValue("D").getBytes().toUTF8String()); assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) .getAccount(dataKey.getAddress()).getDataset().getVersion("A")); assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) @@ -473,7 +473,7 @@ public class IntegrationTestAll4Redis { Bytes dataAddress = AddressEncoding.generateAddress(pubKey); assertEquals(dataAddress, dataAccountSet.getAccount(dataAddress).getID().getAddress()); assertEquals("hello", - dataAccountSet.getAccount(dataAddress).getDataset().getValue(KEY_TOTAL, -1).getValue().toUTF8String()); + dataAccountSet.getAccount(dataAddress).getDataset().getValue(KEY_TOTAL, -1).getBytes().toUTF8String()); // 验证userAccount,从合约内部赋值,然后外部验证;内部定义动态key,外部不便于得到,临时屏蔽; // UserAccountSet userAccountSet = @@ -504,8 +504,8 @@ public class IntegrationTestAll4Redis { .getDataset().getValue("A"); BytesValue val2InDb = ledgerRepository.getDataAccountSet(block).getAccount(contractDataKey.getAddress()) .getDataset().getValue(KEY_TOTAL); - assertEquals("Value_A_0", val1InDb.getValue().toUTF8String()); - assertEquals("total value,dataAccount", val2InDb.getValue().toUTF8String()); + assertEquals("Value_A_0", val1InDb.getBytes().toUTF8String()); + assertEquals("total value,dataAccount", val2InDb.getBytes().toUTF8String()); } /** diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java index 33ad1f7c..a84654c2 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java @@ -4,28 +4,6 @@ public interface Dataset { long getDataCount(); -// /** -// * Create or update the value associated the specified key if the version -// * checking is passed.
-// * -// * The value of the key will be updated only if it's latest version equals the -// * specified version argument.
-// * If the key doesn't exist, it will be created when the version arg was -1. -// *

-// * 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 latest 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;
-// * If this operation fail by version checking or other reason, then -// * return -1; -// */ -// long setValue(String key, byte[] value, long version); - /** * Create or update the value associated the specified key if the version * checking is passed.
From a05f4e7895a1d1c5be94a2578c1d12db0ad4bc12 Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Fri, 25 Oct 2019 00:36:20 +0800 Subject: [PATCH 7/9] Fixed all compilation errors; --- .../blockchain/contract/ReadContractImpl.java | 6 +- .../contract/TransferContractImpl.java | 14 +- .../gateway/web/BlockBrowserController.java | 8 +- .../blockchain/ledger/core/DataAccount.java | 4 +- .../ledger/core/LedgerQueryService.java | 43 +- .../ledger/core/MerkleAccountSet.java | 7 +- .../blockchain/ledger/core/MerkleDataSet.java | 157 ++++- .../core/handles/ContractLedgerContext.java | 8 +- .../blockchain/ledger/TxTestContractImpl.java | 6 +- .../ledger/core/AccountSetTest.java | 3 +- .../jd/blockchain/ledger/ContractInfo.java | 3 +- .../jd/blockchain/ledger/KVDataObject.java | 616 ------------------ .../com/jd/blockchain/ledger/TypedKVData.java | 78 +++ .../{KVDataEntry.java => TypedKVEntry.java} | 10 +- .../com/jd/blockchain/ledger/TypedValue.java | 31 +- .../transaction/BlockchainQueryService.java | 8 +- .../peer/web/LedgerQueryController.java | 56 +- .../sdk/converters/ClientResolveUtil.java | 8 +- .../sdk/proxy/BlockchainServiceProxy.java | 14 +- .../sdk/proxy/HttpBlockchainQueryService.java | 6 +- .../contract/samples/AssetContractImpl.java | 16 +- .../blockchain/sdk/samples/SDKDemo_Query.java | 4 +- .../sdk/samples/SDK_Contract_Demo.java | 6 +- .../sdk/samples/SDK_Contract_Random_Demo.java | 4 +- .../sdk/samples/SDK_InsertData_Demo.java | 4 +- .../sdk/test/SDK_GateWay_Query_Test_.java | 6 +- .../jd/blockchain/intgr/IntegrationTest.java | 6 +- .../jd/blockchain/intgr/IntegrationBase.java | 4 +- .../intgr/IntegrationTestAll4Redis.java | 6 +- .../intgr/IntegrationTestDataAccount.java | 4 +- .../com/jd/blockchain/utils/ArrayUtils.java | 69 +- .../com/jd/blockchain/utils/BaseConstant.java | 2 - .../com/jd/blockchain/utils/DataEntry.java | 2 +- .../com/jd/blockchain/utils/DataIterator.java | 21 + .../jd/blockchain/utils/DataTypeUtils.java | 34 - .../java/com/jd/blockchain/utils/Dataset.java | 72 +- .../jd/blockchain/utils/DatasetHelper.java | 93 ++- 37 files changed, 605 insertions(+), 834 deletions(-) delete mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedKVData.java rename source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/{KVDataEntry.java => TypedKVEntry.java} (57%) create mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataIterator.java delete mode 100644 source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataTypeUtils.java diff --git a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java index e3d720a5..2f6e0610 100644 --- a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java +++ b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java @@ -1,7 +1,7 @@ package com.jd.blockchain.contract; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; @Contract public class ReadContractImpl implements EventProcessingAware, ReadContract { @@ -24,7 +24,7 @@ public class ReadContractImpl implements EventProcessingAware, ReadContract { @Override @ContractEvent(name = "read-key") public String read(String address, String key) { - KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); + TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); if (kvDataEntries != null && kvDataEntries.length == 1) { return kvDataEntries[0].getValue().toString(); @@ -35,7 +35,7 @@ public class ReadContractImpl implements EventProcessingAware, ReadContract { @Override @ContractEvent(name = "version-key") public Long readVersion(String address, String key) { - KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); + TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); if (kvDataEntries != null && kvDataEntries.length == 1) { return kvDataEntries[0].getVersion(); diff --git a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContractImpl.java b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContractImpl.java index c312dd4f..d29ee281 100644 --- a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContractImpl.java +++ b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContractImpl.java @@ -2,7 +2,7 @@ package com.jd.blockchain.contract; import com.alibaba.fastjson.JSON; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.KVDataVO; import com.jd.blockchain.ledger.KVInfoVO; @@ -14,7 +14,7 @@ public class TransferContractImpl implements EventProcessingAware, TransferContr @Override public String create(String address, String account, long money) { - KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account); + TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account); // 肯定有返回值,但若不存在则返回version=-1 if (kvDataEntries != null && kvDataEntries.length > 0) { long currVersion = kvDataEntries[0].getVersion(); @@ -32,13 +32,13 @@ public class TransferContractImpl implements EventProcessingAware, TransferContr @Override public String transfer(String address, String from, String to, long money) { // 首先查询余额 - KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, from, to); + TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, from, to); if (kvDataEntries == null || kvDataEntries.length != 2) { throw new IllegalStateException(String.format("%s -> %s - %s may be not created !!!", address, from, to)); } else { // 判断from账号中钱数量是否足够 long fromMoney = 0L, toMoney = 0L, fromVersion = 0L, toVersion = 0L; - for (KVDataEntry kvDataEntry : kvDataEntries) { + for (TypedKVEntry kvDataEntry : kvDataEntries) { if (kvDataEntry.getKey().equals(from)) { fromMoney = (long) kvDataEntry.getValue(); fromVersion = kvDataEntry.getVersion(); @@ -62,7 +62,7 @@ public class TransferContractImpl implements EventProcessingAware, TransferContr @Override public long read(String address, String account) { - KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account); + TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account); if (kvDataEntries == null || kvDataEntries.length == 0) { return -1; } @@ -71,7 +71,7 @@ public class TransferContractImpl implements EventProcessingAware, TransferContr @Override public String readAll(String address, String account) { - KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account); + TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account); // 获取最新的版本号 if (kvDataEntries == null || kvDataEntries.length == 0) { return ""; @@ -91,7 +91,7 @@ public class TransferContractImpl implements EventProcessingAware, TransferContr KVInfoVO kvInfoVO = new KVInfoVO(kvDataVOS); - KVDataEntry[] allEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, kvInfoVO); + TypedKVEntry[] allEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, kvInfoVO); return JSON.toJSONString(allEntries); } diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java index f39e9424..12dfb4f5 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java @@ -25,7 +25,7 @@ import com.jd.blockchain.gateway.PeerService; import com.jd.blockchain.gateway.service.DataRetrievalService; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.ContractInfo; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.KVInfoVO; import com.jd.blockchain.ledger.LedgerAdminInfo; import com.jd.blockchain.ledger.LedgerBlock; @@ -261,7 +261,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/{address}/entries") @Override - public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, + public TypedKVEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, @PathVariable("address") String address, @RequestParam("keys") String... keys) { return peerService.getQueryService().getDataEntries(ledgerHash, address, keys); } @@ -269,7 +269,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") @Override - public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, + public TypedKVEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, @PathVariable("address") String address, @RequestBody KVInfoVO kvInfoVO) { return peerService.getQueryService().getDataEntries(ledgerHash, address, kvInfoVO); } @@ -277,7 +277,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") @Override - public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, + public TypedKVEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, @PathVariable("address") String address, @RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, @RequestParam(name = "count", required = false, defaultValue = "-1") int count) { 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 324de791..58452dc2 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 @@ -2,8 +2,8 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.KVDataEntry; -import com.jd.blockchain.ledger.KVDataObject; +import com.jd.blockchain.ledger.TypedKVEntry; +import com.jd.blockchain.ledger.TypedKVData; import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.utils.Bytes; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java index 2c9e92de..c58d5a5c 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerQueryService.java @@ -8,8 +8,9 @@ import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.ContractInfo; -import com.jd.blockchain.ledger.KVDataEntry; -import com.jd.blockchain.ledger.KVDataObject; +import com.jd.blockchain.ledger.TypedKVEntry; +import com.jd.blockchain.ledger.TypedValue; +import com.jd.blockchain.ledger.TypedKVData; import com.jd.blockchain.ledger.KVDataVO; import com.jd.blockchain.ledger.KVInfoVO; import com.jd.blockchain.ledger.LedgerAdminInfo; @@ -22,12 +23,15 @@ import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.ledger.UserInfo; import com.jd.blockchain.transaction.BlockchainQueryService; +import com.jd.blockchain.utils.ArrayUtils; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.DataEntry; +import com.jd.blockchain.utils.DataIterator; import com.jd.blockchain.utils.QueryUtil; public class LedgerQueryService implements BlockchainQueryService { - private static final KVDataEntry[] EMPTY_ENTRIES = new KVDataEntry[0]; + private static final TypedKVEntry[] EMPTY_ENTRIES = new TypedKVEntry[0]; private HashDigest[] ledgerHashs; @@ -278,7 +282,7 @@ public class LedgerQueryService implements BlockchainQueryService { } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { if (keys == null || keys.length == 0) { return EMPTY_ENTRIES; } @@ -287,7 +291,8 @@ public class LedgerQueryService implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - KVDataEntry[] entries = new KVDataEntry[keys.length]; + + TypedKVEntry[] entries = new TypedKVEntry[keys.length]; long ver; for (int i = 0; i < entries.length; i++) { final String currKey = keys[i]; @@ -295,17 +300,17 @@ public class LedgerQueryService implements BlockchainQueryService { ver = dataAccount == null ? -1 : dataAccount.getDataset().getVersion(currKey); if (ver < 0) { - entries[i] = new KVDataObject(currKey, -1, null); + entries[i] = new TypedKVData(currKey, -1, null); } else { BytesValue value = dataAccount.getDataset().getValue(currKey, ver); - entries[i] = new KVDataObject(currKey, ver, value); + entries[i] = new TypedKVData(currKey, ver, value); } } return entries; } - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { // parse kvInfoVO; List keyList = new ArrayList<>(); List versionList = new ArrayList<>(); @@ -335,22 +340,22 @@ public class LedgerQueryService implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - KVDataEntry[] entries = new KVDataEntry[keys.length]; + TypedKVEntry[] entries = new TypedKVEntry[keys.length]; long ver = -1; for (int i = 0; i < entries.length; i++) { // ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); // dataAccount.getBytes(Bytes.fromString(keys[i]),1); ver = versions[i]; if (ver < 0) { - entries[i] = new KVDataObject(keys[i], -1, null); + entries[i] = new TypedKVData(keys[i], -1, null); } else { if (dataAccount.getDataset().getDataCount() == 0 || dataAccount.getDataset().getValue(keys[i], ver) == null) { // is the address is not exist; the result is null; - entries[i] = new KVDataObject(keys[i], -1, null); + entries[i] = new TypedKVData(keys[i], -1, null); } else { BytesValue value = dataAccount.getDataset().getValue(keys[i], ver); - entries[i] = new KVDataObject(keys[i], ver, value); + entries[i] = new TypedKVData(keys[i], ver, value); } } } @@ -359,14 +364,22 @@ public class LedgerQueryService implements BlockchainQueryService { } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { checkLedgerHash(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataset().getDataCount()); - return dataAccount.getDataset()..getDataEntries(pages[0], pages[1]); +// int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataset().getDataCount()); +// return dataAccount.getDataset().getDataEntry(key, version).getDataEntries(pages[0], pages[1]); + + DataIterator iterator = dataAccount.getDataset().iterator(); + iterator.skip(fromIndex); + DataEntry[] dataEntries = iterator.next(count); + + TypedKVEntry[] typedKVEntries = ArrayUtils.castTo(dataEntries, TypedKVEntry.class, + e -> e == null ? null : new TypedKVData(e.getKey(), e.getVersion(), e.getValue())); + return typedKVEntries; } @Override diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java index 73696c27..3cc65cb7 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java @@ -136,7 +136,12 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * @return */ public boolean contains(Bytes address) { - long latestVersion = getVersion(address); + InnerMerkleAccount acc = latestAccountsCache.get(address); + if (acc != null) { + // 无论是新注册未提交的,还是缓存已提交的账户实例,都认为是存在; + return true; + } + long latestVersion = merkleDataset.getVersion(address); return latestVersion > -1; } 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 2e31c27e..80217efe 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 @@ -10,10 +10,12 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.storage.service.utils.BufferedKVStorage; import com.jd.blockchain.storage.service.utils.VersioningKVData; +import com.jd.blockchain.utils.ArrayUtils; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.Transactional; import com.jd.blockchain.utils.DataEntry; +import com.jd.blockchain.utils.DataIterator; import com.jd.blockchain.utils.Dataset; +import com.jd.blockchain.utils.Transactional; import com.jd.blockchain.utils.io.BytesUtils; /** @@ -39,6 +41,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable, Dataset[] EMPTY_ENTRIES = new DataEntry[0]; + private BufferedKVStorage bufferedStorage; private VersioningKVStorage valueStorage; @@ -162,11 +167,16 @@ public class MerkleDataSet implements Transactional, MerkleProvable, Dataset LedgerConsts.MAX_LIST_COUNT) { throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!"); } @@ -182,13 +192,16 @@ public class MerkleDataSet implements Transactional, MerkleProvable, Dataset[] getLatestDataEntries(int fromIndex, int count) { + public DataEntry[] getLatestDataEntries(long fromIndex, int count) { if (count > LedgerConsts.MAX_LIST_COUNT) { throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!"); } if (fromIndex < 0 || (fromIndex + count) > merkleTree.getDataCount()) { throw new IllegalArgumentException("Index out of bound!"); } + if (count == 0) { + return EMPTY_ENTRIES; + } @SuppressWarnings("unchecked") DataEntry[] values = new DataEntry[count]; byte[] bytesValue; @@ -201,6 +214,19 @@ public class MerkleDataSet implements Transactional, MerkleProvable, Dataset getLatestDataEntry(long index) { + if (index < 0 || index + 1 > merkleTree.getDataCount()) { + throw new IllegalArgumentException("Index out of bound!"); + } + byte[] bytesValue; + MerkleDataNode dataNode = merkleTree.getData(index); + Bytes dataKey = encodeDataKey(dataNode.getKey()); + bytesValue = valueStorage.get(dataKey, dataNode.getVersion()); + DataEntry entry = new VersioningKVData(dataNode.getKey(), dataNode.getVersion(), + bytesValue); + return entry; + } + /** * get the data at the specific index; * @@ -505,6 +531,16 @@ public class MerkleDataSet implements Transactional, MerkleProvable, Dataset(key, version, value); } + @Override + public DataIterator iterator() { + return new AscDataInterator(getDataCount()); + } + + @Override + public DataIterator iteratorDesc() { + return new DescDataInterator(getDataCount()); + } + public MerkleDataEntry getMerkleEntry(Bytes key, long version) { DataEntry dataEntry = getDataEntry(key, version); if (dataEntry == null) { @@ -586,4 +622,119 @@ public class MerkleDataSet implements Transactional, MerkleProvable, Dataset { + + private final long total; + + private long cursor = 0; + + public AscDataInterator(long total) { + this.total = total; + } + + @Override + public void skip(long count) { + cursor = nextCursor(count); + } + + private long nextCursor(long skippingCount) { + long c = cursor + skippingCount; + return c > total ? total : c; + } + + @Override + public DataEntry next() { + if (hasNext()) { + DataEntry entry = getLatestDataEntry(cursor); + cursor = nextCursor(1); + return entry; + } + return null; + } + + @Override + public DataEntry[] next(int count) { + if (hasNext()) { + long from = cursor; + long nextCursor = nextCursor(count); + long c = nextCursor - cursor; + if (c > LedgerConsts.MAX_LIST_COUNT) { + throw new IllegalArgumentException( + "Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!"); + } + DataEntry[] entries = getLatestDataEntries(from, (int) c); + cursor = nextCursor; + return entries; + } + return EMPTY_ENTRIES; + } + + @Override + public boolean hasNext() { + return cursor < total; + } + + } + + private class DescDataInterator implements DataIterator { + + private final long total; + + private long cursor; + + public DescDataInterator(long total) { + this.total = total; + this.cursor = total - 1; + } + + @Override + public void skip(long count) { + cursor = nextCursor(count); + } + + private long nextCursor(long skippingCount) { + long c = cursor - skippingCount; + return c < 0 ? -1 : c; + } + + @Override + public DataEntry next() { + if (hasNext()) { + DataEntry entry = getLatestDataEntry(cursor); + cursor = nextCursor(1); + return entry; + } + return null; + } + + @Override + public DataEntry[] next(int count) { + if (hasNext()) { + long nextCursor = nextCursor(count); + long from = nextCursor + 1; + long c = cursor - nextCursor; + if (c > LedgerConsts.MAX_LIST_COUNT) { + throw new IllegalArgumentException( + "Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!"); + } + DataEntry[] entries = getLatestDataEntries(from, (int) c); + // reverse; + ArrayUtils.reverse(entries); + + cursor = nextCursor; + return entries; + } + return EMPTY_ENTRIES; + } + + @Override + public boolean hasNext() { + return cursor < total; + } + + } + } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java index e86747db..fe3f9826 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/handles/ContractLedgerContext.java @@ -10,7 +10,7 @@ import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.ContractInfo; import com.jd.blockchain.ledger.DataAccountKVSetOperation; import com.jd.blockchain.ledger.DataAccountRegisterOperation; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.KVInfoVO; import com.jd.blockchain.ledger.LedgerAdminInfo; import com.jd.blockchain.ledger.LedgerBlock; @@ -172,17 +172,17 @@ public class ContractLedgerContext implements LedgerContext { } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { return innerQueryService.getDataEntries(ledgerHash, address, keys); } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { return innerQueryService.getDataEntries(ledgerHash, address, kvInfoVO); } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { return innerQueryService.getDataEntries(ledgerHash, address, fromIndex, count); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TxTestContractImpl.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TxTestContractImpl.java index 60ee6864..a0bf65be 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TxTestContractImpl.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TxTestContractImpl.java @@ -3,7 +3,7 @@ package test.com.jd.blockchain.ledger; import com.jd.blockchain.contract.ContractEventContext; import com.jd.blockchain.contract.ContractLifecycleAware; import com.jd.blockchain.contract.EventProcessingAware; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.utils.Bytes; public class TxTestContractImpl implements TxTestContract, ContractLifecycleAware, EventProcessingAware { @@ -16,7 +16,7 @@ public class TxTestContractImpl implements TxTestContract, ContractLifecycleAwar @Override public boolean testReadable() { - KVDataEntry v1 = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), + TypedKVEntry v1 = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), dataAddress.toBase58(), KEY)[0]; String text1 = (String) v1.getValue(); System.out.printf("k1=%s, version=%s \r\n", text1, v1.getVersion()); @@ -26,7 +26,7 @@ public class TxTestContractImpl implements TxTestContract, ContractLifecycleAwar System.out.printf("new value = %s\r\n", newValue); eventContext.getLedger().dataAccount(dataAddress).setText(KEY, newValue, v1.getVersion()); - KVDataEntry v2 = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), + TypedKVEntry v2 = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), dataAddress.toBase58(), KEY)[0]; System.out.printf("---- read new value ----\r\nk1=%s, version=%s \r\n", v2.getValue(), v2.getVersion()); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java index 6a99be27..64f99a23 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java @@ -48,7 +48,8 @@ public class AccountSetTest { BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); accset.register(userKey.getAddress(), userKey.getPubKey()); - + + //尚未提交之前,可以检索到账户的存在,但版本仍然标记为 -1; MerkleAccount userAcc = accset.getAccount(userKey.getAddress()); assertNotNull(userAcc); assertTrue(accset.contains(userKey.getAddress())); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java index 4683f9ca..047e3c51 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractInfo.java @@ -6,8 +6,9 @@ import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.consts.DataCodes; @DataContract(code= DataCodes.CONTRACT_ACCOUNT_HEADER) -public interface ContractInfo extends BlockchainIdentity { +public interface ContractInfo extends BlockchainIdentity, MerkleSnapshot { @DataField(order=4, primitiveType= PrimitiveType.BYTES) byte[] getChainCode(); + } 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 deleted file mode 100644 index a19d9fff..00000000 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataObject.java +++ /dev/null @@ -1,616 +0,0 @@ -package com.jd.blockchain.ledger; - -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; - -/** - * KV数据项; - * - *

- * - * {@link KVDataObject} 被设计为只读对象; - * - * @author huanghaiquan - * - */ -public class KVDataObject implements KVDataEntry { - - private String key; - - private long version; - - private BytesValue bytesValue; - - public KVDataObject(String key, long version, BytesValue bytesValue) { - this.key = key; - this.version = version < 0 ? -1 : version; - this.bytesValue = bytesValue; - } - - /* - * (non-Javadoc) - * - * @see com.jd.blockchain.ledger.KVDataEntry#getKey() - */ - @Override - public String getKey() { - return key; - } - - /* - * (non-Javadoc) - * - * @see com.jd.blockchain.ledger.KVDataEntry#getVersion() - */ - @Override - public long getVersion() { - return version; - } - - /* - * (non-Javadoc) - * - * @see com.jd.blockchain.ledger.KVDataEntry#getType() - */ - @Override - public DataType getType() { - return bytesValue == null ? DataType.NIL : bytesValue.getType(); - } - - @Override - public Object getValue() { - if (bytesValue == null) { - return null; - } - - switch (getType()) { - case NIL: - return null; - case TEXT: - return bytesValue.getBytes().toUTF8String(); - case BYTES: - return ByteArray.toHex(bytesValue.getBytes().toBytes()); - case INT64: - return BytesUtils.toLong(bytesValue.getBytes().toBytes()); - case JSON: - return bytesValue.getBytes().toUTF8String(); - case XML: - return bytesValue.getBytes().toUTF8String(); - - default: - throw new IllegalStateException("Unsupported value type[" + getType() + "] to resolve!"); - } - } - - /** - * 是否为空值; - *

- * - * 仅当数据类型 {@link #getType()} 为 {@link PrimitiveType#NIL} 时返回 true,其它情况返回 false; - *

- * - * @return - */ - public boolean isNil() { - return bytesValue == null || DataType.NIL == bytesValue.getType(); - } - - /** - * 字节数组形式的原始内容; - * - * @return - */ - Bytes bytesArray() { - return bytesValue.getBytes(); - } - - /** - * 返回 8 位整数值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public byte tinyValue() { - if (DataType.INT8 == getType()) { - return bytesValue.getBytes().toBytes()[0]; - } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT8, getType())); - } - - /** - * 返回 16 位整数值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public short shortValue() { - if (DataType.INT16 == getType()) { - return BytesUtils.toShort(bytesValue.getBytes().toBytes(), 0); - } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT16, getType())); - } - - /** - * 返回 32 位整数值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public int intValue() { - if (DataType.INT32 == getType()) { - return BytesUtils.toInt(bytesValue.getBytes().toBytes(), 0); - } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT32, getType())); - } - - /** - * 返回 64 位整数值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public long longValue() { - if (DataType.INT64 == getType()) { - return BytesUtils.toLong(bytesValue.getBytes().toBytes(), 0); - } - throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT64, getType())); - - } - - /** - * 返回大整数值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public BigInteger bigIntValue() { - if (DataType.BIG_INT == getType()) { - return new BigInteger(bytesValue.getBytes().toBytes()); - } - throw new IllegalStateException( - String.format("Expected type [%s], but [%s]", DataType.BIG_INT, getType())); - } - - /** - * 返回布尔值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public boolean boolValue() { - if (DataType.BOOLEAN == getType()) { - return BytesUtils.toBoolean(bytesValue.getBytes().toBytes()[0]); - } - throw new IllegalStateException( - String.format("Expected type [%s], but [%s]", DataType.BOOLEAN, getType())); - } - - /** - * 返回日期时间值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public Date datetimeValue() { - if (DataType.TIMESTAMP == getType()) { - long ts = BytesUtils.toLong(bytesValue.getBytes().toBytes()); - return new Date(ts); - } - throw new IllegalStateException( - String.format("Expected type [%s], but [%s]", DataType.TIMESTAMP, getType())); - } - - /** - * 返回大整数值; - *

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

- * - * 无效类型将引发 {@link IllegalStateException} 异常; - * - * @return - */ - public String stringValue() { - DataType type = getType(); - if (DataType.TEXT == type || DataType.JSON == type || DataType.XML == type) { - return bytesValue.getBytes().toUTF8String(); - } - throw new IllegalStateException(String.format("Expected type [%s] or [%s] or [%s] , but [%s]", - PrimitiveType.TEXT, DataType.JSON, DataType.XML, type)); - } - -// // ---------------- -// public KVDataEntry nextVersionNil() { -// return nilState(key, version + 1); -// } -// -// public KVDataEntry nextVersionBoolean(boolean value) { -// return booleanState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionTiny(byte value) { -// return tinyState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionShort(short value) { -// return shortState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionInt(int value) { -// return intState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionLong(long value) { -// return longState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionDatetime(Date value) { -// return datetimeState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionJson(String value) { -// return jsonState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionXml(String value) { -// return xmlState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionBigInt(BigInteger value) { -// return bigIntState(key, version + 1, value); -// } -// -// public KVDataEntry nextVersionText(boolean encrypted, String value) { -// return textState(key, version + 1, encrypted, value); -// } -// -// public KVDataEntry nextVersionBytes(boolean encrypted, byte[] value) { -// return bytesState(key, version + 1, encrypted, value); -// } -// -// public KVDataEntry nextVersionImage(boolean encrypted, byte[] value) { -// return imageState(key, version + 1, encrypted, value); -// } -// -// public KVDataEntry nextVersionVideo(boolean encrypted, byte[] value) { -// return videoState(key, version + 1, encrypted, value); -// } -// -// public KVDataEntry nextVersionLocation(boolean encrypted, byte[] value) { -// return locationState(key, version + 1, encrypted, value); -// } -// // ---------------- -// -// public KVDataEntry newNil() { -// return nilState(key, version); -// } -// -// public KVDataEntry newBoolean(boolean value) { -// return booleanState(key, version, value); -// } -// -// public KVDataEntry newTiny(byte value) { -// return tinyState(key, version, value); -// } -// -// public KVDataEntry newShort(short value) { -// return shortState(key, version, value); -// } -// -// public KVDataEntry newInt(int value) { -// return intState(key, version, value); -// } -// -// public KVDataObject newLong(long value) { -// return longState(key, version, value); -// } -// -// public KVDataEntry newDatetime(Date value) { -// return datetimeState(key, version, value); -// } -// -// public KVDataEntry newJson(String value) { -// return jsonState(key, version, value); -// } -// -// public KVDataEntry newXml(String value) { -// return xmlState(key, version, value); -// } -// -// public KVDataEntry newBigInt(BigInteger value) { -// return bigIntState(key, version, value); -// } -// -// public KVDataEntry newText(boolean encrypted, String value) { -// return textState(key, version, encrypted, value); -// } -// -// public KVDataEntry newBytes(boolean encrypted, byte[] value) { -// return bytesState(key, version, encrypted, value); -// } -// -// public KVDataEntry newImage(boolean encrypted, byte[] value) { -// return imageState(key, version, encrypted, value); -// } -// -// public KVDataEntry newVideo(boolean encrypted, byte[] value) { -// return videoState(key, version, encrypted, value); -// } -// -// public KVDataEntry newLocation(boolean encrypted, byte[] value) { -// return locationState(key, version, encrypted, value); -// } -// -// // ---------------- -// -// public KVDataEntry newNil(long version) { -// return nilState(key, version); -// } -// -// public KVDataEntry newBoolean(long version, boolean value) { -// return booleanState(key, version, value); -// } -// -// public KVDataEntry newTiny(long version, byte value) { -// return tinyState(key, version, value); -// } -// -// public KVDataEntry newShort(long version, short value) { -// return shortState(key, version, value); -// } -// -// public KVDataEntry newInt(long version, int value) { -// return intState(key, version, value); -// } -// -// public KVDataEntry newLong(long version, long value) { -// return longState(key, version, value); -// } -// -// public KVDataEntry newDatetime(long version, Date value) { -// return datetimeState(key, version, value); -// } -// -// public KVDataEntry newJson(long version, String value) { -// return jsonState(key, version, value); -// } -// -// public KVDataEntry newXml(long version, String value) { -// return xmlState(key, version, value); -// } -// -// public KVDataEntry newBigInt(long version, BigInteger value) { -// return bigIntState(key, version, value); -// } -// -// public KVDataEntry newText(long version, boolean encrypted, String value) { -// return textState(key, version, encrypted, value); -// } -// -// public KVDataEntry newBytes(long version, boolean encrypted, byte[] value) { -// return bytesState(key, version, encrypted, value); -// } -// -// public KVDataEntry newImage(long version, boolean encrypted, byte[] value) { -// return imageState(key, version, encrypted, value); -// } -// -// public KVDataEntry newVideo(long version, boolean encrypted, byte[] value) { -// return videoState(key, version, encrypted, value); -// } -// -// public KVDataEntry newLocation(long version, boolean encrypted, byte[] value) { -// return locationState(key, version, encrypted, value); -// } -// -// // ---------------- -// -// public static KVDataEntry booleanState(String key, boolean value) { -// return booleanState(key, -1, value); -// } -// -// public static KVDataEntry tinyState(String key, byte value) { -// return tinyState(key, -1, value); -// } -// -// public static KVDataEntry shortState(String key, short value) { -// return shortState(key, -1, value); -// } -// -// public static KVDataEntry intState(String key, int value) { -// return intState(key, -1, value); -// } -// -// public static KVDataEntry longState(String key, long value) { -// return longState(key, -1, value); -// } -// -// public static KVDataEntry datetimeState(String key, Date value) { -// return datetimeState(key, -1, value); -// } -// -// public static KVDataEntry jsonState(String key, String value) { -// return jsonState(key, -1, value); -// } -// -// public static KVDataEntry xmlState(String key, String value) { -// return xmlState(key, -1, value); -// } -// -// public static KVDataEntry bigIntState(String key, BigInteger value) { -// return bigIntState(key, -1, value); -// } -// -// public static KVDataObject textState(String key, String value) { -// return textState(key, -1, false, value); -// } -// -// public static KVDataEntry bytesState(String key, byte[] value) { -// return bytesState(key, -1, false, value); -// } -// -// public static KVDataEntry imageState(String key, byte[] value) { -// return imageState(key, -1, false, value); -// } -// -// public static KVDataEntry videoState(String key, byte[] value) { -// return videoState(key, -1, false, value); -// } -// -// public static KVDataEntry locationState(String key, byte[] value) { -// return locationState(key, -1, false, value); -// } -// -// // ---------------- -// -// public static KVDataEntry textState(String key, boolean encrypted, String value) { -// return textState(key, -1, encrypted, value); -// } -// -// public static KVDataEntry bytesState(String key, boolean encrypted, byte[] value) { -// return bytesState(key, -1, encrypted, value); -// } -// -// public static KVDataEntry imageState(String key, boolean encrypted, byte[] value) { -// return imageState(key, -1, encrypted, value); -// } -// -// public static KVDataEntry videoState(String key, boolean encrypted, byte[] value) { -// return videoState(key, -1, encrypted, value); -// } -// -// public static KVDataEntry locationState(String key, boolean encrypted, byte[] value) { -// return locationState(key, -1, encrypted, value); -// } -// -// // ---------------------- -// -// public static KVDataEntry nilState(String key) { -// return new KVDataObject(key, ValueType.NIL, -1, false, BytesUtils.EMPTY_BYTES); -// } -// -// public static KVDataEntry nilState(String key, long version) { -// return new KVDataObject(key, ValueType.NIL, version, false, BytesUtils.EMPTY_BYTES); -// } -// -// public static KVDataEntry booleanState(String key, long version, boolean value) { -// byte[] v = { value ? (byte) 1 : (byte) 0 }; -// return new KVDataObject(key, ValueType.BOOLEAN, version, false, v); -// } -// -// public static KVDataEntry tinyState(String key, long version, byte value) { -// byte[] v = { value }; -// return new KVDataObject(key, ValueType.INT8, version, false, v); -// } -// -// public static KVDataEntry shortState(String key, long version, short value) { -// byte[] v = BytesUtils.toBytes(value); -// return new KVDataObject(key, ValueType.INT16, version, false, v); -// } -// -// public static KVDataEntry intState(String key, long version, int value) { -// byte[] v = BytesUtils.toBytes(value); -// return new KVDataObject(key, ValueType.INT32, version, false, v); -// } -// -// public static KVDataObject longState(String key, long version, long value) { -// byte[] v = BytesUtils.toBytes(value); -// return new KVDataObject(key, ValueType.INT64, version, false, v); -// } -// -// public static KVDataEntry datetimeState(String key, long version, Date value) { -// byte[] v = BytesUtils.toBytes(value.getTime()); -// return new KVDataObject(key, ValueType.DATETIME, version, false, v); -// } -// -// public static KVDataObject textState(String key, long version, boolean encrypted, String value) { -// try { -// byte[] v = value.getBytes("UTF-8"); -// return new KVDataObject(key, ValueType.TEXT, version, encrypted, v); -// } catch (UnsupportedEncodingException e) { -// throw new IllegalStateException(e.getMessage(), e); -// } -// } -// -// public static KVDataEntry jsonState(String key, long version, String value) { -// try { -// byte[] v = value.getBytes("UTF-8"); -// return new KVDataObject(key, ValueType.JSON, version, false, v); -// } catch (UnsupportedEncodingException e) { -// throw new IllegalStateException(e.getMessage(), e); -// } -// } -// -// public static KVDataEntry xmlState(String key, long version, String value) { -// try { -// byte[] v = value.getBytes("UTF-8"); -// return new KVDataObject(key, ValueType.XML, version, false, v); -// } catch (UnsupportedEncodingException e) { -// throw new IllegalStateException(e.getMessage(), e); -// } -// } -// -// public static KVDataEntry bigIntState(String key, long version, BigInteger value) { -// byte[] v = value.toByteArray(); -// return new KVDataObject(key, ValueType.BIG_INT, version, false, v); -// } -// -// public static KVDataEntry bytesState(String key, long version, boolean encrypted, byte[] value) { -// return new KVDataObject(key, ValueType.BYTES, version, encrypted, value); -// } -// -// public static KVDataEntry imageState(String key, long version, boolean encrypted, byte[] value) { -// return new KVDataObject(key, ValueType.IMG, version, encrypted, value); -// } -// -// public static KVDataEntry videoState(String key, long version, boolean encrypted, byte[] value) { -// return new KVDataObject(key, ValueType.VIDEO, version, encrypted, value); -// } -// -// public static KVDataEntry locationState(String key, long version, boolean encrypted, byte[] value) { -// return new KVDataObject(key, ValueType.LOCATION, version, encrypted, value); -// } - -} \ No newline at end of file diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedKVData.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedKVData.java new file mode 100644 index 00000000..dd06de98 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedKVData.java @@ -0,0 +1,78 @@ +package com.jd.blockchain.ledger; + +/** + * 强类型的“键-值”数据对象; + * + *

+ * + * {@link TypedKVData} 被设计为只读对象; + * + * @author huanghaiquan + * + */ +public class TypedKVData implements TypedKVEntry { + + private String key; + + private long version; + + private DataType type; + + private Object value; + + public TypedKVData(String key, long version, DataType type, Object value) { + this.key = key; + this.version = version; + this.type = type; + this.value = value; + } + + public TypedKVData(String key, long version, BytesValue bytesValue) { + this.key = key; + this.version = version; + TypedValue typedValue; + if (bytesValue != null && bytesValue instanceof TypedValue) { + typedValue = (TypedValue) bytesValue; + } else { + typedValue = TypedValue.wrap(bytesValue); + } + this.type = typedValue.getType(); + this.value = typedValue.getValue(); + } + + /* + * (non-Javadoc) + * + * @see com.jd.blockchain.ledger.KVDataEntry#getKey() + */ + @Override + public String getKey() { + return key; + } + + /* + * (non-Javadoc) + * + * @see com.jd.blockchain.ledger.KVDataEntry#getVersion() + */ + @Override + public long getVersion() { + return version; + } + + /* + * (non-Javadoc) + * + * @see com.jd.blockchain.ledger.KVDataEntry#getType() + */ + @Override + public DataType getType() { + return type; + } + + @Override + public Object getValue() { + return value; + } + +} \ No newline at end of file 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/TypedKVEntry.java similarity index 57% rename from source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataEntry.java rename to source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedKVEntry.java index 396cc36d..54165c61 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/TypedKVEntry.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger; -public interface KVDataEntry { +public interface TypedKVEntry { /** * 键名; @@ -33,4 +33,12 @@ public interface KVDataEntry { */ Object getValue(); + default long longValue() { + if (getType() == DataType.INT64) { + Object value = getValue(); + return value == null ? 0 : (long) value; + } + throw new IllegalStateException(String.format("Expected type [%s], but [%s]", DataType.INT64, getType())); + } + } \ No newline at end of file diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java index e2c0c9d5..65dbd298 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TypedValue.java @@ -16,9 +16,9 @@ import com.jd.blockchain.utils.io.BytesUtils; * */ public class TypedValue implements BytesValue { - + public static final BytesValue NIL = new TypedValue(); - + private DataType type; private Bytes value; @@ -31,16 +31,19 @@ public class TypedValue implements BytesValue { this.type = type; this.value = bytes; } - + private TypedValue(BytesValue bytesValue) { - this.type = bytesValue.getType(); - this.value = bytesValue.getBytes(); + if (bytesValue == null) { + this.type = DataType.NIL; + } else { + this.type = bytesValue.getType(); + this.value = bytesValue.getBytes(); + } } - + private TypedValue() { this.type = DataType.NIL; } - @Override public DataType getType() { @@ -229,8 +232,7 @@ public class TypedValue implements BytesValue { if (DataType.BIG_INT == type) { return toBigInteger(); } - throw new IllegalStateException( - String.format("Type [%s] cannot be convert to BigInteger!", type)); + throw new IllegalStateException(String.format("Type [%s] cannot be convert to BigInteger!", type)); } private BigInteger toBigInteger() { @@ -280,8 +282,7 @@ public class TypedValue implements BytesValue { if (DataType.TIMESTAMP == type) { return toDatetime(); } - throw new IllegalStateException( - String.format("Type [%s] cannot be convert to datetime!", type)); + throw new IllegalStateException(String.format("Type [%s] cannot be convert to datetime!", type)); } private Date toDatetime() { @@ -346,8 +347,7 @@ public class TypedValue implements BytesValue { if (DataType.HASH_DIGEST == type) { return toHashDegist(); } - throw new IllegalStateException( - String.format("Type [%s] cannot be convert to hash digest!", type)); + throw new IllegalStateException(String.format("Type [%s] cannot be convert to hash digest!", type)); } private HashDigest toHashDegist() { @@ -375,14 +375,13 @@ public class TypedValue implements BytesValue { if (DataType.SIGNATURE_DIGEST == type) { return toSignatureDigest(); } - throw new IllegalStateException( - String.format("Type [%s] cannot be convert to signature digest!", type)); + throw new IllegalStateException(String.format("Type [%s] cannot be convert to signature digest!", type)); } private SignatureDigest toSignatureDigest() { return new SignatureDigest(toBytesArray()); } - + public static TypedValue wrap(BytesValue value) { return new TypedValue(value); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java index 9d8f5fa8..f63a7f2a 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java @@ -5,7 +5,7 @@ import org.springframework.cglib.core.Block; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.ContractInfo; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.KVInfoVO; import com.jd.blockchain.ledger.LedgerAdminInfo; import com.jd.blockchain.ledger.LedgerBlock; @@ -264,9 +264,9 @@ public interface BlockchainQueryService { * @param keys * @return */ - KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys); + TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys); - KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO); + TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO); /** * 返回指定数据账户中KV数据的总数;
@@ -287,7 +287,7 @@ public interface BlockchainQueryService { * 如果参数值为 -1,则返回全部的记录;
* @return */ - KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count); + TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count); /** * 返回合约账户信息; 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 8bbada7f..2fd0cd80 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 @@ -3,7 +3,6 @@ package com.jd.blockchain.peer.web; import java.util.ArrayList; import java.util.List; -import com.jd.blockchain.ledger.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -14,6 +13,22 @@ import org.springframework.web.bind.annotation.RestController; import com.jd.blockchain.contract.ContractException; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.ContractInfo; +import com.jd.blockchain.ledger.KVDataVO; +import com.jd.blockchain.ledger.KVInfoVO; +import com.jd.blockchain.ledger.LedgerAdminInfo; +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.TypedKVData; +import com.jd.blockchain.ledger.TypedKVEntry; +import com.jd.blockchain.ledger.TypedValue; +import com.jd.blockchain.ledger.UserInfo; import com.jd.blockchain.ledger.core.ContractAccountQuery; import com.jd.blockchain.ledger.core.DataAccount; import com.jd.blockchain.ledger.core.DataAccountQuery; @@ -23,7 +38,10 @@ import com.jd.blockchain.ledger.core.ParticipantCertData; import com.jd.blockchain.ledger.core.TransactionQuery; import com.jd.blockchain.ledger.core.UserAccountQuery; import com.jd.blockchain.transaction.BlockchainQueryService; +import com.jd.blockchain.utils.ArrayUtils; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.DataEntry; +import com.jd.blockchain.utils.DataIterator; import com.jd.blockchain.utils.QueryUtil; @RestController @@ -72,7 +90,7 @@ public class LedgerQueryController implements BlockchainQueryService { } return null; } - + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/admininfo") @Override public LedgerAdminInfo getLedgerAdminInfo(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { @@ -337,7 +355,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/{address}/entries") @Override - public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public TypedKVEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @PathVariable(name = "address") String address, @RequestParam("keys") String... keys) { if (keys == null || keys.length == 0) { return null; @@ -347,15 +365,15 @@ public class LedgerQueryController implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - KVDataEntry[] entries = new KVDataEntry[keys.length]; + TypedKVEntry[] entries = new TypedKVEntry[keys.length]; long ver; for (int i = 0; i < entries.length; i++) { ver = dataAccount.getDataset().getVersion(keys[i]); if (ver < 0) { - entries[i] = new KVDataObject(keys[i], -1, null); + entries[i] = new TypedKVData(keys[i], -1, null); } else { BytesValue value = dataAccount.getDataset().getValue(keys[i], ver); - entries[i] = new KVDataObject(keys[i], ver, value); + entries[i] = new TypedKVData(keys[i], ver, value); } } @@ -365,7 +383,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") @Override - public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public TypedKVEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @PathVariable(name = "address") String address, @RequestBody KVInfoVO kvInfoVO) { // parse kvInfoVO; List keyList = new ArrayList<>(); @@ -396,21 +414,21 @@ public class LedgerQueryController implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - KVDataEntry[] entries = new KVDataEntry[keys.length]; + TypedKVEntry[] entries = new TypedKVEntry[keys.length]; long ver = -1; for (int i = 0; i < entries.length; i++) { // ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); ver = versions[i]; if (ver < 0) { - entries[i] = new KVDataObject(keys[i], -1, null); + entries[i] = new TypedKVData(keys[i], -1, null); } else { if (dataAccount.getDataset().getDataCount() == 0 || dataAccount.getDataset().getValue(keys[i], ver) == null) { // is the address is not exist; the result is null; - entries[i] = new KVDataObject(keys[i], -1, null); + entries[i] = new TypedKVData(keys[i], -1, null); } else { BytesValue value = dataAccount.getDataset().getValue(keys[i], ver); - entries[i] = new KVDataObject(keys[i], ver, value); + entries[i] = new TypedKVData(keys[i], ver, value); } } } @@ -421,7 +439,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") @Override - public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, + public TypedKVEntry[] 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) { @@ -431,15 +449,21 @@ public class LedgerQueryController implements BlockchainQueryService { DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address)); - int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataset().getDataCount()); - return dataAccount.getDataEntries(pages[0], pages[1]); +// int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccount.getDataset().getDataCount()); +// return dataAccount.getDataEntries(pages[0], pages[1]); + + DataIterator iterator = dataAccount.getDataset().iterator(); + iterator.skip(fromIndex); + DataEntry[] dataEntries = iterator.next(count); + TypedKVEntry[] typedKVEntries = ArrayUtils.castTo(dataEntries, TypedKVEntry.class, + e -> e == null ? null : new TypedKVData(e.getKey(), e.getVersion(), e.getValue())); + return typedKVEntries; } @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) { - LedgerQuery ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); @@ -451,7 +475,7 @@ public class LedgerQueryController implements BlockchainQueryService { @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/address/{address}") @Override public ContractInfo getContract(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, - @PathVariable(name = "address") String address) { + @PathVariable(name = "address") String address) { LedgerQuery ledger = ledgerService.getLedger(ledgerHash); LedgerBlock block = ledger.getLatestBlock(); ContractAccountQuery contractAccountSet = ledger.getContractAccountSet(block); diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java index cc6d41a7..4e7534a4 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java @@ -39,14 +39,14 @@ import com.jd.blockchain.utils.io.BytesUtils; public class ClientResolveUtil { - public static KVDataEntry[] read(KVDataEntry[] kvDataEntries) { + public static TypedKVEntry[] read(TypedKVEntry[] kvDataEntries) { if (kvDataEntries == null || kvDataEntries.length == 0) { return kvDataEntries; } - KVDataEntry[] resolveKvDataEntries = new KVDataEntry[kvDataEntries.length]; + TypedKVEntry[] resolveKvDataEntries = new TypedKVEntry[kvDataEntries.length]; // kvDataEntries是代理对象,需要处理 for (int i = 0; i < kvDataEntries.length; i++) { - KVDataEntry kvDataEntry = kvDataEntries[i]; + TypedKVEntry kvDataEntry = kvDataEntries[i]; String key = kvDataEntry.getKey(); long version = kvDataEntry.getVersion(); DataType dataType = kvDataEntry.getType(); @@ -330,7 +330,7 @@ public class ClientResolveUtil { } - public static class KvData implements KVDataEntry { + public static class KvData implements TypedKVEntry { private String key; diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java index 4949a777..9984cef5 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java @@ -3,7 +3,7 @@ package com.jd.blockchain.sdk.proxy; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.ContractInfo; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.KVInfoVO; import com.jd.blockchain.ledger.LedgerAdminInfo; import com.jd.blockchain.ledger.LedgerBlock; @@ -161,20 +161,20 @@ public abstract class BlockchainServiceProxy implements BlockchainService { } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { - KVDataEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys); + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) { + TypedKVEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys); return ClientResolveUtil.read(kvDataEntries); } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { - KVDataEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, kvInfoVO); + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { + TypedKVEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, kvInfoVO); return ClientResolveUtil.read(kvDataEntries); } @Override - public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { - KVDataEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, fromIndex, count); + public TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { + TypedKVEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, fromIndex, count); return ClientResolveUtil.read(kvDataEntries); } diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java index 56127820..d13fa436 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java @@ -504,13 +504,13 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService */ @HttpAction(method=HttpMethod.POST, path="ledgers/{ledgerHash}/accounts/{address}/entries") @Override - KVDataEntry[] getDataEntries(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, + TypedKVEntry[] getDataEntries(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, @PathParam(name="address") String address, @RequestParam(name="keys", array = true) String... keys); @HttpAction(method=HttpMethod.POST, path="ledgers/{ledgerHash}/accounts/{address}/entries-version") @Override - KVDataEntry[] getDataEntries(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, + TypedKVEntry[] getDataEntries(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, @PathParam(name="address") String address, @RequestBody KVInfoVO kvInfoVO); @@ -531,7 +531,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService */ @HttpAction(method = HttpMethod.POST, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") @Override - KVDataEntry[] getDataEntries(@PathParam(name = "ledgerHash") HashDigest ledgerHash, + TypedKVEntry[] getDataEntries(@PathParam(name = "ledgerHash") HashDigest ledgerHash, @PathParam(name = "address") String address, @RequestParam(name = "fromIndex", required = false) int fromIndex, @RequestParam(name = "count", required = false) int count); 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 d662378d..1782d985 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 @@ -9,8 +9,8 @@ import com.jd.blockchain.contract.ContractException; import com.jd.blockchain.contract.EventProcessingAware; 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.ledger.TypedKVEntry; +import com.jd.blockchain.ledger.TypedKVData; import com.jd.blockchain.utils.Bytes; /** @@ -47,16 +47,16 @@ public class AssetContractImpl implements EventProcessingAware, AssetContract { } // 查询当前值; - KVDataEntry[] kvEntries = eventContext.getLedger().getDataEntries(currentLedgerHash(), ASSET_ADDRESS, KEY_TOTAL, + TypedKVEntry[] kvEntries = eventContext.getLedger().getDataEntries(currentLedgerHash(), ASSET_ADDRESS, KEY_TOTAL, assetHolderAddress); // 计算资产的发行总数; - KVDataObject currTotal = (KVDataObject) kvEntries[0]; + TypedKVData currTotal = (TypedKVData) kvEntries[0]; long newTotal = currTotal.longValue() + amount; eventContext.getLedger().dataAccount(ASSET_ADDRESS).setInt64(KEY_TOTAL, newTotal, currTotal.getVersion()); // 分配到持有者账户; - KVDataObject holderAmount = (KVDataObject) kvEntries[1]; + TypedKVData holderAmount = (TypedKVData) kvEntries[1]; long newHodlerAmount = holderAmount.longValue() + amount; eventContext.getLedger().dataAccount(ASSET_ADDRESS) .setInt64(assetHolderAddress, newHodlerAmount, holderAmount.getVersion()).setText("K2", "info2", -1) @@ -77,10 +77,10 @@ public class AssetContractImpl implements EventProcessingAware, AssetContract { checkSignerPermission(fromAddress); // 查询现有的余额; - KVDataEntry[] origBalances = eventContext.getLedger().getDataEntries(currentLedgerHash(), ASSET_ADDRESS, + TypedKVEntry[] origBalances = eventContext.getLedger().getDataEntries(currentLedgerHash(), ASSET_ADDRESS, fromAddress, toAddress); - KVDataEntry fromBalanceKV = origBalances[0]; - KVDataEntry toBalanceKV = origBalances[1]; + TypedKVEntry fromBalanceKV = origBalances[0]; + TypedKVEntry toBalanceKV = origBalances[1]; long fromBalance = fromBalanceKV.getVersion() == -1 ? 0 : (long) fromBalanceKV.getValue(); long toBalance = toBalanceKV.getVersion() == -1 ? 0 : (long) toBalanceKV.getValue(); diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Query.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Query.java index 3205fd73..a3e44d95 100644 --- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Query.java +++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Query.java @@ -4,7 +4,7 @@ import com.jd.blockchain.crypto.Crypto; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerTransaction; import com.jd.blockchain.ledger.Transaction; @@ -67,7 +67,7 @@ public class SDKDemo_Query { // 获取数据; String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; String[] objKeys = new String[] { "x001", "x002" }; - KVDataEntry[] kvData = service.getDataEntries(LEDGER_HASH, commerceAccount, objKeys); + TypedKVEntry[] kvData = service.getDataEntries(LEDGER_HASH, commerceAccount, objKeys); long payloadVersion = kvData[0].getVersion(); diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java index 9d43b199..caae0d6d 100644 --- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java +++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java @@ -6,7 +6,7 @@ import static com.jd.blockchain.transaction.ContractReturnValue.decode; import com.jd.blockchain.contract.TransferContract; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.PreparedTransaction; import com.jd.blockchain.ledger.TransactionResponse; import com.jd.blockchain.ledger.TransactionTemplate; @@ -106,11 +106,11 @@ public class SDK_Contract_Demo extends SDK_Base_Demo { } private long readByKvOperation(String address, String account) { - KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, address, account); + TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, address, account); if (kvDataEntries == null || kvDataEntries.length == 0) { throw new IllegalStateException(String.format("Ledger %s Service inner Error !!!", ledgerHash.toBase58())); } - KVDataEntry kvDataEntry = kvDataEntries[0]; + TypedKVEntry kvDataEntry = kvDataEntries[0]; if (kvDataEntry.getVersion() == -1) { return 0L; } diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Random_Demo.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Random_Demo.java index c73a7f91..868f3269 100644 --- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Random_Demo.java +++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Random_Demo.java @@ -79,11 +79,11 @@ public class SDK_Contract_Random_Demo extends SDK_Base_Demo { } private long readByKvOperation(String address, String account) { - KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, address, account); + TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, address, account); if (kvDataEntries == null || kvDataEntries.length == 0) { throw new IllegalStateException(String.format("Ledger %s Service inner Error !!!", ledgerHash.toBase58())); } - KVDataEntry kvDataEntry = kvDataEntries[0]; + TypedKVEntry kvDataEntry = kvDataEntries[0]; if (kvDataEntry.getVersion() == -1) { return 0L; } diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_InsertData_Demo.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_InsertData_Demo.java index 3a89c7a6..d90b5233 100644 --- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_InsertData_Demo.java +++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_InsertData_Demo.java @@ -107,9 +107,9 @@ public class SDK_InsertData_Demo extends SDK_Base_Demo { // KVDataEntry[] kvData = blockchainService.getDataEntries(ledgerHash, commerceAccount, objKeys); // 获取数据账户下所有的KV列表 - KVDataEntry[] kvData = blockchainService.getDataEntries(ledgerHash, commerceAccount, 0, 100); + TypedKVEntry[] kvData = blockchainService.getDataEntries(ledgerHash, commerceAccount, 0, 100); if (kvData != null && kvData.length > 0) { - for (KVDataEntry kvDatum : kvData) { + for (TypedKVEntry kvDatum : kvData) { System.out.println("kvData.key=" + kvDatum.getKey()); System.out.println("kvData.version=" + kvDatum.getVersion()); System.out.println("kvData.type=" + kvDatum.getType()); diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java index 346aae79..3d291811 100644 --- a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java +++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_GateWay_Query_Test_.java @@ -24,7 +24,7 @@ import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.DigitalSignature; import com.jd.blockchain.ledger.EndpointRequest; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInfo; import com.jd.blockchain.ledger.LedgerTransaction; @@ -149,8 +149,8 @@ public class SDK_GateWay_Query_Test_ { String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; String[] objKeys = new String[] { "x001", "x002" }; - KVDataEntry[] kvData = service.getDataEntries(ledgerHash, commerceAccount, objKeys); - for (KVDataEntry kvDatum : kvData) { + TypedKVEntry[] kvData = service.getDataEntries(ledgerHash, commerceAccount, objKeys); + for (TypedKVEntry kvDatum : kvData) { System.out.println("kvData.key=" + kvDatum.getKey()); System.out.println("kvData.version=" + kvDatum.getVersion()); System.out.println("kvData.value=" + kvDatum.getValue()); 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 421dfd89..0ffcbb3e 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 @@ -26,7 +26,7 @@ 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.TypedKVEntry; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInfo; import com.jd.blockchain.ledger.LedgerInitProperties; @@ -216,8 +216,8 @@ public class IntegrationTest { ledgerOfNode0.retrieveLatestBlock(); // 更新内存 // 先验证应答 - KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, dataAccountAddress, dataKey); - for (KVDataEntry kvDataEntry : kvDataEntries) { + TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, dataAccountAddress, dataKey); + for (TypedKVEntry kvDataEntry : kvDataEntries) { String valHexText = (String) kvDataEntry.getValue(); byte[] valBytes = HexUtils.decode(valHexText); String valText = new String(valBytes); 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 9c3b3320..37c792f2 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 @@ -286,8 +286,8 @@ public class IntegrationBase { assertEquals(txResp.getContentHash(), transactionHash); assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); - KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, daAddress, dataKey); - for (KVDataEntry kvDataEntry : kvDataEntries) { + TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, daAddress, dataKey); + for (TypedKVEntry kvDataEntry : kvDataEntries) { assertEquals(dataKey, kvDataEntry.getKey()); String valHexText = (String) kvDataEntry.getValue(); assertEquals(dataVal, valHexText); 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 86b70840..6c8c762c 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 @@ -26,7 +26,7 @@ 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.TypedKVEntry; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInfo; import com.jd.blockchain.ledger.LedgerInitProperties; @@ -302,9 +302,9 @@ public class IntegrationTestAll4Redis { assertEquals(txResp.getContentHash(), prepTx.getHash()); assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); - KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, dataAccountAddress.toString(), + TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, dataAccountAddress.toString(), dataKey); - for (KVDataEntry kvDataEntry : kvDataEntries) { + for (TypedKVEntry kvDataEntry : kvDataEntries) { assertEquals(dataKey, kvDataEntry.getKey()); String valHexText = (String) kvDataEntry.getValue(); byte[] valBytes = HexUtils.decode(valHexText); 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 c6361d89..e029dc09 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 @@ -23,7 +23,7 @@ import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.DataAccountKVSetOperation; -import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.TypedKVEntry; import com.jd.blockchain.ledger.LedgerBlock; import com.jd.blockchain.ledger.LedgerInitProperties; import com.jd.blockchain.ledger.PreparedTransaction; @@ -214,7 +214,7 @@ public class IntegrationTestDataAccount { e.printStackTrace(); } - KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHashs[0], dataAddr.toBase58(), "A", "B", + TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHashs[0], dataAddr.toBase58(), "A", "B", "C", "D"); for (int i = 0; i < kvDataEntries.length; i++) { Object result = kvDataEntries[i].getValue(); diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java index 79773915..cea92cbc 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/ArrayUtils.java @@ -9,17 +9,29 @@ import java.util.*; */ public abstract class ArrayUtils { private ArrayUtils() { - + } - + + public static R[] castTo(T[] objs, Class clazz, CastFunction cf) { + if (objs == null) { + return null; + } + @SuppressWarnings("unchecked") + R[] array = (R[]) Array.newInstance(clazz, objs.length); + for (int i = 0; i < objs.length; i++) { + array[i] = cf.cast(objs[i]); + } + return array; + } + public static T[] singleton(T obj, Class clazz) { @SuppressWarnings("unchecked") T[] array = (T[]) Array.newInstance(clazz, 1); array[0] = obj; return array; } - - public static T[] toArray(Iterator itr, Class clazz){ + + public static T[] toArray(Iterator itr, Class clazz) { List lst = new LinkedList(); while (itr.hasNext()) { T t = (T) itr.next(); @@ -30,19 +42,19 @@ public abstract class ArrayUtils { lst.toArray(array); return array; } - - public static T[] toArray(Collection collection, Class clazz){ + + public static T[] toArray(Collection collection, Class clazz) { @SuppressWarnings("unchecked") T[] array = (T[]) Array.newInstance(clazz, collection.size()); collection.toArray(array); return array; } - - public static List asList(T[] array){ + + public static List asList(T[] array) { return asList(array, 0, array.length); } - - public static Set asSet(T[] array){ + + public static Set asSet(T[] array) { if (array == null || array.length == 0) { return Collections.emptySet(); } @@ -52,8 +64,8 @@ public abstract class ArrayUtils { } return set; } - - public static SortedSet asSortedSet(T[] array){ + + public static SortedSet asSortedSet(T[] array) { if (array == null || array.length == 0) { return Collections.emptySortedSet(); } @@ -63,12 +75,12 @@ public abstract class ArrayUtils { } return set; } - - public static List asList(T[] array, int fromIndex){ + + public static List asList(T[] array, int fromIndex) { return asList(array, fromIndex, array.length); } - - public static List asList(T[] array, int fromIndex, int toIndex){ + + public static List asList(T[] array, int fromIndex, int toIndex) { if (toIndex < fromIndex) { throw new IllegalArgumentException("The toIndex less than fromIndex!"); } @@ -78,10 +90,33 @@ public abstract class ArrayUtils { if (toIndex > array.length) { throw new IllegalArgumentException("The toIndex great than the length of array!"); } - + if (fromIndex == toIndex) { return Collections.emptyList(); } return new ReadonlyArrayListWrapper(array, fromIndex, toIndex); } + + public static interface CastFunction { + public R cast(T data); + } + + /** + * Reverse all elements of the specified array;
+ * + * @param + * @param array + */ + public static void reverse(T[] array) { + if (array == null || array.length < 2) { + return; + } + + T t; + for (int i = 0, j = array.length - 1; i < j; i++, j--) { + t = array[i]; + array[i] = array[j]; + array[j] = t; + } + } } diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java index 4548dbad..890748e5 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java @@ -1,7 +1,5 @@ package com.jd.blockchain.utils; -import java.io.File; - /** * * @author zhaogw diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataEntry.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataEntry.java index 6c538525..b02fa524 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataEntry.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataEntry.java @@ -1,7 +1,7 @@ package com.jd.blockchain.utils; /** - * 版本化的键值数据项; + * Versioning Key-Value data entry; * * @author huanghaiquan * diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataIterator.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataIterator.java new file mode 100644 index 00000000..13a8a0d0 --- /dev/null +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataIterator.java @@ -0,0 +1,21 @@ +package com.jd.blockchain.utils; + +/** + * 数据迭代器; + * + * @author huanghaiquan + * + * @param + * @param + */ +public interface DataIterator { + + void skip(long count); + + DataEntry next(); + + DataEntry[] next(int count); + + boolean hasNext(); + +} diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataTypeUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataTypeUtils.java deleted file mode 100644 index 05952868..00000000 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DataTypeUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.jd.blockchain.utils; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.util.TypeUtils; - -public abstract class DataTypeUtils { - - private static Map, Class> wrapperTypes = new HashMap, Class>(); - - static{ - wrapperTypes.put(long.class, Long.class); - wrapperTypes.put(int.class, Integer.class); - wrapperTypes.put(char.class, Character.class); - wrapperTypes.put(byte.class, Byte.class); - wrapperTypes.put(boolean.class, Boolean.class); - } - - public static boolean isAssignable(Type lhsType, Type rhsType) { - boolean assignable = TypeUtils.isAssignable(lhsType, rhsType); - if (assignable) { - return true; - } - if (lhsType instanceof Class) { - Class lhsClass = (Class) lhsType; - - } - - return false; - } - -} diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java index a84654c2..5cd2f2f3 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java @@ -1,7 +1,20 @@ package com.jd.blockchain.utils; +/** + * Key-Value data set; + * + * @author huanghaiquan + * + * @param + * @param + */ public interface Dataset { - + + /** + * Total count of data entries; + * + * @return + */ long getDataCount(); /** @@ -26,17 +39,6 @@ public interface Dataset { */ long setValue(K key, V value, long version); -// /** -// * Return the specified version's value;
-// * -// * If the key with the specified version doesn't exist, then return null;
-// * If the version is specified to -1, then return the latest version's value; -// * -// * @param key -// * @param version -// */ -// byte[] getValue(String key, long version); - /** * Return the specified version's value;
* @@ -48,47 +50,51 @@ public interface Dataset { */ V getValue(K key, long version); -// /** -// * Return the latest version's value; -// * -// * @param key -// * @return return null if not exist; -// */ -// byte[] getValue(String key); - /** - * Return the latest version's value; + * Return the value of the latest version; * * @param key * @return return null if not exist; */ V getValue(K key); -// /** -// * Return the latest version entry associated the specified key; If the key -// * doesn't exist, then return -1; -// * -// * @param key -// * @return -// */ -// long getVersion(String key); - /** - * Return the latest version entry associated the specified key; If the key - * doesn't exist, then return -1; + * Return the latest version number of the specified key; * * @param key - * @return + * @return The version number of the specified key; If the key doesn't exist, + * then return -1; */ long getVersion(K key); /** + * Return data entry * * @param key * @return Null if the key doesn't exist! */ DataEntry getDataEntry(K key); + /** + * + * @param key + * @param version + * @return + */ DataEntry getDataEntry(K key, long version); + /** + * Ascending iterator; + * + * @return + */ + DataIterator iterator(); + + /** + * Descending iterator; + * + * @return + */ + DataIterator iteratorDesc(); + } \ No newline at end of file diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java index de96f665..acbdce51 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/DatasetHelper.java @@ -1,8 +1,12 @@ package com.jd.blockchain.utils; +/** + * Helper for {@link Dataset}; + * + * @author huanghaiquan + * + */ public class DatasetHelper { - - public static final TypeMapper UTF8_STRING_BYTES_MAPPER = new TypeMapper() { @@ -29,7 +33,7 @@ public class DatasetHelper { return Bytes.fromString(t2); } }; - + /** * 适配两个不同类型参数的数据集; * @@ -121,8 +125,8 @@ public class DatasetHelper { T2 decode(T1 t1); } - - private static class EmptyMapper implements TypeMapper{ + + private static class EmptyMapper implements TypeMapper { @Override public T encode(T t) { @@ -133,7 +137,7 @@ public class DatasetHelper { public T decode(T t) { return t; } - + } private static class DatasetUpdatingMonitor implements Dataset { @@ -186,6 +190,16 @@ public class DatasetHelper { return dataset.getDataEntry(key, version); } + @Override + public DataIterator iterator() { + return dataset.iterator(); + } + + @Override + public DataIterator iteratorDesc() { + return dataset.iteratorDesc(); + } + } /** @@ -269,6 +283,73 @@ public class DatasetHelper { return new KeyValueEntry(key, v, entry.getVersion()); } + @Override + public DataIterator iterator() { + DataIterator it = dataset.iterator(); + return new DataIteratorAdapter(it, keyMapper, valueMapper); + } + + @Override + public DataIterator iteratorDesc() { + DataIterator it = dataset.iteratorDesc(); + return new DataIteratorAdapter(it, keyMapper, valueMapper); + } + + } + + private static class DataIteratorAdapter implements DataIterator { + + private DataIterator iterator; + + private TypeMapper keyMapper; + private TypeMapper valueMapper; + + public DataIteratorAdapter(DataIterator iterator, TypeMapper keyMapper, + TypeMapper valueMapper) { + this.iterator = iterator; + this.keyMapper = keyMapper; + this.valueMapper = valueMapper; + } + + @Override + public void skip(long count) { + iterator.skip(count); + } + + @Override + public DataEntry next() { + DataEntry entry = iterator.next(); + return cast(entry); + } + + private DataEntry cast(DataEntry entry) { + if (entry == null) { + return null; + } + + K2 k = keyMapper.decode(entry.getKey()); + V2 v = valueMapper.decode(entry.getValue()); + return new KeyValueEntry(k, v, entry.getVersion()); + } + + @SuppressWarnings("unchecked") + @Override + public DataEntry[] next(int count) { + DataEntry[] entries = iterator.next(count); + if (entries == null) { + return null; + } + if (entries.length == 0) { + return (DataEntry[]) entries; + } + return ArrayUtils.castTo(entries, DataEntry.class, e -> cast(e)); + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + } private static class KeyValueEntry implements DataEntry { From 4aedf9c4b576d064e4a2ceba549bf56fb2d5abcd Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Tue, 29 Oct 2019 00:24:19 +0800 Subject: [PATCH 8/9] Refactored MerkleAccountSet to prevent calls to Account with Transactional interface; --- .../ledger/core/AccountDecorator.java | 7 ++- .../ledger/core/CompositeAccount.java | 12 ++++ .../ledger/core/ContractAccount.java | 2 +- .../ledger/core/ContractAccountSet.java | 8 +-- .../blockchain/ledger/core/DataAccount.java | 10 +--- .../ledger/core/DataAccountSet.java | 6 +- .../blockchain/ledger/core/LedgerAccount.java | 13 ----- .../blockchain/ledger/core/MerkleAccount.java | 4 +- .../ledger/core/MerkleAccountSet.java | 25 +++++--- .../ledger/core/MerkleDataCluster.java | 2 - .../ledger/core/SecurityContext.java | 7 --- .../blockchain/ledger/core/UserAccount.java | 4 +- .../ledger/core/UserAccountSet.java | 6 +- .../ledger/core/AccountSetTest.java | 10 ++-- .../ledger/core/LedgerTestUtils.java | 10 +++- .../ledger/core/MerkleAccountSetTest.java | 58 +++++++++++++++++++ .../core/TransactionBatchProcessorTest.java | 1 + .../com/jd/blockchain/ledger/Account.java | 11 ++++ 18 files changed, 132 insertions(+), 64 deletions(-) create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CompositeAccount.java delete mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java create mode 100644 source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleAccountSetTest.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Account.java diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java index 8e30be95..399631ce 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java @@ -1,6 +1,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.Account; import com.jd.blockchain.ledger.BlockchainIdentity; import com.jd.blockchain.ledger.HashProof; import com.jd.blockchain.ledger.MerkleSnapshot; @@ -8,11 +9,11 @@ import com.jd.blockchain.ledger.TypedValue; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Dataset; -public class AccountDecorator implements LedgerAccount, HashProvable, MerkleSnapshot{ +public class AccountDecorator implements Account, HashProvable, MerkleSnapshot{ - private MerkleAccount mklAccount; + private CompositeAccount mklAccount; - public AccountDecorator(MerkleAccount mklAccount) { + public AccountDecorator(CompositeAccount mklAccount) { this.mklAccount = mklAccount; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CompositeAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CompositeAccount.java new file mode 100644 index 00000000..5630917e --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CompositeAccount.java @@ -0,0 +1,12 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.ledger.Account; +import com.jd.blockchain.ledger.MerkleSnapshot; +import com.jd.blockchain.ledger.TypedValue; +import com.jd.blockchain.utils.Dataset; + +public interface CompositeAccount extends Account, MerkleSnapshot, HashProvable{ + + Dataset getHeaders(); + +} 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 0d288d7b..19c76463 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 @@ -12,7 +12,7 @@ public class ContractAccount extends AccountDecorator implements ContractInfo { private static final String CHAIN_CODE_KEY = "CHAIN-CODE"; - public ContractAccount(MerkleAccount mklAccount) { + public ContractAccount(CompositeAccount mklAccount) { super(mklAccount); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java index 8d9fdbda..c4ee0408 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java @@ -67,7 +67,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { @Override public ContractAccount getAccount(Bytes address) { - MerkleAccount accBase = accountSet.getAccount(address); + CompositeAccount accBase = accountSet.getAccount(address); return new ContractAccount(accBase); } @@ -78,7 +78,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { @Override public ContractAccount getAccount(Bytes address, long version) { - MerkleAccount accBase = accountSet.getAccount(address, version); + CompositeAccount accBase = accountSet.getAccount(address, version); return new ContractAccount(accBase); } @@ -93,7 +93,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { */ public ContractAccount deploy(Bytes address, PubKey pubKey, DigitalSignature addressSignature, byte[] chaincode) { // TODO: 校验和记录合约地址签名; - MerkleAccount accBase = accountSet.register(address, pubKey); + CompositeAccount accBase = accountSet.register(address, pubKey); ContractAccount contractAcc = new ContractAccount(accBase); contractAcc.setChaincode(chaincode, -1); return contractAcc; @@ -108,7 +108,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { * @return 返回链码的新版本号; */ public long update(Bytes address, byte[] chaincode, long version) { - MerkleAccount accBase = accountSet.getAccount(address); + CompositeAccount accBase = accountSet.getAccount(address); ContractAccount contractAcc = new ContractAccount(accBase); return contractAcc.setChaincode(chaincode, version); } 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 58452dc2..4814cdf6 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 @@ -1,16 +1,8 @@ package com.jd.blockchain.ledger.core; -import com.jd.blockchain.binaryproto.BinaryProtocol; -import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.TypedKVEntry; -import com.jd.blockchain.ledger.TypedKVData; -import com.jd.blockchain.ledger.MerkleProof; -import com.jd.blockchain.ledger.TypedValue; -import com.jd.blockchain.utils.Bytes; - public class DataAccount extends AccountDecorator { - public DataAccount(MerkleAccount mklAccount) { + public DataAccount(CompositeAccount mklAccount) { super(mklAccount); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java index e1c5caf3..0f849c1d 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java @@ -65,7 +65,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { public DataAccount register(Bytes address, PubKey pubKey, DigitalSignature addressSignature) { // TODO: 未实现对地址签名的校验和记录; - MerkleAccount accBase = accountSet.register(address, pubKey); + CompositeAccount accBase = accountSet.register(address, pubKey); return new DataAccount(accBase); } @@ -83,7 +83,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { */ @Override public DataAccount getAccount(Bytes address) { - MerkleAccount accBase = accountSet.getAccount(address); + CompositeAccount accBase = accountSet.getAccount(address); if (accBase == null) { return null; } @@ -92,7 +92,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { @Override public DataAccount getAccount(Bytes address, long version) { - MerkleAccount accBase = accountSet.getAccount(address, version); + CompositeAccount accBase = accountSet.getAccount(address, version); return new DataAccount(accBase); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java deleted file mode 100644 index f57777ed..00000000 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.jd.blockchain.ledger.core; - -import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.TypedValue; -import com.jd.blockchain.utils.Dataset; - -public interface LedgerAccount { - - BlockchainIdentity getID(); - - Dataset getDataset(); - -} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java index 6b59dacc..dc0169a5 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java @@ -26,7 +26,7 @@ import com.jd.blockchain.utils.Transactional; * @author huanghaiquan * */ -public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapshot, Transactional { +public class MerkleAccount implements CompositeAccount, HashProvable, MerkleSnapshot, Transactional { private static final Bytes HEADER_PREFIX = Bytes.fromString("HD/"); private static final Bytes DATA_PREFIX = Bytes.fromString("DT/"); @@ -179,7 +179,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho return accountID; } - protected Dataset getHeaders() { + public Dataset getHeaders() { return typedHeader; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java index 3cc65cb7..8f46e235 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java @@ -20,7 +20,7 @@ import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.DataEntry; import com.jd.blockchain.utils.Transactional; -public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery { +public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery { static { DataContractRegistry.register(MerkleSnapshot.class); @@ -111,7 +111,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ } @Override - public MerkleAccount getAccount(String address) { + public CompositeAccount getAccount(String address) { return getAccount(Bytes.fromBase58(address)); } @@ -122,7 +122,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * @return */ @Override - public MerkleAccount getAccount(Bytes address) { + public CompositeAccount getAccount(Bytes address) { return this.getAccount(address, -1); } @@ -174,7 +174,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * @param version 账户版本;如果指定为 -1,则返回最新版本; * @return */ - public MerkleAccount getAccount(Bytes address, long version) { + public CompositeAccount getAccount(Bytes address, long version) { version = version < 0 ? -1 : version; InnerMerkleAccount acc = latestAccountsCache.get(address); if (acc != null && version == -1) { @@ -206,9 +206,10 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ // Now, be sure that "acc == null", so get account from storage; // Set readonly for the old version account; boolean readonly = (version > -1 && version < latestVersion) || isReadonly(); - + + long qVersion = version == -1 ? latestVersion : version; // load account from storage; - acc = loadAccount(address, readonly, version); + acc = loadAccount(address, readonly, qVersion); if (acc == null) { return null; } @@ -220,7 +221,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ return acc; } - public MerkleAccount register(Bytes address, PubKey pubKey) { + public CompositeAccount register(Bytes address, PubKey pubKey) { return register(new BlockchainIdentityData(address, pubKey)); } @@ -235,7 +236,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ * @param pubKey 公钥; * @return 注册成功的账户对象; */ - public MerkleAccount register(BlockchainIdentity accountId) { + public CompositeAccount register(BlockchainIdentity accountId) { if (isReadonly()) { throw new IllegalArgumentException("This AccountSet is readonly!"); } @@ -281,6 +282,14 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ return new InnerMerkleAccount(header, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage); } + /** + * 加载指定版本的账户; + * + * @param address 账户地址; + * @param readonly 是否只读; + * @param version 账户的版本;大于等于 0 ; + * @return + */ private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) { byte[] rootHashBytes = merkleDataset.getValue(address, version); if (rootHashBytes == null) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java index 5865c3fd..41339c58 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java @@ -4,13 +4,11 @@ import java.util.Map; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.CryptoSetting; -import com.jd.blockchain.ledger.MerkleProof; import com.jd.blockchain.ledger.MerkleSnapshot; import com.jd.blockchain.storage.service.ExPolicyKVStorage; import com.jd.blockchain.storage.service.VersioningKVStorage; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; -import com.jd.blockchain.utils.Dataset; public class MerkleDataCluster implements Transactional, MerkleSnapshot { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SecurityContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SecurityContext.java index d3ad83ba..2fde0054 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SecurityContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SecurityContext.java @@ -1,12 +1,5 @@ package com.jd.blockchain.ledger.core; -import java.util.Set; - -import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.LedgerPermission; -import com.jd.blockchain.ledger.LedgerSecurityException; -import com.jd.blockchain.ledger.TransactionPermission; - public class SecurityContext { private static ThreadLocal policyHolder = new ThreadLocal(); 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 1ac4b4fe..87696e86 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 @@ -19,8 +19,8 @@ public class UserAccount extends AccountDecorator implements UserInfo { // imple private static final String DATA_PUB_KEY = "DATA-PUBKEY"; - public UserAccount(MerkleAccount mklAccount) { - super(mklAccount); + public UserAccount(CompositeAccount baseAccount) { + super(baseAccount); } private PubKey dataPubKey; 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 24958c77..bc71711d 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 @@ -72,7 +72,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { @Override public UserAccount getAccount(Bytes address) { - MerkleAccount baseAccount = accountSet.getAccount(address); + CompositeAccount baseAccount = accountSet.getAccount(address); return new UserAccount(baseAccount); } @@ -83,7 +83,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { @Override public UserAccount getAccount(Bytes address, long version) { - MerkleAccount baseAccount = accountSet.getAccount(address, version); + CompositeAccount baseAccount = accountSet.getAccount(address, version); return new UserAccount(baseAccount); } @@ -99,7 +99,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { * @return 注册成功的用户对象; */ public UserAccount register(Bytes address, PubKey pubKey) { - MerkleAccount baseAccount = accountSet.register(address, pubKey); + CompositeAccount baseAccount = accountSet.register(address, pubKey); return new UserAccount(baseAccount); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java index 64f99a23..99bd2076 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java @@ -14,8 +14,8 @@ import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; import com.jd.blockchain.crypto.service.sm.SMCryptoService; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.core.CompositeAccount; import com.jd.blockchain.ledger.core.CryptoConfig; -import com.jd.blockchain.ledger.core.MerkleAccount; import com.jd.blockchain.ledger.core.MerkleAccountSet; import com.jd.blockchain.ledger.core.OpeningAccessPolicy; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; @@ -50,7 +50,7 @@ public class AccountSetTest { accset.register(userKey.getAddress(), userKey.getPubKey()); //尚未提交之前,可以检索到账户的存在,但版本仍然标记为 -1; - MerkleAccount userAcc = accset.getAccount(userKey.getAddress()); + CompositeAccount userAcc = accset.getAccount(userKey.getAddress()); assertNotNull(userAcc); assertTrue(accset.contains(userKey.getAddress())); @@ -59,12 +59,12 @@ public class AccountSetTest { assertNotNull(rootHash); MerkleAccountSet reloadAccSet = new MerkleAccountSet(rootHash, cryptoConf, Bytes.fromString(keyPrefix), storage, storage, true, accessPolicy); - MerkleAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress()); + CompositeAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress()); assertNotNull(reloadUserAcc); assertTrue(reloadAccSet.contains(userKey.getAddress())); - assertEquals(userAcc.getAddress(), reloadUserAcc.getAddress()); - assertEquals(userAcc.getPubKey(), reloadUserAcc.getPubKey()); + assertEquals(userAcc.getID().getAddress(), reloadUserAcc.getID().getAddress()); + assertEquals(userAcc.getID().getPubKey(), reloadUserAcc.getID().getPubKey()); } } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerTestUtils.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerTestUtils.java index d3595755..a9c8a683 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerTestUtils.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerTestUtils.java @@ -44,12 +44,18 @@ public class LedgerTestUtils { partiKeys[1] = BlockchainKeyGenerator.getInstance().generate(); return createLedgerInitSetting(partiKeys); } - - public static LedgerInitSetting createLedgerInitSetting(BlockchainKeypair[] partiKeys) { + + public static CryptoProvider[] getContextProviders() { CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); } + + return supportedProviders; + } + + public static LedgerInitSetting createLedgerInitSetting(BlockchainKeypair[] partiKeys) { + CryptoProvider[] supportedProviders =getContextProviders(); CryptoConfig defCryptoSetting = new CryptoConfig(); defCryptoSetting.setSupportedProviders(supportedProviders); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleAccountSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleAccountSetTest.java new file mode 100644 index 00000000..f3bb67da --- /dev/null +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleAccountSetTest.java @@ -0,0 +1,58 @@ +package test.com.jd.blockchain.ledger.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.ledger.BlockchainKeyGenerator; +import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.TypedValue; +import com.jd.blockchain.ledger.core.CompositeAccount; +import com.jd.blockchain.ledger.core.CryptoConfig; +import com.jd.blockchain.ledger.core.MerkleAccountSet; +import com.jd.blockchain.ledger.core.OpeningAccessPolicy; +import com.jd.blockchain.storage.service.utils.MemoryKVStorage; +import com.jd.blockchain.utils.Bytes; + +public class MerkleAccountSetTest { + + @Test + public void testRegister() { + final OpeningAccessPolicy POLICY = new OpeningAccessPolicy(); + + final MemoryKVStorage STORAGE = new MemoryKVStorage(); + + Bytes KEY_PREFIX = Bytes.fromString("/ACCOUNT"); + + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setSupportedProviders(LedgerTestUtils.getContextProviders()); + cryptoConfig.setAutoVerifyHash(true); + cryptoConfig.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); + + MerkleAccountSet accountset = new MerkleAccountSet(cryptoConfig, KEY_PREFIX, STORAGE, STORAGE, POLICY); + + BlockchainKeypair key1 = BlockchainKeyGenerator.getInstance().generate(); + accountset.register(key1.getIdentity()); + + accountset.commit(); + + CompositeAccount acc1 = accountset.getAccount(key1.getAddress()); + assertNotNull(acc1); + assertEquals(0, accountset.getVersion(key1.getAddress())); + + acc1.getDataset().setValue("K1", TypedValue.fromText("V0"), -1); + + TypedValue v1 = acc1.getDataset().getValue("K1"); + assertNotNull(v1); + assertEquals(0, acc1.getDataset().getVersion("K1")); + + accountset.commit(); + + v1 = acc1.getDataset().getValue("K1"); + assertNotNull(v1); + assertEquals(0, acc1.getDataset().getVersion("K1")); + } + +} diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java index a9f09845..3d7f179b 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java @@ -340,6 +340,7 @@ public class TransactionBatchProcessorTest { 0); BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K3", 0); + assertNotNull(v1_0); assertNotNull(v1_1); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Account.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Account.java new file mode 100644 index 00000000..28694160 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Account.java @@ -0,0 +1,11 @@ +package com.jd.blockchain.ledger; + +import com.jd.blockchain.utils.Dataset; + +public interface Account { + + BlockchainIdentity getID(); + + Dataset getDataset(); + +} From 4c5c61e7641687a5a8d61d5e34d55db0a28eb6ea Mon Sep 17 00:00:00 2001 From: huanghaiquan Date: Tue, 29 Oct 2019 00:39:40 +0800 Subject: [PATCH 9/9] Fixed errors of test cases; --- .../ledger/core/ContractInvokingTest.java | 19 ++++++++++--------- .../java/com/jd/blockchain/utils/Dataset.java | 5 +++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java index 14e29d65..de1d224f 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/ContractInvokingTest.java @@ -307,8 +307,8 @@ public class ContractInvokingTest { 0); assertEquals(0, kv1.getVersion()); assertEquals(0, kv2.getVersion()); - assertEquals("V1-0", kv1.getValue()); - assertEquals("V2-0", kv2.getValue()); + assertEquals("V1-0", kv1.getValue().stringValue()); + assertEquals("V2-0", kv2.getValue().stringValue()); // 构建基于接口调用合约的交易请求,用于测试合约调用; buildBlock(ledgerRepo, ledgerManager, opReg, new TxDefinitor() { @@ -326,8 +326,8 @@ public class ContractInvokingTest { kv2 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K2", 1); assertEquals(1, kv1.getVersion()); assertEquals(1, kv2.getVersion()); - assertEquals("V1-1", kv1.getValue()); - assertEquals("V2-1", kv2.getValue()); + assertEquals("V1-1", kv1.getValue().stringValue()); + assertEquals("V2-1", kv2.getValue().stringValue()); // 构建基于接口调用合约的交易请求,用于测试合约调用; buildBlock(ledgerRepo, ledgerManager, opReg, new TxDefinitor() { @@ -337,16 +337,17 @@ public class ContractInvokingTest { contractProxy.testRollbackWhileVersionConfliction(kpDataAccount.getAddress().toBase58(), "K1", "V1-2", 1); contractProxy.testRollbackWhileVersionConfliction(kpDataAccount.getAddress().toBase58(), "K2", "V2-2", - 0); + 0);//预期会回滚; } }); - // 预期数据都能够正常写入; + // 预期数据回滚,账本没有发生变更; kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", 1); assertEquals(1, kv1.getVersion()); - assertEquals("V1-1", kv1.getValue()); + assertEquals("V1-1", kv1.getValue().stringValue()); kv1 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K1", 2); - assertEquals(-1, kv1.getVersion()); - assertEquals(null, kv1.getValue()); + assertNull(kv1); + kv2 = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getDataEntry("K2", 1); + assertEquals(1, kv2.getVersion()); } diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java index 5cd2f2f3..2a82bd19 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/Dataset.java @@ -68,7 +68,7 @@ public interface Dataset { long getVersion(K key); /** - * Return data entry + * Return the data entry with the specified key; * * @param key * @return Null if the key doesn't exist! @@ -76,10 +76,11 @@ public interface Dataset { DataEntry getDataEntry(K key); /** + * Return the data entry with the specified key and version; * * @param key * @param version - * @return + * @return Null if the key doesn't exist! */ DataEntry getDataEntry(K key, long version);