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 f27c5258..d936c788 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 @@ -67,6 +67,7 @@ public interface DataCodes { // contract types of metadata; public static final int METADATA = 0x600; + public static final int METADATA_V2 = 0x601; public static final int METADATA_INIT_SETTING = 0x610; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java index d1522ea5..e120525c 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java @@ -25,6 +25,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { static { DataContractRegistry.register(LedgerMetadata.class); + DataContractRegistry.register(LedgerMetadata_V2.class); } private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminAccount.class); @@ -40,7 +41,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { private final Bytes rolePrivilegePrefix; private final Bytes userRolePrefix; - private LedgerMetadata origMetadata; + private LedgerMetadata_V2 origMetadata; private LedgerMetadataImpl metadata; @@ -225,7 +226,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { return BinaryProtocol.encode(setting, LedgerSettings.class); } - private LedgerMetadata loadAndVerifyMetadata(HashDigest adminAccountHash) { + private LedgerMetadata_V2 loadAndVerifyMetadata(HashDigest adminAccountHash) { Bytes key = encodeMetadataKey(adminAccountHash); byte[] bytes = storage.get(key); HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm()); @@ -253,7 +254,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { * @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata() */ @Override - public LedgerMetadata getMetadata() { + public LedgerMetadata_V2 getMetadata() { return metadata; } @@ -325,7 +326,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { @Override public boolean isUpdated() { - return updated || participants.isUpdated(); + return updated || participants.isUpdated() || rolePrivileges.isUpdated() || userRoles.isUpdated(); } @Override @@ -392,12 +393,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { updated = false; } - private LedgerMetadata deserializeMetadata(byte[] bytes) { + private LedgerMetadata_V2 deserializeMetadata(byte[] bytes) { return BinaryProtocol.decode(bytes); } private byte[] serializeMetadata(LedgerMetadataImpl config) { - return BinaryProtocol.encode(config, LedgerMetadata.class); + return BinaryProtocol.encode(config, LedgerMetadata_V2.class); } @Override @@ -426,11 +427,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { public LedgerMetadataImpl() { } - public LedgerMetadataImpl(LedgerMetadata metadata) { + public LedgerMetadataImpl(LedgerMetadata_V2 metadata) { this.seed = metadata.getSeed(); -// this.setting = metadata.getSetting(); this.participantsHash = metadata.getParticipantsHash(); this.settingsHash = metadata.getSettingsHash(); + this.rolePrivilegesHash = metadata.getRolePrivilegesHash(); + this.userRolesHash = metadata.getUserRolesHash(); } @Override diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java index 2a5cec59..04111ef6 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java @@ -15,10 +15,10 @@ import com.jd.blockchain.consts.DataCodes; public enum LedgerPermission { /** - * 设置角色权限;
+ * 授权角色权限;
* 包括:创建角色、设置角色的权限代码、分配用户角色; */ - SET_ROLE_PERMISSION((byte) 0x01), + AUTHORIZE_ROLES((byte) 0x01), /** * 设置共识协议;
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 d17d219f..30846867 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 @@ -8,6 +8,7 @@ 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.io.BytesUtils; @@ -62,12 +63,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { /** * 创建一个新的 MerkleDataSet; * - * @param setting - * 密码设置; - * @param exPolicyStorage - * 默克尔树的存储; - * @param versioningStorage - * 数据的存储; + * @param setting 密码设置; + * @param exPolicyStorage 默克尔树的存储; + * @param versioningStorage 数据的存储; */ public MerkleDataSet(CryptoSetting setting, String keyPrefix, ExPolicyKVStorage exPolicyStorage, VersioningKVStorage versioningStorage) { @@ -149,7 +147,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable { } return values; } - + 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 + "]!"); @@ -158,16 +156,19 @@ public class MerkleDataSet implements Transactional, MerkleProvable { throw new IllegalArgumentException("Index out of bound!"); } 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()); - values[i] = valueStorage.getEntry(dataKey, dataNode.getVersion()); + bytesValue = valueStorage.get(dataKey, dataNode.getVersion()); + values[i] = new VersioningKVData(dataNode.getKey(), dataNode.getVersion(), bytesValue); } return values; } /** * get the data at the specific index; + * * @param fromIndex * @return */ @@ -179,15 +180,15 @@ public class MerkleDataSet implements Transactional, MerkleProvable { /** * get the key at the specific index; + * * @param fromIndex * @return */ public String getKeyAtIndex(int fromIndex) { MerkleDataNode dataNode = merkleTree.getData(fromIndex); - return new String(dataNode.getKey().toBytes()); + return new String(dataNode.getKey().toBytes()); } - /** * Create or update the value associated the specified key if the version * checking is passed.
@@ -199,12 +200,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { * 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. + * @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;
@@ -226,12 +224,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { * 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. + * @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;
@@ -430,7 +425,12 @@ public class MerkleDataSet implements Transactional, MerkleProvable { if (latestVersion < 0) { return null; } - return valueStorage.getEntry(key, latestVersion); + Bytes dataKey = encodeDataKey(key); + byte[] value = valueStorage.get(dataKey, latestVersion); + if (value == null) { + return null; + } + return new VersioningKVData(key, latestVersion, value); } public VersioningKVEntry getDataEntry(Bytes key, long version) { @@ -441,7 +441,12 @@ public class MerkleDataSet implements Transactional, MerkleProvable { return null; } version = version < 0 ? latestVersion : version; - return valueStorage.getEntry(key, version); + Bytes dataKey = encodeDataKey(key); + byte[] value = valueStorage.get(dataKey, version); + if (value == null) { + return null; + } + return new VersioningKVData(key, version, value); } public MerkleDataEntry getMerkleEntry(Bytes key, long version) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java index 05fd0611..82d066e2 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java @@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.ParticipantNode; +import com.jd.blockchain.utils.Bytes; /** * 参与方证书数据对象; @@ -12,7 +13,7 @@ import com.jd.blockchain.ledger.ParticipantNode; public class ParticipantCertData implements ParticipantNode { private int id; - private String address; + private Bytes address; private String name; private PubKey pubKey; @@ -26,14 +27,14 @@ public class ParticipantCertData implements ParticipantNode { this.pubKey = participantNode.getPubKey(); } - public ParticipantCertData(String address, String name, PubKey pubKey) { + public ParticipantCertData(Bytes address, String name, PubKey pubKey) { this.address = address; this.name = name; this.pubKey = pubKey; } @Override - public String getAddress() { + public Bytes getAddress() { return address; } 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 bd84185d..9c015a6f 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 @@ -73,9 +73,8 @@ public class ParticipantDataSet implements Transactional, MerkleProvable { } } - private Bytes encodeKey(String address) { - // return id + ""; - return Bytes.fromString(address); + private Bytes encodeKey(Bytes address) { + return address; } /** @@ -87,7 +86,7 @@ public class ParticipantDataSet implements Transactional, MerkleProvable { * @param address * @return */ - public ParticipantNode getParticipant(String address) { + public ParticipantNode getParticipant(Bytes address) { Bytes key = encodeKey(address); byte[] bytes = dataset.getValue(key); if (bytes == null) { @@ -95,11 +94,11 @@ public class ParticipantDataSet implements Transactional, MerkleProvable { } return BinaryProtocol.decode(bytes); } - + public ParticipantNode[] getParticipants() { - byte[][] bytes = dataset.getLatestValues(0, (int)dataset.getDataCount()); + byte[][] bytes = dataset.getLatestValues(0, (int) dataset.getDataCount()); ParticipantNode[] pns = new ParticipantNode[bytes.length]; - + for (int i = 0; i < pns.length; i++) { pns[i] = BinaryProtocol.decode(bytes[i]); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java index aa22efd2..ca4b2914 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java @@ -17,7 +17,7 @@ public interface PrivilegeSet { @DataField(order = 1, primitiveType = PrimitiveType.BYTES) LedgerPrivilege getLedgerPrivilege(); - @DataField(order = 1, primitiveType = PrimitiveType.BYTES) + @DataField(order = 2, primitiveType = PrimitiveType.BYTES) TransactionPrivilege getTransactionPrivilege(); } 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 327a4d3f..e221bb06 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 @@ -12,11 +12,6 @@ import com.jd.blockchain.utils.Transactional; public class RolePrivilegeDataSet implements Transactional, MerkleProvable, RolePrivilegeSettings { - /** - * 角色名称的最大 Unicode 字符数; - */ - public static final int MAX_ROLE_NAME_LENGTH = 20; - private MerkleDataSet dataset; public RolePrivilegeDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, @@ -60,22 +55,30 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role } /** - * 加入新的角色授权;
- * - * 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; - * - * @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符; - * @param ledgerPrivilege - * @param txPrivilege + * */ @Override - public void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) { - RolePrivileges roleAuth = new RolePrivileges(roleName, -1, ledgerPrivilege, - txPrivilege); + public long addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) { + RolePrivileges roleAuth = new RolePrivileges(roleName, -1, ledgerPrivilege, txPrivilege); long nv = setRolePrivilege(roleAuth); if (nv < 0) { throw new LedgerException("Role[" + roleName + "] already exist!"); } + return nv; + } + + @Override + public long addRolePrivilege(String roleName, LedgerPermission[] ledgerPermissions, + TransactionPermission[] txPermissions) { + LedgerPrivilege ledgerPrivilege = new LedgerPrivilege(); + for (LedgerPermission lp : ledgerPermissions) { + ledgerPrivilege.enable(lp); + } + TransactionPrivilege txPrivilege = new TransactionPrivilege(); + for (TransactionPermission tp : txPermissions) { + txPrivilege.enable(tp); + } + return addRolePrivilege(roleName, ledgerPrivilege, txPrivilege); } /** @@ -144,7 +147,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role roleAuth.getTransactionPrivilege().enable(permissions); return setRolePrivilege(roleAuth); } - + /** * 禁止角色指定的权限;
* 如果角色不存在,则返回 -1; @@ -162,7 +165,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role roleAuth.getLedgerPrivilege().disable(permissions); return setRolePrivilege(roleAuth); } - + /** * 禁止角色指定的权限;
* 如果角色不存在,则返回 -1; @@ -248,7 +251,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role PrivilegeSet privilege = BinaryProtocol.decode(kv.getValue()); return new RolePrivileges(roleName, kv.getVersion(), privilege); } - + @Override public RolePrivileges[] getRolePrivileges(int index, int count) { VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); @@ -256,8 +259,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role PrivilegeSet privilege; for (int i = 0; i < pns.length; i++) { privilege = BinaryProtocol.decode(kvEntries[i].getValue()); - pns[i] = new RolePrivileges(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), - privilege); + pns[i] = new RolePrivileges(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), privilege); } return pns; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java index d900e002..47cdca37 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java @@ -3,6 +3,11 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.ledger.LedgerException; public interface RolePrivilegeSettings { + + /** + * 角色名称的最大 Unicode 字符数; + */ + public static final int MAX_ROLE_NAME_LENGTH = 20; long getRoleCount(); @@ -15,7 +20,20 @@ public interface RolePrivilegeSettings { * @param ledgerPrivilege * @param txPrivilege */ - void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); + long addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); + + /** + * 加入新的角色授权;
+ * + * 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; + * + * @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode + * 字符; + * @param ledgerPermissions 给角色授予的账本权限列表; + * @param txPermissions 给角色授予的交易权限列表; + * @return + */ + long addRolePrivilege(String roleName, LedgerPermission[] ledgerPermissions, TransactionPermission[] txPermissions); /** * 更新角色授权;
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 36b6b633..9fd9b834 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 @@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core; import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.ledger.AuthorizationException; import com.jd.blockchain.ledger.CryptoSetting; import com.jd.blockchain.ledger.LedgerException; import com.jd.blockchain.storage.service.ExPolicyKVStorage; @@ -11,12 +12,7 @@ import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Transactional; public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleSettings { - - /** - * 角色名称的最大 Unicode 字符数; - */ - public static final int MAX_ROLE_NAME_LENGTH = 20; - + private MerkleDataSet dataset; public UserRoleDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, @@ -55,7 +51,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS } @Override - public long getRoleCount() { + public long getUserCount() { return dataset.getDataCount(); } @@ -74,7 +70,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS roleAuth.addRoles(roles); long nv = setUserRolesAuthorization(roleAuth); if (nv < 0) { - throw new LedgerException("Roles authorization of User[" + userAddress + "] already exists!"); + throw new AuthorizationException("Roles authorization of User[" + userAddress + "] already exists!"); } } @@ -86,6 +82,9 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS * @return */ private long setUserRolesAuthorization(UserRoles userRoles) { + if (userRoles.getRoleCount() > MAX_ROLES_PER_USER) { + throw new AuthorizationException("The number of roles exceeds the maximum range!"); + } byte[] rolesetBytes = BinaryProtocol.encode(userRoles, RoleSet.class); return dataset.setValue(userRoles.getUserAddress(), rolesetBytes, userRoles.getVersion()); } @@ -100,7 +99,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS public void updateUserRoles(UserRoles userRoles) { long nv = setUserRolesAuthorization(userRoles); if (nv < 0) { - throw new LedgerException("Update to roles of user[" + userRoles.getUserAddress() + throw new AuthorizationException("Update to roles of user[" + userRoles.getUserAddress() + "] failed due to wrong version[" + userRoles.getVersion() + "] !"); } } @@ -146,7 +145,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS } @Override - public UserRoles[] getRoleAuthorizations() { + public UserRoles[] getUserRoles() { VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); UserRoles[] pns = new UserRoles[kvEntries.length]; RoleSet roleset; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java index d720aa59..7c35a267 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java @@ -5,7 +5,17 @@ import com.jd.blockchain.utils.Bytes; public interface UserRoleSettings { - long getRoleCount(); + /** + * 单一用户可被授权的角色数量的最大值; + */ + public static final int MAX_ROLES_PER_USER = 20; + + /** + * 进行了授权的用户的数量; + * + * @return + */ + long getUserCount(); /** * 加入新的用户角色授权;
@@ -48,6 +58,11 @@ public interface UserRoleSettings { */ UserRoles getUserRoles(Bytes userAddress); - UserRoles[] getRoleAuthorizations(); + /** + * 返回全部的用户授权; + * + * @return + */ + UserRoles[] getUserRoles(); } \ No newline at end of file diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java index 57ec2110..9233953a 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java @@ -79,6 +79,10 @@ public class UserRoles implements RoleSet { * @param roles */ public void setRoles(String[] roles) { - + TreeSet rs = new TreeSet(); + for (String r : roles) { + rs.add(r); + } + this.roles = rs; } } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java index fe65af65..d7d820c4 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java @@ -1,5 +1,6 @@ package test.com.jd.blockchain.ledger; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -9,7 +10,6 @@ import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Random; -import com.jd.blockchain.ledger.LedgerMetadata; import org.junit.Test; import com.jd.blockchain.crypto.AddressEncoding; @@ -21,15 +21,23 @@ 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.LedgerMetadata_V2; +import com.jd.blockchain.ledger.LedgerSettings; import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.ledger.core.CryptoConfig; import com.jd.blockchain.ledger.core.LedgerAdminAccount; import com.jd.blockchain.ledger.core.LedgerConfiguration; +import com.jd.blockchain.ledger.core.LedgerPermission; +import com.jd.blockchain.ledger.core.RolePrivilegeSettings; +import com.jd.blockchain.ledger.core.RolePrivileges; +import com.jd.blockchain.ledger.core.RolesPolicy; +import com.jd.blockchain.ledger.core.TransactionPermission; +import com.jd.blockchain.ledger.core.UserRoleSettings; +import com.jd.blockchain.ledger.core.UserRoles; import com.jd.blockchain.storage.service.utils.MemoryKVStorage; import com.jd.blockchain.transaction.ConsensusParticipantData; import com.jd.blockchain.transaction.LedgerInitSettingData; import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.io.BytesUtils; import com.jd.blockchain.utils.net.NetworkAddress; public class LedgerAdminAccountTest { @@ -40,7 +48,7 @@ public class LedgerAdminAccountTest { private Random rand = new Random(); @Test - public void test() { + public void testSerialization() { String keyPrefix = ""; LedgerInitSettingData initSetting = new LedgerInitSettingData(); ConsensusParticipantData[] parties = new ConsensusParticipantData[5]; @@ -49,7 +57,7 @@ public class LedgerAdminAccountTest { bckeys[i] = BlockchainKeyGenerator.getInstance().generate(); parties[i] = new ConsensusParticipantData(); parties[i].setId(i); - parties[i].setAddress(AddressEncoding.generateAddress(bckeys[i].getPubKey()).toBase58()); + parties[i].setAddress(AddressEncoding.generateAddress(bckeys[i].getPubKey())); parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); parties[i].setName("Participant[" + i + "]"); parties[i].setPubKey(bckeys[i].getPubKey()); @@ -66,7 +74,6 @@ public class LedgerAdminAccountTest { for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); } - CryptoConfig cryptoSetting = new CryptoConfig(); cryptoSetting.setSupportedProviders(supportedProviders); cryptoSetting.setAutoVerifyHash(true); @@ -83,12 +90,20 @@ public class LedgerAdminAccountTest { LedgerAdminAccount ledgerAdminAccount = new LedgerAdminAccount(initSetting, keyPrefix, testStorage, testStorage); + ledgerAdminAccount.getRolePrivileges().addRolePrivilege("DEFAULT", + new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.REGISTER_USER, + LedgerPermission.APPROVE_TX }, + new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION, + TransactionPermission.CONTRACT_OPERATION }); + + ledgerAdminAccount.getUserRoles().addUserRoles(parties[0].getAddress(), RolesPolicy.UNION, "DEFAULT"); + // New created instance is updated until being committed; assertTrue(ledgerAdminAccount.isUpdated()); // Hash of account is null until being committed; assertNull(ledgerAdminAccount.getHash()); - LedgerMetadata meta = ledgerAdminAccount.getMetadata(); + LedgerMetadata_V2 meta = ledgerAdminAccount.getMetadata(); assertNull(meta.getParticipantsHash()); // Commit, and check the storage keys; @@ -101,83 +116,145 @@ public class LedgerAdminAccountTest { meta = ledgerAdminAccount.getMetadata(); assertNotNull(meta.getParticipantsHash()); + assertNotNull(meta.getSettingsHash()); + assertNotNull(meta.getRolePrivilegesHash()); + assertNotNull(meta.getUserRolesHash()); + + assertNotNull(ledgerAdminAccount.getRolePrivileges().getRolePrivilege("DEFAULT")); // ---------------------- // Reload account from storage with readonly mode, and check the integrity of // data; HashDigest adminAccHash = ledgerAdminAccount.getHash(); - LedgerAdminAccount reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, + LedgerAdminAccount reloadAdminAccount1 = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, true); - + + LedgerMetadata_V2 meta2 = reloadAdminAccount1.getMetadata(); + assertNotNull(meta2.getParticipantsHash()); + assertNotNull(meta2.getSettingsHash()); + assertNotNull(meta2.getRolePrivilegesHash()); + assertNotNull(meta2.getUserRolesHash()); + // verify realod settings of admin account; - verifyRealoadingSettings(reloadAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata()); - + verifyRealoadingSettings(reloadAdminAccount1, adminAccHash, ledgerAdminAccount.getMetadata(), + ledgerAdminAccount.getSettings()); // verify the consensus participant list; - verifyReadlingParities(reloadAdminAccount, parties1); - + verifyRealoadingParities(reloadAdminAccount1, parties1); // It will throw exeception because of this account is readonly; - verifyReadonlyState(reloadAdminAccount); + verifyReadonlyState(reloadAdminAccount1); + + verifyRealoadingRoleAuthorizations(reloadAdminAccount1, ledgerAdminAccount.getRolePrivileges(), + ledgerAdminAccount.getUserRoles()); // -------------- - // reload again with writing mode; - reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, false); - LedgerConfiguration newSetting = new LedgerConfiguration(reloadAdminAccount.getPreviousSetting()); + // 重新加载,并进行修改; + LedgerAdminAccount reloadAdminAccount2 = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, false); + LedgerConfiguration newSetting = new LedgerConfiguration(reloadAdminAccount2.getPreviousSetting()); byte[] newCsSettingBytes = new byte[64]; rand.nextBytes(newCsSettingBytes); newSetting.setConsensusSetting(new Bytes(newCsSettingBytes)); newSetting.getCryptoSetting().setAutoVerifyHash(false); - reloadAdminAccount.setLedgerSetting(newSetting); + reloadAdminAccount2.setLedgerSetting(newSetting); + + reloadAdminAccount2.addParticipant(parties[4]); + + reloadAdminAccount2.getRolePrivileges().addRolePrivilege("ADMIN", + new LedgerPermission[] { LedgerPermission.APPROVE_TX }, + new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION }); + + reloadAdminAccount2.getRolePrivileges().disablePermissions("DEFAULT", TransactionPermission.CONTRACT_OPERATION); + + reloadAdminAccount2.getUserRoles().addUserRoles(parties[1].getAddress(), RolesPolicy.UNION, "DEFAULT", "ADMIN"); - reloadAdminAccount.addParticipant(parties[4]); - reloadAdminAccount.commit(); + reloadAdminAccount2.commit(); + + LedgerSettings newlyLedgerSettings = reloadAdminAccount2.getSettings(); // record the new account hash; - HashDigest newAccHash = reloadAdminAccount.getHash(); - LedgerMetadata newMeta = reloadAdminAccount.getMetadata(); + HashDigest newAccHash = reloadAdminAccount2.getHash(); + LedgerMetadata_V2 newMeta = reloadAdminAccount2.getMetadata(); // load the last version of account and verify again; - reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, true); - verifyRealoadingSettings(reloadAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata()); - verifyReadlingParities(reloadAdminAccount, parties1); - verifyReadonlyState(reloadAdminAccount); + LedgerAdminAccount previousAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, + testStorage, true); + verifyRealoadingSettings(previousAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata(), + ledgerAdminAccount.getSettings()); + verifyRealoadingParities(previousAdminAccount, parties1); + verifyReadonlyState(previousAdminAccount); // load the hash of new committing; - reloadAdminAccount = new LedgerAdminAccount(newAccHash, keyPrefix, testStorage, testStorage, true); - verifyRealoadingSettings(reloadAdminAccount, newAccHash, newMeta); - verifyReadlingParities(reloadAdminAccount, parties); - verifyReadonlyState(reloadAdminAccount); - - // System.out.println("========= [LedgerAdminAccount Test] Show generated - // storage keys... ======="); - // testStorage.printStoragedKeys(); + LedgerAdminAccount newlyAdminAccount = new LedgerAdminAccount(newAccHash, keyPrefix, testStorage, testStorage, + true); + verifyRealoadingSettings(newlyAdminAccount, newAccHash, newMeta, newlyLedgerSettings); + verifyRealoadingParities(newlyAdminAccount, parties); + verifyReadonlyState(newlyAdminAccount); + +// System.out.println("========= [LedgerAdminAccount Test] Show generated storage keys... ======="); +// testStorage.printStoragedKeys(); } - private void verifyRealoadingSettings(LedgerAdminAccount actualAccount, HashDigest expHash, - LedgerMetadata expMeta) { + private void verifyRealoadingSettings(LedgerAdminAccount actualAccount, HashDigest expAccRootHash, + LedgerMetadata_V2 expMeta, LedgerSettings expLedgerSettings) { // 验证基本信息; assertFalse(actualAccount.isUpdated()); assertTrue(actualAccount.isReadonly()); - assertEquals(expHash, actualAccount.getHash()); + assertEquals(expAccRootHash, actualAccount.getHash()); // verify metadata; - LedgerMetadata rlmeta = actualAccount.getMetadata(); - assertEquals(expMeta.getParticipantsHash(), rlmeta.getParticipantsHash()); - - assertTrue(BytesUtils.equals(expMeta.getSeed(), rlmeta.getSeed())); - - assertNotNull(rlmeta.getSettingsHash()); - assertEquals(expMeta.getSettingsHash(), rlmeta.getSettingsHash()); -// assertTrue(expMeta.getSettings().getConsensusSetting().equals(rlmeta.getSettings().getConsensusSetting())); -// assertEquals(expMeta.getSettings().getConsensusProvider(), rlmeta.getSettings().getConsensusProvider()); -// -// assertEquals(expMeta.getSettings().getCryptoSetting().getAutoVerifyHash(), -// rlmeta.getSettings().getCryptoSetting().getAutoVerifyHash()); -// assertEquals(expMeta.getSettings().getCryptoSetting().getHashAlgorithm(), -// rlmeta.getSettings().getCryptoSetting().getHashAlgorithm()); + LedgerMetadata_V2 actualMeta = actualAccount.getMetadata(); + assertArrayEquals(expMeta.getSeed(), actualMeta.getSeed()); + assertEquals(expMeta.getParticipantsHash(), actualMeta.getParticipantsHash()); + assertNotNull(actualMeta.getSettingsHash()); + assertEquals(expMeta.getSettingsHash(), actualMeta.getSettingsHash()); + assertNotNull(actualMeta.getRolePrivilegesHash()); + assertEquals(expMeta.getRolePrivilegesHash(), actualMeta.getRolePrivilegesHash()); + assertNotNull(actualMeta.getUserRolesHash()); + assertEquals(expMeta.getUserRolesHash(), actualMeta.getUserRolesHash()); + + LedgerSettings actualLedgerSettings = actualAccount.getSettings(); + + assertEquals(expLedgerSettings.getConsensusSetting(), actualLedgerSettings.getConsensusSetting()); + assertEquals(expLedgerSettings.getConsensusProvider(), actualLedgerSettings.getConsensusProvider()); + + assertEquals(expLedgerSettings.getCryptoSetting().getAutoVerifyHash(), + actualLedgerSettings.getCryptoSetting().getAutoVerifyHash()); + assertEquals(expLedgerSettings.getCryptoSetting().getHashAlgorithm(), + actualLedgerSettings.getCryptoSetting().getHashAlgorithm()); + } + + private void verifyRealoadingRoleAuthorizations(LedgerAdminAccount actualAccount, + RolePrivilegeSettings expRolePrivilegeSettings, UserRoleSettings expUserRoleSettings) { + // 验证基本信息; + RolePrivilegeSettings actualRolePrivileges = actualAccount.getRolePrivileges(); + RolePrivileges[] expRPs = expRolePrivilegeSettings.getRolePrivileges(); + + assertEquals(expRPs.length, actualRolePrivileges.getRoleCount()); + + for (RolePrivileges expRP : expRPs) { + RolePrivileges actualRP = actualRolePrivileges.getRolePrivilege(expRP.getRoleName()); + assertNotNull(actualRP); + assertArrayEquals(expRP.getLedgerPrivilege().toBytes(), actualRP.getLedgerPrivilege().toBytes()); + assertArrayEquals(expRP.getTransactionPrivilege().toBytes(), actualRP.getTransactionPrivilege().toBytes()); + } + + UserRoleSettings actualUserRoleSettings = actualAccount.getUserRoles(); + UserRoles[] expUserRoles = expUserRoleSettings.getUserRoles(); + assertEquals(expUserRoles.length, actualUserRoleSettings.getUserCount()); + + for (UserRoles expUR : expUserRoles) { + UserRoles actualUR = actualAccount.getUserRoles().getUserRoles(expUR.getUserAddress()); + assertNotNull(actualUR); + assertEquals(expUR.getPolicy(), actualUR.getPolicy()); + String[] expRoles = expUR.getRoles(); + Arrays.sort(expRoles); + String[] actualRoles = actualUR.getRoles(); + Arrays.sort(actualRoles); + assertArrayEquals(expRoles, actualRoles); + } } - private void verifyReadlingParities(LedgerAdminAccount actualAccount, ParticipantNode[] expParties) { + private void verifyRealoadingParities(LedgerAdminAccount actualAccount, ParticipantNode[] expParties) { assertEquals(expParties.length, actualAccount.getParticipantCount()); ParticipantNode[] actualPaticipants = actualAccount.getParticipants(); assertEquals(expParties.length, actualPaticipants.length); @@ -191,11 +268,16 @@ public class LedgerAdminAccountTest { } } - private void verifyReadonlyState(LedgerAdminAccount actualAccount) { + /** + * 验证指定账户是否只读; + * + * @param readonlyAccount + */ + private void verifyReadonlyState(LedgerAdminAccount readonlyAccount) { ConsensusParticipantData newParti = new ConsensusParticipantData(); - newParti.setId((int) actualAccount.getParticipantCount()); + newParti.setId((int) readonlyAccount.getParticipantCount()); newParti.setHostAddress( - new NetworkAddress("192.168.10." + (10 + newParti.getAddress()), 10010 + 10 * newParti.getId())); + new NetworkAddress("192.168.10." + (10 + newParti.getId()), 10010 + 10 * newParti.getId())); newParti.setName("Participant[" + newParti.getAddress() + "]"); BlockchainKeypair newKey = BlockchainKeyGenerator.getInstance().generate(); @@ -203,7 +285,7 @@ public class LedgerAdminAccountTest { Throwable ex = null; try { - actualAccount.addParticipant(newParti); + readonlyAccount.addParticipant(newParti); } catch (Exception e) { ex = e; } @@ -211,8 +293,8 @@ public class LedgerAdminAccountTest { ex = null; try { - LedgerConfiguration newLedgerSetting = new LedgerConfiguration(actualAccount.getSettings()); - actualAccount.setLedgerSetting(newLedgerSetting); + LedgerConfiguration newLedgerSetting = new LedgerConfiguration(readonlyAccount.getSettings()); + readonlyAccount.setLedgerSetting(newLedgerSetting); } catch (Exception e) { ex = e; } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java index 9cee71df..483f7019 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java @@ -76,7 +76,7 @@ public class LedgerInitOperationTest { keys[i] = BlockchainKeyGenerator.getInstance().generate(); parties[i] = new ConsensusParticipantData(); // parties[i].setId(i); - parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58()); + parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey())); parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); parties[i].setName("Participant[" + i + "]"); parties[i].setPubKey(keys[i].getPubKey()); @@ -117,7 +117,7 @@ public class LedgerInitOperationTest { for (int i = 0; i < parties.length; i++) { keys[i] = BlockchainKeyGenerator.getInstance().generate(); - parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58(), + parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()), "Participant[" + i + "]", keys[i].getPubKey()); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java index f867ae9b..a06b3ed1 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java @@ -76,7 +76,7 @@ public class LedgerInitSettingSerializeTest { keys[i] = BlockchainKeyGenerator.getInstance().generate(); parties[i] = new ConsensusParticipantData(); // parties[i].setId(i); - parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58()); + parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey())); parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); parties[i].setName("Participant[" + i + "]"); parties[i].setPubKey(keys[i].getPubKey()); @@ -84,7 +84,7 @@ public class LedgerInitSettingSerializeTest { ConsensusParticipantData[] parties1 = Arrays.copyOf(parties, 4); ledgerInitSettingData.setConsensusParticipants(parties1); - + byte[] encode = BinaryProtocol.encode(ledgerInitSettingData, LedgerInitSetting.class); LedgerInitSetting decode = BinaryProtocol.decode(encode); @@ -121,7 +121,7 @@ public class LedgerInitSettingSerializeTest { for (int i = 0; i < parties.length; i++) { keys[i] = BlockchainKeyGenerator.getInstance().generate(); - parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58(), + parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()), "Participant[" + i + "]", keys[i].getPubKey()); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java index dfc17f24..f2021d99 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java @@ -209,7 +209,7 @@ public class LedgerManagerTest { parties[0].setName("John"); AsymmetricKeypair kp0 = signatureFunction.generateKeypair(); parties[0].setPubKey(kp0.getPubKey()); - parties[0].setAddress(AddressEncoding.generateAddress(kp0.getPubKey()).toBase58()); + parties[0].setAddress(AddressEncoding.generateAddress(kp0.getPubKey())); parties[0].setHostAddress(new NetworkAddress("127.0.0.1", 9000)); parties[1] = new ConsensusParticipantData(); @@ -217,7 +217,7 @@ public class LedgerManagerTest { parties[1].setName("Mary"); AsymmetricKeypair kp1 = signatureFunction.generateKeypair(); parties[1].setPubKey(kp1.getPubKey()); - parties[1].setAddress(AddressEncoding.generateAddress(kp1.getPubKey()).toBase58()); + parties[1].setAddress(AddressEncoding.generateAddress(kp1.getPubKey())); parties[1].setHostAddress(new NetworkAddress("127.0.0.1", 9010)); parties[2] = new ConsensusParticipantData(); @@ -225,7 +225,7 @@ public class LedgerManagerTest { parties[2].setName("Jerry"); AsymmetricKeypair kp2 = signatureFunction.generateKeypair(); parties[2].setPubKey(kp2.getPubKey()); - parties[2].setAddress(AddressEncoding.generateAddress(kp2.getPubKey()).toBase58()); + parties[2].setAddress(AddressEncoding.generateAddress(kp2.getPubKey())); parties[2].setHostAddress(new NetworkAddress("127.0.0.1", 9020)); parties[3] = new ConsensusParticipantData(); @@ -233,7 +233,7 @@ public class LedgerManagerTest { parties[3].setName("Tom"); AsymmetricKeypair kp3 = signatureFunction.generateKeypair(); parties[3].setPubKey(kp3.getPubKey()); - parties[3].setAddress(AddressEncoding.generateAddress(kp3.getPubKey()).toBase58()); + parties[3].setAddress(AddressEncoding.generateAddress(kp3.getPubKey())); parties[3].setHostAddress(new NetworkAddress("127.0.0.1", 9030)); initSetting.setConsensusParticipants(parties); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java index d6a16e5d..54eeab93 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java @@ -78,7 +78,7 @@ public class LedgerMetaDataTest { // LedgerConfiguration ledgerConfiguration = new LedgerConfiguration(consensusProvider, // new Bytes(consensusSettingBytes), cryptoConfig); HashDigest settingsHash = Crypto.getHashFunction("SHA256").hash(consensusSettingBytes); - + LedgerAdminAccount.LedgerMetadataImpl ledgerMetadata = new LedgerAdminAccount.LedgerMetadataImpl(); ledgerMetadata.setSeed(seed); @@ -188,7 +188,7 @@ public class LedgerMetaDataTest { String name = "John"; // NetworkAddress consensusAddress = new NetworkAddress("192.168.1.1", 9001, // false); - String address = AddressEncoding.generateAddress(pubKey).toBase58(); + Bytes address = AddressEncoding.generateAddress(pubKey); ParticipantCertData participantCertData = new ParticipantCertData(address, name, pubKey); // encode and decode diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java index 6101cdba..1625411b 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java @@ -72,7 +72,7 @@ public class LedgerTestUtils { parties[i].setId(0); parties[i].setName("Parti-" + i); parties[i].setPubKey(partiKeys[i].getPubKey()); - parties[i].setAddress(AddressEncoding.generateAddress(partiKeys[i].getPubKey()).toBase58()); + parties[i].setAddress(AddressEncoding.generateAddress(partiKeys[i].getPubKey())); parties[i].setHostAddress(new NetworkAddress("192.168.1." + (10 + i), 9000)); } @@ -125,13 +125,13 @@ public class LedgerTestUtils { return txReqBuilder.buildRequest(); } - - public static TransactionRequest createTxRequest_DataAccountReg(BlockchainKeypair dataAccountID, HashDigest ledgerHash, - BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { + + public static TransactionRequest createTxRequest_DataAccountReg(BlockchainKeypair dataAccountID, + HashDigest ledgerHash, BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { TxBuilder txBuilder = new TxBuilder(ledgerHash); - + txBuilder.dataAccounts().register(dataAccountID.getIdentity()); - + TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); if (signers != null) { for (BlockchainKeypair signer : signers) { @@ -141,16 +141,17 @@ public class LedgerTestUtils { if (nodeKeypair != null) { txReqBuilder.signAsNode(nodeKeypair); } - + return txReqBuilder.buildRequest(); } - - public static TransactionRequest createTxRequest_DataAccountWrite(Bytes dataAccountAddress, String key, String value, long version, HashDigest ledgerHash, - BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { + + public static TransactionRequest createTxRequest_DataAccountWrite(Bytes dataAccountAddress, String key, + String value, long version, HashDigest ledgerHash, BlockchainKeypair nodeKeypair, + BlockchainKeypair... signers) { TxBuilder txBuilder = new TxBuilder(ledgerHash); - + txBuilder.dataAccount(dataAccountAddress).setText(key, value, version); - + TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); if (signers != null) { for (BlockchainKeypair signer : signers) { @@ -160,7 +161,7 @@ public class LedgerTestUtils { if (nodeKeypair != null) { txReqBuilder.signAsNode(nodeKeypair); } - + return txReqBuilder.buildRequest(); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java index ce571d71..0570fee9 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java @@ -58,6 +58,18 @@ public class MerkleDataSetTest { mds.setValue("C", "C".getBytes(), -1); mds.commit(); + + byte[] va = mds.getValue("A"); + assertNotNull(va); + assertEquals("A", new String(va)); + + byte[] vc = mds.getValue("C"); + VersioningKVEntry ventry = mds.getDataEntry("C"); + assertNotNull(vc); + assertNotNull(ventry); + assertEquals("C", new String(vc)); + assertEquals("C", ventry.getKey().toUTF8String()); + HashDigest root1 = mds.getRootHash(); // 1个KV项的存储KEY的数量= 1 + 1(保存SN) + Merkle节点数量; diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/RolePrivilegeDataSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/RolePrivilegeDataSetTest.java new file mode 100644 index 00000000..6763162c --- /dev/null +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/RolePrivilegeDataSetTest.java @@ -0,0 +1,70 @@ +package test.com.jd.blockchain.ledger; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoAlgorithm; +import com.jd.blockchain.crypto.CryptoProvider; +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; +import com.jd.blockchain.crypto.service.sm.SMCryptoService; +import com.jd.blockchain.ledger.core.CryptoConfig; +import com.jd.blockchain.ledger.core.LedgerPermission; +import com.jd.blockchain.ledger.core.RolePrivilegeDataSet; +import com.jd.blockchain.ledger.core.RolePrivileges; +import com.jd.blockchain.ledger.core.TransactionPermission; +import com.jd.blockchain.storage.service.utils.MemoryKVStorage; + +public class RolePrivilegeDataSetTest { + + private static final String[] SUPPORTED_PROVIDER_NAMES = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + + private static final CryptoAlgorithm HASH_ALGORITHM = Crypto.getAlgorithm("SHA256"); + + private static final CryptoProvider[] SUPPORTED_PROVIDERS = new CryptoProvider[SUPPORTED_PROVIDER_NAMES.length]; + static { + for (int i = 0; i < SUPPORTED_PROVIDER_NAMES.length; i++) { + SUPPORTED_PROVIDERS[i] = Crypto.getProvider(SUPPORTED_PROVIDER_NAMES[i]); + } + } + + @Test + public void testAddRolePrivilege() { + + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setAutoVerifyHash(true); + cryptoConfig.setSupportedProviders(SUPPORTED_PROVIDERS); + cryptoConfig.setHashAlgorithm(HASH_ALGORITHM); + + MemoryKVStorage testStorage = new MemoryKVStorage(); + + String roleName = "DEFAULT"; + String prefix = "role-privilege/"; + RolePrivilegeDataSet rolePrivilegeDataset = new RolePrivilegeDataSet(cryptoConfig, prefix, testStorage, + testStorage); + rolePrivilegeDataset.addRolePrivilege(roleName, new LedgerPermission[] { LedgerPermission.REGISTER_USER }, + new TransactionPermission[] { TransactionPermission.CONTRACT_OPERATION }); + + rolePrivilegeDataset.commit(); + + RolePrivileges rolePrivilege = rolePrivilegeDataset.getRolePrivilege(roleName); + assertNotNull(rolePrivilege); + + HashDigest rootHash = rolePrivilegeDataset.getRootHash(); + RolePrivilegeDataSet newRolePrivilegeDataset = new RolePrivilegeDataSet(rootHash, cryptoConfig, prefix, + testStorage, testStorage, true); + rolePrivilege = newRolePrivilegeDataset.getRolePrivilege(roleName); + assertNotNull(rolePrivilege); + + assertTrue(rolePrivilege.getLedgerPrivilege().isEnable(LedgerPermission.REGISTER_USER)); + assertTrue(rolePrivilege.getTransactionPrivilege().isEnable(TransactionPermission.CONTRACT_OPERATION)); + + + } + +} diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/UserRoleDataSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/UserRoleDataSetTest.java new file mode 100644 index 00000000..41a59be1 --- /dev/null +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/UserRoleDataSetTest.java @@ -0,0 +1,62 @@ +package test.com.jd.blockchain.ledger; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.CryptoAlgorithm; +import com.jd.blockchain.crypto.CryptoProvider; +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.CryptoConfig; +import com.jd.blockchain.ledger.core.RolesPolicy; +import com.jd.blockchain.ledger.core.UserRoleDataSet; +import com.jd.blockchain.ledger.core.UserRoles; +import com.jd.blockchain.storage.service.utils.MemoryKVStorage; + +public class UserRoleDataSetTest { + + private static final String[] SUPPORTED_PROVIDER_NAMES = { ClassicCryptoService.class.getName(), + SMCryptoService.class.getName() }; + + private static final CryptoAlgorithm HASH_ALGORITHM = Crypto.getAlgorithm("SHA256"); + + private static final CryptoProvider[] SUPPORTED_PROVIDERS = new CryptoProvider[SUPPORTED_PROVIDER_NAMES.length]; + static { + for (int i = 0; i < SUPPORTED_PROVIDER_NAMES.length; i++) { + SUPPORTED_PROVIDERS[i] = Crypto.getProvider(SUPPORTED_PROVIDER_NAMES[i]); + } + } + + @Test + public void testAddUserRoles() { + CryptoConfig cryptoConfig = new CryptoConfig(); + cryptoConfig.setAutoVerifyHash(true); + cryptoConfig.setSupportedProviders(SUPPORTED_PROVIDERS); + cryptoConfig.setHashAlgorithm(HASH_ALGORITHM); + + MemoryKVStorage testStorage = new MemoryKVStorage(); + String prefix = "user-roles/"; + UserRoleDataSet userRolesDataset = new UserRoleDataSet(cryptoConfig, prefix, testStorage, testStorage); + + BlockchainKeypair bckp = BlockchainKeyGenerator.getInstance().generate(); + String[] authRoles = { "DEFAULT", "MANAGER" }; + userRolesDataset.addUserRoles(bckp.getAddress(), RolesPolicy.UNION, authRoles); + + userRolesDataset.commit(); + + assertEquals(1, userRolesDataset.getUserCount()); + UserRoles userRoles = userRolesDataset.getUserRoles(bckp.getAddress()); + assertNotNull(userRoles); + String[] roles = userRoles.getRoles(); + assertEquals(2, roles.length); + assertArrayEquals(authRoles, roles); + assertEquals(RolesPolicy.UNION, userRoles.getPolicy()); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AuthorizationException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AuthorizationException.java new file mode 100644 index 00000000..94a374a8 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AuthorizationException.java @@ -0,0 +1,17 @@ +package com.jd.blockchain.ledger; + +public class AuthorizationException extends LedgerException { + + private static final long serialVersionUID = -4418553411943356320L; + + + + public AuthorizationException(String message) { + super(message); + } + + public AuthorizationException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerAdminInfo.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerAdminInfo.java index 93ef4234..4e1b5105 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerAdminInfo.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerAdminInfo.java @@ -9,7 +9,7 @@ import com.jd.blockchain.consts.DataCodes; public interface LedgerAdminInfo { @DataField(order = 1, refContract = true) - LedgerMetadata getMetadata(); + LedgerMetadata_V2 getMetadata(); @DataField(order = 2, refContract = true) LedgerSettings getSettings(); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java index 01ce182f..228019b7 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java @@ -13,7 +13,7 @@ import com.jd.blockchain.crypto.HashDigest; * @author huanghaiquan * */ -@DataContract(code = DataCodes.METADATA, name = "LEDGER-METADATA-V2") +@DataContract(code = DataCodes.METADATA_V2, name = "LEDGER-METADATA-V2") public interface LedgerMetadata_V2 extends LedgerMetadata { /** diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java index dd2c62fa..8d4075cb 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java @@ -5,6 +5,7 @@ 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; /** * 参与方节点; @@ -30,8 +31,8 @@ public interface ParticipantNode {// extends ConsensusNode, ParticipantInfo { * * @return */ - @DataField(order = 1, primitiveType = PrimitiveType.TEXT) - String getAddress(); + @DataField(order = 1, primitiveType = PrimitiveType.BYTES) + Bytes getAddress(); /** * 参与者名称; diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ConsensusParticipantData.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ConsensusParticipantData.java index b4e64744..ed0130d1 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ConsensusParticipantData.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ConsensusParticipantData.java @@ -2,13 +2,14 @@ package com.jd.blockchain.transaction; import com.jd.blockchain.crypto.PubKey; import com.jd.blockchain.ledger.ParticipantNode; +import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.net.NetworkAddress; public class ConsensusParticipantData implements ParticipantNode { private int id; - private String address; + private Bytes address; private String name; @@ -48,11 +49,11 @@ public class ConsensusParticipantData implements ParticipantNode { this.pubKey = pubKey; } - public String getAddress() { + public Bytes getAddress() { return address; } - public void setAddress(String address) { + public void setAddress(Bytes address) { this.address = address; } diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusRealmImpl.java b/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusRealmImpl.java index 108365a6..d5d5fca9 100644 --- a/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusRealmImpl.java +++ b/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusRealmImpl.java @@ -16,7 +16,7 @@ public class ConsensusRealmImpl implements ConsensusRealm { public ConsensusRealmImpl(ParticipantNode[] nodeList) { this.nodes = nodeList; - String[] addrs = new String[nodes.length]; + Bytes[] addrs = new Bytes[nodes.length]; int i = 0; for (ParticipantNode n : nodes) { addrs[i++] = n.getAddress(); 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 f0f904ad..86011bd7 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 @@ -8,19 +8,41 @@ */ package com.jd.blockchain.sdk.converters; +import java.lang.reflect.Field; + +import org.apache.commons.codec.binary.Base64; + import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.jd.blockchain.crypto.CryptoProvider; import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.*; -import com.jd.blockchain.transaction.*; +import com.jd.blockchain.ledger.BlockchainIdentityData; +import com.jd.blockchain.ledger.BytesData; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.BytesValueEncoding; +import com.jd.blockchain.ledger.ContractCodeDeployOperation; +import com.jd.blockchain.ledger.ContractEventSendOperation; +import com.jd.blockchain.ledger.CryptoSetting; +import com.jd.blockchain.ledger.DataAccountKVSetOperation; +import com.jd.blockchain.ledger.DataAccountRegisterOperation; +import com.jd.blockchain.ledger.DataType; +import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.LedgerInitOperation; +import com.jd.blockchain.ledger.Operation; +import com.jd.blockchain.ledger.ParticipantNode; +import com.jd.blockchain.ledger.UserRegisterOperation; +import com.jd.blockchain.transaction.ContractCodeDeployOpTemplate; +import com.jd.blockchain.transaction.ContractEventSendOpTemplate; +import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; +import com.jd.blockchain.transaction.DataAccountRegisterOpTemplate; +import com.jd.blockchain.transaction.KVData; +import com.jd.blockchain.transaction.LedgerInitOpTemplate; +import com.jd.blockchain.transaction.LedgerInitSettingData; +import com.jd.blockchain.transaction.UserRegisterOpTemplate; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.codec.Base58Utils; import com.jd.blockchain.utils.codec.HexUtils; import com.jd.blockchain.utils.io.BytesUtils; -import org.apache.commons.codec.binary.Base64; - -import java.lang.reflect.Field; /** * @@ -31,347 +53,348 @@ import java.lang.reflect.Field; public class ClientResolveUtil { - public static KVDataEntry[] read(KVDataEntry[] kvDataEntries) { - if (kvDataEntries == null || kvDataEntries.length == 0) { - return kvDataEntries; - } - KVDataEntry[] resolveKvDataEntries = new KVDataEntry[kvDataEntries.length]; - // kvDataEntries是代理对象,需要处理 - for (int i = 0; i < kvDataEntries.length; i++) { - KVDataEntry kvDataEntry = kvDataEntries[i]; - String key = kvDataEntry.getKey(); - long version = kvDataEntry.getVersion(); - DataType dataType = kvDataEntry.getType(); - KvData innerKvData = new KvData(key, version, dataType); - Object valueObj = kvDataEntry.getValue(); - switch (dataType) { - case NIL: - break; - case BYTES: - case TEXT: - case JSON: - innerKvData.setValue(valueObj.toString()); - break; - case INT32: - innerKvData.setValue(Integer.parseInt(valueObj.toString())); - break; - case INT64: - innerKvData.setValue(Long.parseLong(valueObj.toString())); - break; - default: - throw new IllegalStateException("Unsupported value type[" + dataType + "] to resolve!"); - } - resolveKvDataEntries[i] = innerKvData; - } - return resolveKvDataEntries; - } - - public static Operation read(Operation operation) { - - try { - // Class - Class clazz = operation.getClass(); - Field field = clazz.getSuperclass().getDeclaredField("h"); - field.setAccessible(true); - Object object = field.get(operation); - if (object instanceof JSONObject) { - JSONObject jsonObject = (JSONObject) object; - if (jsonObject.containsKey("accountID")) { - return convertDataAccountRegisterOperation(jsonObject); - } else if (jsonObject.containsKey("userID")) { - return convertUserRegisterOperation(jsonObject); - } else if (jsonObject.containsKey("contractID")) { - return convertContractCodeDeployOperation(jsonObject); - } else if (jsonObject.containsKey("writeSet")) { - return convertDataAccountKVSetOperation(jsonObject); - } else if (jsonObject.containsKey("initSetting")) { - return convertLedgerInitOperation(jsonObject); - } else if (jsonObject.containsKey("contractAddress")) { - return convertContractEventSendOperation(jsonObject); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - - return null; - } - - public static Object readValueByBytesValue(BytesValue bytesValue) { - DataType dataType = bytesValue.getType(); - Bytes saveVal = bytesValue.getValue(); - Object showVal; - switch (dataType) { - case BYTES: - // return hex - showVal = HexUtils.encode(saveVal.toBytes()); - break; - case TEXT: - case JSON: - showVal = saveVal.toUTF8String(); - break; - case INT64: - showVal = BytesUtils.toLong(saveVal.toBytes()); - break; - default: - showVal = HexUtils.encode(saveVal.toBytes()); - break; - } - return showVal; - } - - public static DataAccountRegisterOperation convertDataAccountRegisterOperation(JSONObject jsonObject) { - JSONObject account = jsonObject.getJSONObject("accountID"); - return new DataAccountRegisterOpTemplate(blockchainIdentity(account)); - } - - public static DataAccountKVSetOperation convertDataAccountKVSetOperation(JSONObject jsonObject) { - // 写入集合处理 - JSONArray writeSetObj = jsonObject.getJSONArray("writeSet"); - JSONObject accountAddrObj = jsonObject.getJSONObject("accountAddress"); - String addressBase58 = accountAddrObj.getString("value"); - Bytes address = Bytes.fromBase58(addressBase58); - - DataAccountKVSetOpTemplate kvOperation = new DataAccountKVSetOpTemplate(address); - for (int i = 0; i clazz = operation.getClass(); + Field field = clazz.getSuperclass().getDeclaredField("h"); + field.setAccessible(true); + Object object = field.get(operation); + if (object instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) object; + if (jsonObject.containsKey("accountID")) { + return convertDataAccountRegisterOperation(jsonObject); + } else if (jsonObject.containsKey("userID")) { + return convertUserRegisterOperation(jsonObject); + } else if (jsonObject.containsKey("contractID")) { + return convertContractCodeDeployOperation(jsonObject); + } else if (jsonObject.containsKey("writeSet")) { + return convertDataAccountKVSetOperation(jsonObject); + } else if (jsonObject.containsKey("initSetting")) { + return convertLedgerInitOperation(jsonObject); + } else if (jsonObject.containsKey("contractAddress")) { + return convertContractEventSendOperation(jsonObject); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + return null; + } + + public static Object readValueByBytesValue(BytesValue bytesValue) { + DataType dataType = bytesValue.getType(); + Bytes saveVal = bytesValue.getValue(); + Object showVal; + switch (dataType) { + case BYTES: + // return hex + showVal = HexUtils.encode(saveVal.toBytes()); + break; + case TEXT: + case JSON: + showVal = saveVal.toUTF8String(); + break; + case INT64: + showVal = BytesUtils.toLong(saveVal.toBytes()); + break; + default: + showVal = HexUtils.encode(saveVal.toBytes()); + break; + } + return showVal; + } + + public static DataAccountRegisterOperation convertDataAccountRegisterOperation(JSONObject jsonObject) { + JSONObject account = jsonObject.getJSONObject("accountID"); + return new DataAccountRegisterOpTemplate(blockchainIdentity(account)); + } + + public static DataAccountKVSetOperation convertDataAccountKVSetOperation(JSONObject jsonObject) { + // 写入集合处理 + JSONArray writeSetObj = jsonObject.getJSONArray("writeSet"); + JSONObject accountAddrObj = jsonObject.getJSONObject("accountAddress"); + String addressBase58 = accountAddrObj.getString("value"); + Bytes address = Bytes.fromBase58(addressBase58); + + DataAccountKVSetOpTemplate kvOperation = new DataAccountKVSetOpTemplate(address); + for (int i = 0; i < writeSetObj.size(); i++) { + JSONObject currWriteSetObj = writeSetObj.getJSONObject(i); + long expectedVersion = currWriteSetObj.getLong("expectedVersion"); + JSONObject valueObj = currWriteSetObj.getJSONObject("value"); + String typeStr = valueObj.getString("type"); + String realValBase58 = valueObj.getString("value"); + String key = currWriteSetObj.getString("key"); + DataType dataType = DataType.valueOf(typeStr); + BytesValue bytesValue = BytesData.fromType(dataType, Base58Utils.decode(realValBase58)); + KVData kvData = new KVData(key, bytesValue, expectedVersion); + kvOperation.set(kvData); + } + + return kvOperation; + } + + public static LedgerInitOperation convertLedgerInitOperation(JSONObject jsonObject) { + JSONObject legerInitObj = jsonObject.getJSONObject("initSetting"); + LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData(); + String ledgerSeedStr = legerInitObj.getString("ledgerSeed"); + + // 种子需要做Base64转换 + ledgerInitSettingData.setLedgerSeed(Base64.decodeBase64(BytesUtils.toBytes(ledgerSeedStr))); + + String consensusProvider = legerInitObj.getString("consensusProvider"); + + ledgerInitSettingData.setConsensusProvider(consensusProvider); + + JSONObject cryptoSettingObj = legerInitObj.getJSONObject("cryptoSetting"); + boolean autoVerifyHash = cryptoSettingObj.getBoolean("autoVerifyHash"); + short hashAlgorithm = cryptoSettingObj.getShort("hashAlgorithm"); + + CryptoConfig cryptoConfig = new CryptoConfig(); + + cryptoConfig.setAutoVerifyHash(autoVerifyHash); + + cryptoConfig.setHashAlgorithm(hashAlgorithm); + + ledgerInitSettingData.setCryptoSetting(cryptoConfig); + + JSONObject consensusSettingsObj = legerInitObj.getJSONObject("consensusSettings"); + Bytes consensusSettings = Bytes.fromBase58(consensusSettingsObj.getString("value")); + + ledgerInitSettingData.setConsensusSettings(consensusSettings); + + JSONArray consensusParticipantsArray = legerInitObj.getJSONArray("consensusParticipants"); + + if (!consensusParticipantsArray.isEmpty()) { + ParticipantNode[] participantNodes = new ParticipantNode[consensusParticipantsArray.size()]; + for (int i = 0; i < consensusParticipantsArray.size(); i++) { + JSONObject currConsensusParticipant = consensusParticipantsArray.getJSONObject(i); + String addressBase58 = currConsensusParticipant.getString("address"); + String name = currConsensusParticipant.getString("name"); + int id = currConsensusParticipant.getInteger("id"); + JSONObject pubKeyObj = currConsensusParticipant.getJSONObject("pubKey"); + String pubKeyBase58 = pubKeyObj.getString("value"); + // 生成ParticipantNode对象 + ParticipantCertData participantCertData = new ParticipantCertData(id, Bytes.fromBase58(addressBase58), + name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes())); + participantNodes[i] = participantCertData; + } + ledgerInitSettingData.setConsensusParticipants(participantNodes); + } + + return new LedgerInitOpTemplate(ledgerInitSettingData); + } + + public static UserRegisterOperation convertUserRegisterOperation(JSONObject jsonObject) { + JSONObject user = jsonObject.getJSONObject("userID"); + return new UserRegisterOpTemplate(blockchainIdentity(user)); + } + + public static ContractCodeDeployOperation convertContractCodeDeployOperation(JSONObject jsonObject) { + JSONObject contract = jsonObject.getJSONObject("contractID"); + BlockchainIdentityData blockchainIdentity = blockchainIdentity(contract); + + String chainCodeStr = jsonObject.getString("chainCode"); + ContractCodeDeployOpTemplate contractCodeDeployOpTemplate = new ContractCodeDeployOpTemplate(blockchainIdentity, + BytesUtils.toBytes(chainCodeStr)); + return contractCodeDeployOpTemplate; + } + + public static ContractEventSendOperation convertContractEventSendOperation(JSONObject jsonObject) { + JSONObject contractAddressObj = jsonObject.getJSONObject("contractAddress"); + String contractAddress = contractAddressObj.getString("value"); + String argsStr = jsonObject.getString("args"); + String event = jsonObject.getString("event"); + return new ContractEventSendOpTemplate(Bytes.fromBase58(contractAddress), event, + BytesValueEncoding.encodeArray(new Object[] { argsStr }, null)); + } + + private static BlockchainIdentityData blockchainIdentity(JSONObject jsonObject) { + JSONObject addressObj = jsonObject.getJSONObject("address"); + // base58值 + String addressBase58 = addressObj.getString("value"); + Bytes address = Bytes.fromBase58(addressBase58); + + JSONObject pubKeyObj = jsonObject.getJSONObject("pubKey"); + // base58值 + String pubKeyBase58 = pubKeyObj.getString("value"); + PubKey pubKey = new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes()); + + // 生成对应的对象 + return new BlockchainIdentityData(address, pubKey); + } + + public static class CryptoConfig implements CryptoSetting { + + private short hashAlgorithm; + + private boolean autoVerifyHash; + + @Override + public CryptoProvider[] getSupportedProviders() { + return new CryptoProvider[0]; + } + + @Override + public short getHashAlgorithm() { + return hashAlgorithm; + } + + @Override + public boolean getAutoVerifyHash() { + return autoVerifyHash; + } + + public void setHashAlgorithm(short hashAlgorithm) { + this.hashAlgorithm = hashAlgorithm; + } + + public void setAutoVerifyHash(boolean autoVerifyHash) { + this.autoVerifyHash = autoVerifyHash; + } + } + + public static class ParticipantCertData implements ParticipantNode { + private int id; + private Bytes address; + private String name; + private PubKey pubKey; + + public ParticipantCertData() { + } + + public ParticipantCertData(ParticipantNode participantNode) { + this.address = participantNode.getAddress(); + this.name = participantNode.getName(); + this.pubKey = participantNode.getPubKey(); + } + + public ParticipantCertData(int id, Bytes address, String name, PubKey pubKey) { + this.id = id; + this.address = address; + this.name = name; + this.pubKey = pubKey; + } + + @Override + public Bytes getAddress() { + return address; + } + + @Override + public String getName() { + return name; + } + + @Override + public PubKey getPubKey() { + return pubKey; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } + + public static class KvData implements KVDataEntry { + + private String key; + + private long version; + + private DataType dataType; + + private Object value; + + public KvData() { + } + + public KvData(String key, long version, DataType dataType) { + this(key, version, dataType, null); + } + + public KvData(String key, long version, DataType dataType, Object value) { + this.key = key; + this.version = version; + this.dataType = dataType; + this.value = value; + } + + public void setKey(String key) { + this.key = key; + } + + public void setVersion(long version) { + this.version = version; + } + + public void setDataType(DataType dataType) { + this.dataType = dataType; + } + + public void setValue(Object value) { + this.value = value; + } + + @Override + public String getKey() { + return key; + } + + @Override + public long getVersion() { + return version; + } + + @Override + public DataType getType() { + return dataType; + } + + @Override + public Object getValue() { + return value; + } + } } \ No newline at end of file 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 65920967..0c2192a3 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 @@ -12,11 +12,6 @@ import com.jd.blockchain.utils.io.BytesMap; public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, KVStorageService, BytesMap { -// private Set keys = new HashSet<>(); - -// private Set keys = Collections.synchronizedSet(new HashSet<>()); - -// private Map storageMap = new ConcurrentHashMap<>(); private ExistancePolicyKVStorageMap exStorage = new ExistancePolicyKVStorageMap(); private VersioningKVStorageMap verStorage = new VersioningKVStorageMap(); @@ -38,10 +33,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, @Override public long set(Bytes key, byte[] value, long version) { return verStorage.set(key, value, version); -// if (v > -1) { -// keys.add(key); -// } -// return v; } @Override @@ -57,10 +48,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, @Override public boolean set(Bytes key, byte[] value, ExPolicy ex) { return exStorage.set(key, value, ex); -// if (ok) { -// keys.add(key); -// } -// return ok; } @Override @@ -81,12 +68,10 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, HashSet keySet = new HashSet<>(exStorage.keySet()); keySet.addAll(verStorage.keySet()); return keySet; -// return storageMap.keySet(); } public int getStorageCount() { return exStorage.getCount() + verStorage.getCount(); -// return storageMap.size(); } // public void printStoragedKeys() { 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 new file mode 100644 index 00000000..684c75fe --- /dev/null +++ b/source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java @@ -0,0 +1,35 @@ +package com.jd.blockchain.storage.service.utils; + +import com.jd.blockchain.storage.service.VersioningKVEntry; +import com.jd.blockchain.utils.Bytes; + +public class VersioningKVData implements VersioningKVEntry { + + private Bytes key; + + private long version; + + private byte[] value; + + public VersioningKVData(Bytes key, long version, byte[] value) { + this.key = key; + this.version = version; + this.value = value; + } + + @Override + public Bytes getKey() { + return key; + } + + @Override + public long getVersion() { + return version; + } + + @Override + public byte[] getValue() { + return value; + } + + } \ No newline at end of file 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 2569007f..3c4855e3 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 @@ -215,38 +215,6 @@ public class VersioningKVStorageMap implements VersioningKVStorage, BytesMap