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