@@ -67,6 +67,7 @@ public interface DataCodes { | |||||
// contract types of metadata; | // contract types of metadata; | ||||
public static final int METADATA = 0x600; | public static final int METADATA = 0x600; | ||||
public static final int METADATA_V2 = 0x601; | |||||
public static final int METADATA_INIT_SETTING = 0x610; | public static final int METADATA_INIT_SETTING = 0x610; | ||||
@@ -25,6 +25,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||||
static { | static { | ||||
DataContractRegistry.register(LedgerMetadata.class); | DataContractRegistry.register(LedgerMetadata.class); | ||||
DataContractRegistry.register(LedgerMetadata_V2.class); | |||||
} | } | ||||
private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminAccount.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 rolePrivilegePrefix; | ||||
private final Bytes userRolePrefix; | private final Bytes userRolePrefix; | ||||
private LedgerMetadata origMetadata; | |||||
private LedgerMetadata_V2 origMetadata; | |||||
private LedgerMetadataImpl metadata; | private LedgerMetadataImpl metadata; | ||||
@@ -225,7 +226,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||||
return BinaryProtocol.encode(setting, LedgerSettings.class); | return BinaryProtocol.encode(setting, LedgerSettings.class); | ||||
} | } | ||||
private LedgerMetadata loadAndVerifyMetadata(HashDigest adminAccountHash) { | |||||
private LedgerMetadata_V2 loadAndVerifyMetadata(HashDigest adminAccountHash) { | |||||
Bytes key = encodeMetadataKey(adminAccountHash); | Bytes key = encodeMetadataKey(adminAccountHash); | ||||
byte[] bytes = storage.get(key); | byte[] bytes = storage.get(key); | ||||
HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm()); | HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm()); | ||||
@@ -253,7 +254,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||||
* @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata() | * @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata() | ||||
*/ | */ | ||||
@Override | @Override | ||||
public LedgerMetadata getMetadata() { | |||||
public LedgerMetadata_V2 getMetadata() { | |||||
return metadata; | return metadata; | ||||
} | } | ||||
@@ -325,7 +326,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||||
@Override | @Override | ||||
public boolean isUpdated() { | public boolean isUpdated() { | ||||
return updated || participants.isUpdated(); | |||||
return updated || participants.isUpdated() || rolePrivileges.isUpdated() || userRoles.isUpdated(); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -392,12 +393,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||||
updated = false; | updated = false; | ||||
} | } | ||||
private LedgerMetadata deserializeMetadata(byte[] bytes) { | |||||
private LedgerMetadata_V2 deserializeMetadata(byte[] bytes) { | |||||
return BinaryProtocol.decode(bytes); | return BinaryProtocol.decode(bytes); | ||||
} | } | ||||
private byte[] serializeMetadata(LedgerMetadataImpl config) { | private byte[] serializeMetadata(LedgerMetadataImpl config) { | ||||
return BinaryProtocol.encode(config, LedgerMetadata.class); | |||||
return BinaryProtocol.encode(config, LedgerMetadata_V2.class); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -426,11 +427,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||||
public LedgerMetadataImpl() { | public LedgerMetadataImpl() { | ||||
} | } | ||||
public LedgerMetadataImpl(LedgerMetadata metadata) { | |||||
public LedgerMetadataImpl(LedgerMetadata_V2 metadata) { | |||||
this.seed = metadata.getSeed(); | this.seed = metadata.getSeed(); | ||||
// this.setting = metadata.getSetting(); | |||||
this.participantsHash = metadata.getParticipantsHash(); | this.participantsHash = metadata.getParticipantsHash(); | ||||
this.settingsHash = metadata.getSettingsHash(); | this.settingsHash = metadata.getSettingsHash(); | ||||
this.rolePrivilegesHash = metadata.getRolePrivilegesHash(); | |||||
this.userRolesHash = metadata.getUserRolesHash(); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -15,10 +15,10 @@ import com.jd.blockchain.consts.DataCodes; | |||||
public enum LedgerPermission { | public enum LedgerPermission { | ||||
/** | /** | ||||
* 设置角色权限;<br> | |||||
* 授权角色权限;<br> | |||||
* 包括:创建角色、设置角色的权限代码、分配用户角色; | * 包括:创建角色、设置角色的权限代码、分配用户角色; | ||||
*/ | */ | ||||
SET_ROLE_PERMISSION((byte) 0x01), | |||||
AUTHORIZE_ROLES((byte) 0x01), | |||||
/** | /** | ||||
* 设置共识协议;<br> | * 设置共识协议;<br> | ||||
@@ -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.VersioningKVEntry; | ||||
import com.jd.blockchain.storage.service.VersioningKVStorage; | import com.jd.blockchain.storage.service.VersioningKVStorage; | ||||
import com.jd.blockchain.storage.service.utils.BufferedKVStorage; | 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.Bytes; | ||||
import com.jd.blockchain.utils.Transactional; | import com.jd.blockchain.utils.Transactional; | ||||
import com.jd.blockchain.utils.io.BytesUtils; | import com.jd.blockchain.utils.io.BytesUtils; | ||||
@@ -62,12 +63,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||||
/** | /** | ||||
* 创建一个新的 MerkleDataSet; | * 创建一个新的 MerkleDataSet; | ||||
* | * | ||||
* @param setting | |||||
* 密码设置; | |||||
* @param exPolicyStorage | |||||
* 默克尔树的存储; | |||||
* @param versioningStorage | |||||
* 数据的存储; | |||||
* @param setting 密码设置; | |||||
* @param exPolicyStorage 默克尔树的存储; | |||||
* @param versioningStorage 数据的存储; | |||||
*/ | */ | ||||
public MerkleDataSet(CryptoSetting setting, String keyPrefix, ExPolicyKVStorage exPolicyStorage, | public MerkleDataSet(CryptoSetting setting, String keyPrefix, ExPolicyKVStorage exPolicyStorage, | ||||
VersioningKVStorage versioningStorage) { | VersioningKVStorage versioningStorage) { | ||||
@@ -149,7 +147,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||||
} | } | ||||
return values; | return values; | ||||
} | } | ||||
public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) { | public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) { | ||||
if (count > LedgerConsts.MAX_LIST_COUNT) { | if (count > LedgerConsts.MAX_LIST_COUNT) { | ||||
throw new IllegalArgumentException("Count exceed the upper limit[" + 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!"); | throw new IllegalArgumentException("Index out of bound!"); | ||||
} | } | ||||
VersioningKVEntry[] values = new VersioningKVEntry[count]; | VersioningKVEntry[] values = new VersioningKVEntry[count]; | ||||
byte[] bytesValue; | |||||
for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
MerkleDataNode dataNode = merkleTree.getData(fromIndex + i); | MerkleDataNode dataNode = merkleTree.getData(fromIndex + i); | ||||
Bytes dataKey = encodeDataKey(dataNode.getKey()); | 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; | return values; | ||||
} | } | ||||
/** | /** | ||||
* get the data at the specific index; | * get the data at the specific index; | ||||
* | |||||
* @param fromIndex | * @param fromIndex | ||||
* @return | * @return | ||||
*/ | */ | ||||
@@ -179,15 +180,15 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||||
/** | /** | ||||
* get the key at the specific index; | * get the key at the specific index; | ||||
* | |||||
* @param fromIndex | * @param fromIndex | ||||
* @return | * @return | ||||
*/ | */ | ||||
public String getKeyAtIndex(int fromIndex) { | public String getKeyAtIndex(int fromIndex) { | ||||
MerkleDataNode dataNode = merkleTree.getData(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 | * Create or update the value associated the specified key if the version | ||||
* checking is passed.<br> | * checking is passed.<br> | ||||
@@ -199,12 +200,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||||
* If updating is performed, the version of the key increase by 1. <br> | * If updating is performed, the version of the key increase by 1. <br> | ||||
* If creating is performed, the version of the key initialize by 0. <br> | * If creating is performed, the version of the key initialize by 0. <br> | ||||
* | * | ||||
* @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. <br> | * @return The new version of the key. <br> | ||||
* If the key is new created success, then return 0; <br> | * If the key is new created success, then return 0; <br> | ||||
* If the key is updated success, then return the new version;<br> | * If the key is updated success, then return the new version;<br> | ||||
@@ -226,12 +224,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||||
* If updating is performed, the version of the key increase by 1. <br> | * If updating is performed, the version of the key increase by 1. <br> | ||||
* If creating is performed, the version of the key initialize by 0. <br> | * If creating is performed, the version of the key initialize by 0. <br> | ||||
* | * | ||||
* @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. <br> | * @return The new version of the key. <br> | ||||
* If the key is new created success, then return 0; <br> | * If the key is new created success, then return 0; <br> | ||||
* If the key is updated success, then return the new version;<br> | * If the key is updated success, then return the new version;<br> | ||||
@@ -430,7 +425,12 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||||
if (latestVersion < 0) { | if (latestVersion < 0) { | ||||
return null; | 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) { | public VersioningKVEntry getDataEntry(Bytes key, long version) { | ||||
@@ -441,7 +441,12 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||||
return null; | return null; | ||||
} | } | ||||
version = version < 0 ? latestVersion : version; | 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) { | public MerkleDataEntry getMerkleEntry(Bytes key, long version) { | ||||
@@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core; | |||||
import com.jd.blockchain.crypto.PubKey; | import com.jd.blockchain.crypto.PubKey; | ||||
import com.jd.blockchain.ledger.ParticipantNode; | 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 { | public class ParticipantCertData implements ParticipantNode { | ||||
private int id; | private int id; | ||||
private String address; | |||||
private Bytes address; | |||||
private String name; | private String name; | ||||
private PubKey pubKey; | private PubKey pubKey; | ||||
@@ -26,14 +27,14 @@ public class ParticipantCertData implements ParticipantNode { | |||||
this.pubKey = participantNode.getPubKey(); | this.pubKey = participantNode.getPubKey(); | ||||
} | } | ||||
public ParticipantCertData(String address, String name, PubKey pubKey) { | |||||
public ParticipantCertData(Bytes address, String name, PubKey pubKey) { | |||||
this.address = address; | this.address = address; | ||||
this.name = name; | this.name = name; | ||||
this.pubKey = pubKey; | this.pubKey = pubKey; | ||||
} | } | ||||
@Override | @Override | ||||
public String getAddress() { | |||||
public Bytes getAddress() { | |||||
return address; | return address; | ||||
} | } | ||||
@@ -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 | * @param address | ||||
* @return | * @return | ||||
*/ | */ | ||||
public ParticipantNode getParticipant(String address) { | |||||
public ParticipantNode getParticipant(Bytes address) { | |||||
Bytes key = encodeKey(address); | Bytes key = encodeKey(address); | ||||
byte[] bytes = dataset.getValue(key); | byte[] bytes = dataset.getValue(key); | ||||
if (bytes == null) { | if (bytes == null) { | ||||
@@ -95,11 +94,11 @@ public class ParticipantDataSet implements Transactional, MerkleProvable { | |||||
} | } | ||||
return BinaryProtocol.decode(bytes); | return BinaryProtocol.decode(bytes); | ||||
} | } | ||||
public ParticipantNode[] getParticipants() { | 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]; | ParticipantNode[] pns = new ParticipantNode[bytes.length]; | ||||
for (int i = 0; i < pns.length; i++) { | for (int i = 0; i < pns.length; i++) { | ||||
pns[i] = BinaryProtocol.decode(bytes[i]); | pns[i] = BinaryProtocol.decode(bytes[i]); | ||||
} | } | ||||
@@ -17,7 +17,7 @@ public interface PrivilegeSet { | |||||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | @DataField(order = 1, primitiveType = PrimitiveType.BYTES) | ||||
LedgerPrivilege getLedgerPrivilege(); | LedgerPrivilege getLedgerPrivilege(); | ||||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||||
@DataField(order = 2, primitiveType = PrimitiveType.BYTES) | |||||
TransactionPrivilege getTransactionPrivilege(); | TransactionPrivilege getTransactionPrivilege(); | ||||
} | } |
@@ -12,11 +12,6 @@ import com.jd.blockchain.utils.Transactional; | |||||
public class RolePrivilegeDataSet implements Transactional, MerkleProvable, RolePrivilegeSettings { | public class RolePrivilegeDataSet implements Transactional, MerkleProvable, RolePrivilegeSettings { | ||||
/** | |||||
* 角色名称的最大 Unicode 字符数; | |||||
*/ | |||||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||||
private MerkleDataSet dataset; | private MerkleDataSet dataset; | ||||
public RolePrivilegeDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | public RolePrivilegeDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | ||||
@@ -60,22 +55,30 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||||
} | } | ||||
/** | /** | ||||
* 加入新的角色授权; <br> | |||||
* | |||||
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; | |||||
* | |||||
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符; | |||||
* @param ledgerPrivilege | |||||
* @param txPrivilege | |||||
* | |||||
*/ | */ | ||||
@Override | @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); | long nv = setRolePrivilege(roleAuth); | ||||
if (nv < 0) { | if (nv < 0) { | ||||
throw new LedgerException("Role[" + roleName + "] already exist!"); | 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); | roleAuth.getTransactionPrivilege().enable(permissions); | ||||
return setRolePrivilege(roleAuth); | return setRolePrivilege(roleAuth); | ||||
} | } | ||||
/** | /** | ||||
* 禁止角色指定的权限; <br> | * 禁止角色指定的权限; <br> | ||||
* 如果角色不存在,则返回 -1; | * 如果角色不存在,则返回 -1; | ||||
@@ -162,7 +165,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||||
roleAuth.getLedgerPrivilege().disable(permissions); | roleAuth.getLedgerPrivilege().disable(permissions); | ||||
return setRolePrivilege(roleAuth); | return setRolePrivilege(roleAuth); | ||||
} | } | ||||
/** | /** | ||||
* 禁止角色指定的权限; <br> | * 禁止角色指定的权限; <br> | ||||
* 如果角色不存在,则返回 -1; | * 如果角色不存在,则返回 -1; | ||||
@@ -248,7 +251,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||||
PrivilegeSet privilege = BinaryProtocol.decode(kv.getValue()); | PrivilegeSet privilege = BinaryProtocol.decode(kv.getValue()); | ||||
return new RolePrivileges(roleName, kv.getVersion(), privilege); | return new RolePrivileges(roleName, kv.getVersion(), privilege); | ||||
} | } | ||||
@Override | @Override | ||||
public RolePrivileges[] getRolePrivileges(int index, int count) { | public RolePrivileges[] getRolePrivileges(int index, int count) { | ||||
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); | VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); | ||||
@@ -256,8 +259,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||||
PrivilegeSet privilege; | PrivilegeSet privilege; | ||||
for (int i = 0; i < pns.length; i++) { | for (int i = 0; i < pns.length; i++) { | ||||
privilege = BinaryProtocol.decode(kvEntries[i].getValue()); | 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; | return pns; | ||||
} | } | ||||
@@ -3,6 +3,11 @@ package com.jd.blockchain.ledger.core; | |||||
import com.jd.blockchain.ledger.LedgerException; | import com.jd.blockchain.ledger.LedgerException; | ||||
public interface RolePrivilegeSettings { | public interface RolePrivilegeSettings { | ||||
/** | |||||
* 角色名称的最大 Unicode 字符数; | |||||
*/ | |||||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||||
long getRoleCount(); | long getRoleCount(); | ||||
@@ -15,7 +20,20 @@ public interface RolePrivilegeSettings { | |||||
* @param ledgerPrivilege | * @param ledgerPrivilege | ||||
* @param txPrivilege | * @param txPrivilege | ||||
*/ | */ | ||||
void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); | |||||
long addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); | |||||
/** | |||||
* 加入新的角色授权; <br> | |||||
* | |||||
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; | |||||
* | |||||
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode | |||||
* 字符; | |||||
* @param ledgerPermissions 给角色授予的账本权限列表; | |||||
* @param txPermissions 给角色授予的交易权限列表; | |||||
* @return | |||||
*/ | |||||
long addRolePrivilege(String roleName, LedgerPermission[] ledgerPermissions, TransactionPermission[] txPermissions); | |||||
/** | /** | ||||
* 更新角色授权; <br> | * 更新角色授权; <br> | ||||
@@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core; | |||||
import com.jd.blockchain.binaryproto.BinaryProtocol; | import com.jd.blockchain.binaryproto.BinaryProtocol; | ||||
import com.jd.blockchain.crypto.HashDigest; | import com.jd.blockchain.crypto.HashDigest; | ||||
import com.jd.blockchain.ledger.AuthorizationException; | |||||
import com.jd.blockchain.ledger.CryptoSetting; | import com.jd.blockchain.ledger.CryptoSetting; | ||||
import com.jd.blockchain.ledger.LedgerException; | import com.jd.blockchain.ledger.LedgerException; | ||||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | import com.jd.blockchain.storage.service.ExPolicyKVStorage; | ||||
@@ -11,12 +12,7 @@ import com.jd.blockchain.utils.Bytes; | |||||
import com.jd.blockchain.utils.Transactional; | import com.jd.blockchain.utils.Transactional; | ||||
public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleSettings { | public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleSettings { | ||||
/** | |||||
* 角色名称的最大 Unicode 字符数; | |||||
*/ | |||||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||||
private MerkleDataSet dataset; | private MerkleDataSet dataset; | ||||
public UserRoleDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | public UserRoleDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | ||||
@@ -55,7 +51,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||||
} | } | ||||
@Override | @Override | ||||
public long getRoleCount() { | |||||
public long getUserCount() { | |||||
return dataset.getDataCount(); | return dataset.getDataCount(); | ||||
} | } | ||||
@@ -74,7 +70,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||||
roleAuth.addRoles(roles); | roleAuth.addRoles(roles); | ||||
long nv = setUserRolesAuthorization(roleAuth); | long nv = setUserRolesAuthorization(roleAuth); | ||||
if (nv < 0) { | 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 | * @return | ||||
*/ | */ | ||||
private long setUserRolesAuthorization(UserRoles userRoles) { | 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); | byte[] rolesetBytes = BinaryProtocol.encode(userRoles, RoleSet.class); | ||||
return dataset.setValue(userRoles.getUserAddress(), rolesetBytes, userRoles.getVersion()); | return dataset.setValue(userRoles.getUserAddress(), rolesetBytes, userRoles.getVersion()); | ||||
} | } | ||||
@@ -100,7 +99,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||||
public void updateUserRoles(UserRoles userRoles) { | public void updateUserRoles(UserRoles userRoles) { | ||||
long nv = setUserRolesAuthorization(userRoles); | long nv = setUserRolesAuthorization(userRoles); | ||||
if (nv < 0) { | 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() + "] !"); | + "] failed due to wrong version[" + userRoles.getVersion() + "] !"); | ||||
} | } | ||||
} | } | ||||
@@ -146,7 +145,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||||
} | } | ||||
@Override | @Override | ||||
public UserRoles[] getRoleAuthorizations() { | |||||
public UserRoles[] getUserRoles() { | |||||
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); | VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); | ||||
UserRoles[] pns = new UserRoles[kvEntries.length]; | UserRoles[] pns = new UserRoles[kvEntries.length]; | ||||
RoleSet roleset; | RoleSet roleset; | ||||
@@ -5,7 +5,17 @@ import com.jd.blockchain.utils.Bytes; | |||||
public interface UserRoleSettings { | public interface UserRoleSettings { | ||||
long getRoleCount(); | |||||
/** | |||||
* 单一用户可被授权的角色数量的最大值; | |||||
*/ | |||||
public static final int MAX_ROLES_PER_USER = 20; | |||||
/** | |||||
* 进行了授权的用户的数量; | |||||
* | |||||
* @return | |||||
*/ | |||||
long getUserCount(); | |||||
/** | /** | ||||
* 加入新的用户角色授权; <br> | * 加入新的用户角色授权; <br> | ||||
@@ -48,6 +58,11 @@ public interface UserRoleSettings { | |||||
*/ | */ | ||||
UserRoles getUserRoles(Bytes userAddress); | UserRoles getUserRoles(Bytes userAddress); | ||||
UserRoles[] getRoleAuthorizations(); | |||||
/** | |||||
* 返回全部的用户授权; | |||||
* | |||||
* @return | |||||
*/ | |||||
UserRoles[] getUserRoles(); | |||||
} | } |
@@ -79,6 +79,10 @@ public class UserRoles implements RoleSet { | |||||
* @param roles | * @param roles | ||||
*/ | */ | ||||
public void setRoles(String[] roles) { | public void setRoles(String[] roles) { | ||||
TreeSet<String> rs = new TreeSet<String>(); | |||||
for (String r : roles) { | |||||
rs.add(r); | |||||
} | |||||
this.roles = rs; | |||||
} | } | ||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package test.com.jd.blockchain.ledger; | package test.com.jd.blockchain.ledger; | ||||
import static org.junit.Assert.assertArrayEquals; | |||||
import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||
import static org.junit.Assert.assertFalse; | import static org.junit.Assert.assertFalse; | ||||
import static org.junit.Assert.assertNotNull; | import static org.junit.Assert.assertNotNull; | ||||
@@ -9,7 +10,6 @@ import static org.junit.Assert.assertTrue; | |||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Random; | import java.util.Random; | ||||
import com.jd.blockchain.ledger.LedgerMetadata; | |||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.jd.blockchain.crypto.AddressEncoding; | 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.crypto.service.sm.SMCryptoService; | ||||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | import com.jd.blockchain.ledger.BlockchainKeyGenerator; | ||||
import com.jd.blockchain.ledger.BlockchainKeypair; | 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.ParticipantNode; | ||||
import com.jd.blockchain.ledger.core.CryptoConfig; | import com.jd.blockchain.ledger.core.CryptoConfig; | ||||
import com.jd.blockchain.ledger.core.LedgerAdminAccount; | import com.jd.blockchain.ledger.core.LedgerAdminAccount; | ||||
import com.jd.blockchain.ledger.core.LedgerConfiguration; | 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.storage.service.utils.MemoryKVStorage; | ||||
import com.jd.blockchain.transaction.ConsensusParticipantData; | import com.jd.blockchain.transaction.ConsensusParticipantData; | ||||
import com.jd.blockchain.transaction.LedgerInitSettingData; | import com.jd.blockchain.transaction.LedgerInitSettingData; | ||||
import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
import com.jd.blockchain.utils.io.BytesUtils; | |||||
import com.jd.blockchain.utils.net.NetworkAddress; | import com.jd.blockchain.utils.net.NetworkAddress; | ||||
public class LedgerAdminAccountTest { | public class LedgerAdminAccountTest { | ||||
@@ -40,7 +48,7 @@ public class LedgerAdminAccountTest { | |||||
private Random rand = new Random(); | private Random rand = new Random(); | ||||
@Test | @Test | ||||
public void test() { | |||||
public void testSerialization() { | |||||
String keyPrefix = ""; | String keyPrefix = ""; | ||||
LedgerInitSettingData initSetting = new LedgerInitSettingData(); | LedgerInitSettingData initSetting = new LedgerInitSettingData(); | ||||
ConsensusParticipantData[] parties = new ConsensusParticipantData[5]; | ConsensusParticipantData[] parties = new ConsensusParticipantData[5]; | ||||
@@ -49,7 +57,7 @@ public class LedgerAdminAccountTest { | |||||
bckeys[i] = BlockchainKeyGenerator.getInstance().generate(); | bckeys[i] = BlockchainKeyGenerator.getInstance().generate(); | ||||
parties[i] = new ConsensusParticipantData(); | parties[i] = new ConsensusParticipantData(); | ||||
parties[i].setId(i); | 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].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); | ||||
parties[i].setName("Participant[" + i + "]"); | parties[i].setName("Participant[" + i + "]"); | ||||
parties[i].setPubKey(bckeys[i].getPubKey()); | parties[i].setPubKey(bckeys[i].getPubKey()); | ||||
@@ -66,7 +74,6 @@ public class LedgerAdminAccountTest { | |||||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | ||||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | ||||
} | } | ||||
CryptoConfig cryptoSetting = new CryptoConfig(); | CryptoConfig cryptoSetting = new CryptoConfig(); | ||||
cryptoSetting.setSupportedProviders(supportedProviders); | cryptoSetting.setSupportedProviders(supportedProviders); | ||||
cryptoSetting.setAutoVerifyHash(true); | cryptoSetting.setAutoVerifyHash(true); | ||||
@@ -83,12 +90,20 @@ public class LedgerAdminAccountTest { | |||||
LedgerAdminAccount ledgerAdminAccount = new LedgerAdminAccount(initSetting, keyPrefix, testStorage, | LedgerAdminAccount ledgerAdminAccount = new LedgerAdminAccount(initSetting, keyPrefix, testStorage, | ||||
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; | // New created instance is updated until being committed; | ||||
assertTrue(ledgerAdminAccount.isUpdated()); | assertTrue(ledgerAdminAccount.isUpdated()); | ||||
// Hash of account is null until being committed; | // Hash of account is null until being committed; | ||||
assertNull(ledgerAdminAccount.getHash()); | assertNull(ledgerAdminAccount.getHash()); | ||||
LedgerMetadata meta = ledgerAdminAccount.getMetadata(); | |||||
LedgerMetadata_V2 meta = ledgerAdminAccount.getMetadata(); | |||||
assertNull(meta.getParticipantsHash()); | assertNull(meta.getParticipantsHash()); | ||||
// Commit, and check the storage keys; | // Commit, and check the storage keys; | ||||
@@ -101,83 +116,145 @@ public class LedgerAdminAccountTest { | |||||
meta = ledgerAdminAccount.getMetadata(); | meta = ledgerAdminAccount.getMetadata(); | ||||
assertNotNull(meta.getParticipantsHash()); | 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 | // Reload account from storage with readonly mode, and check the integrity of | ||||
// data; | // data; | ||||
HashDigest adminAccHash = ledgerAdminAccount.getHash(); | HashDigest adminAccHash = ledgerAdminAccount.getHash(); | ||||
LedgerAdminAccount reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, | |||||
LedgerAdminAccount reloadAdminAccount1 = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, | |||||
testStorage, true); | 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; | // verify realod settings of admin account; | ||||
verifyRealoadingSettings(reloadAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata()); | |||||
verifyRealoadingSettings(reloadAdminAccount1, adminAccHash, ledgerAdminAccount.getMetadata(), | |||||
ledgerAdminAccount.getSettings()); | |||||
// verify the consensus participant list; | // verify the consensus participant list; | ||||
verifyReadlingParities(reloadAdminAccount, parties1); | |||||
verifyRealoadingParities(reloadAdminAccount1, parties1); | |||||
// It will throw exeception because of this account is readonly; | // 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]; | byte[] newCsSettingBytes = new byte[64]; | ||||
rand.nextBytes(newCsSettingBytes); | rand.nextBytes(newCsSettingBytes); | ||||
newSetting.setConsensusSetting(new Bytes(newCsSettingBytes)); | newSetting.setConsensusSetting(new Bytes(newCsSettingBytes)); | ||||
newSetting.getCryptoSetting().setAutoVerifyHash(false); | 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; | // 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; | // 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; | // 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()); | assertFalse(actualAccount.isUpdated()); | ||||
assertTrue(actualAccount.isReadonly()); | assertTrue(actualAccount.isReadonly()); | ||||
assertEquals(expHash, actualAccount.getHash()); | |||||
assertEquals(expAccRootHash, actualAccount.getHash()); | |||||
// verify metadata; | // 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()); | assertEquals(expParties.length, actualAccount.getParticipantCount()); | ||||
ParticipantNode[] actualPaticipants = actualAccount.getParticipants(); | ParticipantNode[] actualPaticipants = actualAccount.getParticipants(); | ||||
assertEquals(expParties.length, actualPaticipants.length); | 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(); | ConsensusParticipantData newParti = new ConsensusParticipantData(); | ||||
newParti.setId((int) actualAccount.getParticipantCount()); | |||||
newParti.setId((int) readonlyAccount.getParticipantCount()); | |||||
newParti.setHostAddress( | 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() + "]"); | newParti.setName("Participant[" + newParti.getAddress() + "]"); | ||||
BlockchainKeypair newKey = BlockchainKeyGenerator.getInstance().generate(); | BlockchainKeypair newKey = BlockchainKeyGenerator.getInstance().generate(); | ||||
@@ -203,7 +285,7 @@ public class LedgerAdminAccountTest { | |||||
Throwable ex = null; | Throwable ex = null; | ||||
try { | try { | ||||
actualAccount.addParticipant(newParti); | |||||
readonlyAccount.addParticipant(newParti); | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
ex = e; | ex = e; | ||||
} | } | ||||
@@ -211,8 +293,8 @@ public class LedgerAdminAccountTest { | |||||
ex = null; | ex = null; | ||||
try { | try { | ||||
LedgerConfiguration newLedgerSetting = new LedgerConfiguration(actualAccount.getSettings()); | |||||
actualAccount.setLedgerSetting(newLedgerSetting); | |||||
LedgerConfiguration newLedgerSetting = new LedgerConfiguration(readonlyAccount.getSettings()); | |||||
readonlyAccount.setLedgerSetting(newLedgerSetting); | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
ex = e; | ex = e; | ||||
} | } | ||||
@@ -76,7 +76,7 @@ public class LedgerInitOperationTest { | |||||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | keys[i] = BlockchainKeyGenerator.getInstance().generate(); | ||||
parties[i] = new ConsensusParticipantData(); | parties[i] = new ConsensusParticipantData(); | ||||
// parties[i].setId(i); | // 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].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); | ||||
parties[i].setName("Participant[" + i + "]"); | parties[i].setName("Participant[" + i + "]"); | ||||
parties[i].setPubKey(keys[i].getPubKey()); | parties[i].setPubKey(keys[i].getPubKey()); | ||||
@@ -117,7 +117,7 @@ public class LedgerInitOperationTest { | |||||
for (int i = 0; i < parties.length; i++) { | for (int i = 0; i < parties.length; i++) { | ||||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | 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()); | "Participant[" + i + "]", keys[i].getPubKey()); | ||||
} | } | ||||
@@ -76,7 +76,7 @@ public class LedgerInitSettingSerializeTest { | |||||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | keys[i] = BlockchainKeyGenerator.getInstance().generate(); | ||||
parties[i] = new ConsensusParticipantData(); | parties[i] = new ConsensusParticipantData(); | ||||
// parties[i].setId(i); | // 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].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); | ||||
parties[i].setName("Participant[" + i + "]"); | parties[i].setName("Participant[" + i + "]"); | ||||
parties[i].setPubKey(keys[i].getPubKey()); | parties[i].setPubKey(keys[i].getPubKey()); | ||||
@@ -84,7 +84,7 @@ public class LedgerInitSettingSerializeTest { | |||||
ConsensusParticipantData[] parties1 = Arrays.copyOf(parties, 4); | ConsensusParticipantData[] parties1 = Arrays.copyOf(parties, 4); | ||||
ledgerInitSettingData.setConsensusParticipants(parties1); | ledgerInitSettingData.setConsensusParticipants(parties1); | ||||
byte[] encode = BinaryProtocol.encode(ledgerInitSettingData, LedgerInitSetting.class); | byte[] encode = BinaryProtocol.encode(ledgerInitSettingData, LedgerInitSetting.class); | ||||
LedgerInitSetting decode = BinaryProtocol.decode(encode); | LedgerInitSetting decode = BinaryProtocol.decode(encode); | ||||
@@ -121,7 +121,7 @@ public class LedgerInitSettingSerializeTest { | |||||
for (int i = 0; i < parties.length; i++) { | for (int i = 0; i < parties.length; i++) { | ||||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | 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()); | "Participant[" + i + "]", keys[i].getPubKey()); | ||||
} | } | ||||
@@ -209,7 +209,7 @@ public class LedgerManagerTest { | |||||
parties[0].setName("John"); | parties[0].setName("John"); | ||||
AsymmetricKeypair kp0 = signatureFunction.generateKeypair(); | AsymmetricKeypair kp0 = signatureFunction.generateKeypair(); | ||||
parties[0].setPubKey(kp0.getPubKey()); | 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[0].setHostAddress(new NetworkAddress("127.0.0.1", 9000)); | ||||
parties[1] = new ConsensusParticipantData(); | parties[1] = new ConsensusParticipantData(); | ||||
@@ -217,7 +217,7 @@ public class LedgerManagerTest { | |||||
parties[1].setName("Mary"); | parties[1].setName("Mary"); | ||||
AsymmetricKeypair kp1 = signatureFunction.generateKeypair(); | AsymmetricKeypair kp1 = signatureFunction.generateKeypair(); | ||||
parties[1].setPubKey(kp1.getPubKey()); | 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[1].setHostAddress(new NetworkAddress("127.0.0.1", 9010)); | ||||
parties[2] = new ConsensusParticipantData(); | parties[2] = new ConsensusParticipantData(); | ||||
@@ -225,7 +225,7 @@ public class LedgerManagerTest { | |||||
parties[2].setName("Jerry"); | parties[2].setName("Jerry"); | ||||
AsymmetricKeypair kp2 = signatureFunction.generateKeypair(); | AsymmetricKeypair kp2 = signatureFunction.generateKeypair(); | ||||
parties[2].setPubKey(kp2.getPubKey()); | 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[2].setHostAddress(new NetworkAddress("127.0.0.1", 9020)); | ||||
parties[3] = new ConsensusParticipantData(); | parties[3] = new ConsensusParticipantData(); | ||||
@@ -233,7 +233,7 @@ public class LedgerManagerTest { | |||||
parties[3].setName("Tom"); | parties[3].setName("Tom"); | ||||
AsymmetricKeypair kp3 = signatureFunction.generateKeypair(); | AsymmetricKeypair kp3 = signatureFunction.generateKeypair(); | ||||
parties[3].setPubKey(kp3.getPubKey()); | 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)); | parties[3].setHostAddress(new NetworkAddress("127.0.0.1", 9030)); | ||||
initSetting.setConsensusParticipants(parties); | initSetting.setConsensusParticipants(parties); | ||||
@@ -78,7 +78,7 @@ public class LedgerMetaDataTest { | |||||
// LedgerConfiguration ledgerConfiguration = new LedgerConfiguration(consensusProvider, | // LedgerConfiguration ledgerConfiguration = new LedgerConfiguration(consensusProvider, | ||||
// new Bytes(consensusSettingBytes), cryptoConfig); | // new Bytes(consensusSettingBytes), cryptoConfig); | ||||
HashDigest settingsHash = Crypto.getHashFunction("SHA256").hash(consensusSettingBytes); | HashDigest settingsHash = Crypto.getHashFunction("SHA256").hash(consensusSettingBytes); | ||||
LedgerAdminAccount.LedgerMetadataImpl ledgerMetadata = new LedgerAdminAccount.LedgerMetadataImpl(); | LedgerAdminAccount.LedgerMetadataImpl ledgerMetadata = new LedgerAdminAccount.LedgerMetadataImpl(); | ||||
ledgerMetadata.setSeed(seed); | ledgerMetadata.setSeed(seed); | ||||
@@ -188,7 +188,7 @@ public class LedgerMetaDataTest { | |||||
String name = "John"; | String name = "John"; | ||||
// NetworkAddress consensusAddress = new NetworkAddress("192.168.1.1", 9001, | // NetworkAddress consensusAddress = new NetworkAddress("192.168.1.1", 9001, | ||||
// false); | // false); | ||||
String address = AddressEncoding.generateAddress(pubKey).toBase58(); | |||||
Bytes address = AddressEncoding.generateAddress(pubKey); | |||||
ParticipantCertData participantCertData = new ParticipantCertData(address, name, pubKey); | ParticipantCertData participantCertData = new ParticipantCertData(address, name, pubKey); | ||||
// encode and decode | // encode and decode | ||||
@@ -72,7 +72,7 @@ public class LedgerTestUtils { | |||||
parties[i].setId(0); | parties[i].setId(0); | ||||
parties[i].setName("Parti-" + i); | parties[i].setName("Parti-" + i); | ||||
parties[i].setPubKey(partiKeys[i].getPubKey()); | 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)); | parties[i].setHostAddress(new NetworkAddress("192.168.1." + (10 + i), 9000)); | ||||
} | } | ||||
@@ -125,13 +125,13 @@ public class LedgerTestUtils { | |||||
return txReqBuilder.buildRequest(); | 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 txBuilder = new TxBuilder(ledgerHash); | ||||
txBuilder.dataAccounts().register(dataAccountID.getIdentity()); | txBuilder.dataAccounts().register(dataAccountID.getIdentity()); | ||||
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); | TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); | ||||
if (signers != null) { | if (signers != null) { | ||||
for (BlockchainKeypair signer : signers) { | for (BlockchainKeypair signer : signers) { | ||||
@@ -141,16 +141,17 @@ public class LedgerTestUtils { | |||||
if (nodeKeypair != null) { | if (nodeKeypair != null) { | ||||
txReqBuilder.signAsNode(nodeKeypair); | txReqBuilder.signAsNode(nodeKeypair); | ||||
} | } | ||||
return txReqBuilder.buildRequest(); | 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 txBuilder = new TxBuilder(ledgerHash); | ||||
txBuilder.dataAccount(dataAccountAddress).setText(key, value, version); | txBuilder.dataAccount(dataAccountAddress).setText(key, value, version); | ||||
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); | TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); | ||||
if (signers != null) { | if (signers != null) { | ||||
for (BlockchainKeypair signer : signers) { | for (BlockchainKeypair signer : signers) { | ||||
@@ -160,7 +161,7 @@ public class LedgerTestUtils { | |||||
if (nodeKeypair != null) { | if (nodeKeypair != null) { | ||||
txReqBuilder.signAsNode(nodeKeypair); | txReqBuilder.signAsNode(nodeKeypair); | ||||
} | } | ||||
return txReqBuilder.buildRequest(); | return txReqBuilder.buildRequest(); | ||||
} | } | ||||
@@ -58,6 +58,18 @@ public class MerkleDataSetTest { | |||||
mds.setValue("C", "C".getBytes(), -1); | mds.setValue("C", "C".getBytes(), -1); | ||||
mds.commit(); | 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(); | HashDigest root1 = mds.getRootHash(); | ||||
// 1个KV项的存储KEY的数量= 1 + 1(保存SN) + Merkle节点数量; | // 1个KV项的存储KEY的数量= 1 + 1(保存SN) + Merkle节点数量; | ||||
@@ -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)); | |||||
} | |||||
} |
@@ -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()); | |||||
} | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -9,7 +9,7 @@ import com.jd.blockchain.consts.DataCodes; | |||||
public interface LedgerAdminInfo { | public interface LedgerAdminInfo { | ||||
@DataField(order = 1, refContract = true) | @DataField(order = 1, refContract = true) | ||||
LedgerMetadata getMetadata(); | |||||
LedgerMetadata_V2 getMetadata(); | |||||
@DataField(order = 2, refContract = true) | @DataField(order = 2, refContract = true) | ||||
LedgerSettings getSettings(); | LedgerSettings getSettings(); | ||||
@@ -13,7 +13,7 @@ import com.jd.blockchain.crypto.HashDigest; | |||||
* @author huanghaiquan | * @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 { | public interface LedgerMetadata_V2 extends LedgerMetadata { | ||||
/** | /** | ||||
@@ -5,6 +5,7 @@ import com.jd.blockchain.binaryproto.DataField; | |||||
import com.jd.blockchain.binaryproto.PrimitiveType; | import com.jd.blockchain.binaryproto.PrimitiveType; | ||||
import com.jd.blockchain.consts.DataCodes; | import com.jd.blockchain.consts.DataCodes; | ||||
import com.jd.blockchain.crypto.PubKey; | import com.jd.blockchain.crypto.PubKey; | ||||
import com.jd.blockchain.utils.Bytes; | |||||
/** | /** | ||||
* 参与方节点; | * 参与方节点; | ||||
@@ -30,8 +31,8 @@ public interface ParticipantNode {// extends ConsensusNode, ParticipantInfo { | |||||
* | * | ||||
* @return | * @return | ||||
*/ | */ | ||||
@DataField(order = 1, primitiveType = PrimitiveType.TEXT) | |||||
String getAddress(); | |||||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||||
Bytes getAddress(); | |||||
/** | /** | ||||
* 参与者名称; | * 参与者名称; | ||||
@@ -2,13 +2,14 @@ package com.jd.blockchain.transaction; | |||||
import com.jd.blockchain.crypto.PubKey; | import com.jd.blockchain.crypto.PubKey; | ||||
import com.jd.blockchain.ledger.ParticipantNode; | import com.jd.blockchain.ledger.ParticipantNode; | ||||
import com.jd.blockchain.utils.Bytes; | |||||
import com.jd.blockchain.utils.net.NetworkAddress; | import com.jd.blockchain.utils.net.NetworkAddress; | ||||
public class ConsensusParticipantData implements ParticipantNode { | public class ConsensusParticipantData implements ParticipantNode { | ||||
private int id; | private int id; | ||||
private String address; | |||||
private Bytes address; | |||||
private String name; | private String name; | ||||
@@ -48,11 +49,11 @@ public class ConsensusParticipantData implements ParticipantNode { | |||||
this.pubKey = pubKey; | this.pubKey = pubKey; | ||||
} | } | ||||
public String getAddress() { | |||||
public Bytes getAddress() { | |||||
return address; | return address; | ||||
} | } | ||||
public void setAddress(String address) { | |||||
public void setAddress(Bytes address) { | |||||
this.address = address; | this.address = address; | ||||
} | } | ||||
@@ -16,7 +16,7 @@ public class ConsensusRealmImpl implements ConsensusRealm { | |||||
public ConsensusRealmImpl(ParticipantNode[] nodeList) { | public ConsensusRealmImpl(ParticipantNode[] nodeList) { | ||||
this.nodes = nodeList; | this.nodes = nodeList; | ||||
String[] addrs = new String[nodes.length]; | |||||
Bytes[] addrs = new Bytes[nodes.length]; | |||||
int i = 0; | int i = 0; | ||||
for (ParticipantNode n : nodes) { | for (ParticipantNode n : nodes) { | ||||
addrs[i++] = n.getAddress(); | addrs[i++] = n.getAddress(); | ||||
@@ -8,19 +8,41 @@ | |||||
*/ | */ | ||||
package com.jd.blockchain.sdk.converters; | 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.JSONArray; | ||||
import com.alibaba.fastjson.JSONObject; | import com.alibaba.fastjson.JSONObject; | ||||
import com.jd.blockchain.crypto.CryptoProvider; | import com.jd.blockchain.crypto.CryptoProvider; | ||||
import com.jd.blockchain.crypto.PubKey; | 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.Bytes; | ||||
import com.jd.blockchain.utils.codec.Base58Utils; | import com.jd.blockchain.utils.codec.Base58Utils; | ||||
import com.jd.blockchain.utils.codec.HexUtils; | import com.jd.blockchain.utils.codec.HexUtils; | ||||
import com.jd.blockchain.utils.io.BytesUtils; | 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 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 <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, 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 String 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, String address, String name, PubKey pubKey) { | |||||
this.id = id; | |||||
this.address = address; | |||||
this.name = name; | |||||
this.pubKey = pubKey; | |||||
} | |||||
@Override | |||||
public String 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; | |||||
} | |||||
} | |||||
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 < 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; | |||||
} | |||||
} | |||||
} | } |
@@ -12,11 +12,6 @@ import com.jd.blockchain.utils.io.BytesMap; | |||||
public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, KVStorageService, BytesMap<Bytes> { | public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, KVStorageService, BytesMap<Bytes> { | ||||
// private Set<String> keys = new HashSet<>(); | |||||
// private Set<String> keys = Collections.synchronizedSet(new HashSet<>()); | |||||
// private Map<String, Object> storageMap = new ConcurrentHashMap<>(); | |||||
private ExistancePolicyKVStorageMap exStorage = new ExistancePolicyKVStorageMap(); | private ExistancePolicyKVStorageMap exStorage = new ExistancePolicyKVStorageMap(); | ||||
private VersioningKVStorageMap verStorage = new VersioningKVStorageMap(); | private VersioningKVStorageMap verStorage = new VersioningKVStorageMap(); | ||||
@@ -38,10 +33,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, | |||||
@Override | @Override | ||||
public long set(Bytes key, byte[] value, long version) { | public long set(Bytes key, byte[] value, long version) { | ||||
return verStorage.set(key, value, version); | return verStorage.set(key, value, version); | ||||
// if (v > -1) { | |||||
// keys.add(key); | |||||
// } | |||||
// return v; | |||||
} | } | ||||
@Override | @Override | ||||
@@ -57,10 +48,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, | |||||
@Override | @Override | ||||
public boolean set(Bytes key, byte[] value, ExPolicy ex) { | public boolean set(Bytes key, byte[] value, ExPolicy ex) { | ||||
return exStorage.set(key, value, ex); | return exStorage.set(key, value, ex); | ||||
// if (ok) { | |||||
// keys.add(key); | |||||
// } | |||||
// return ok; | |||||
} | } | ||||
@Override | @Override | ||||
@@ -81,12 +68,10 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, | |||||
HashSet<Bytes> keySet = new HashSet<>(exStorage.keySet()); | HashSet<Bytes> keySet = new HashSet<>(exStorage.keySet()); | ||||
keySet.addAll(verStorage.keySet()); | keySet.addAll(verStorage.keySet()); | ||||
return keySet; | return keySet; | ||||
// return storageMap.keySet(); | |||||
} | } | ||||
public int getStorageCount() { | public int getStorageCount() { | ||||
return exStorage.getCount() + verStorage.getCount(); | return exStorage.getCount() + verStorage.getCount(); | ||||
// return storageMap.size(); | |||||
} | } | ||||
// public void printStoragedKeys() { | // public void printStoragedKeys() { | ||||
@@ -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; | |||||
} | |||||
} |
@@ -215,38 +215,6 @@ public class VersioningKVStorageMap implements VersioningKVStorage, BytesMap<Byt | |||||
} | } | ||||
} | } | ||||
} | } | ||||
private static 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; | |||||
} | |||||
} | |||||
// private static class CachedSetEntry implements VersioningKVEntry { | // private static class CachedSetEntry implements VersioningKVEntry { | ||||
// | // | ||||
@@ -6,16 +6,23 @@ import java.util.Map; | |||||
import java.util.Properties; | import java.util.Properties; | ||||
import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
import com.jd.blockchain.crypto.*; | |||||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||||
import com.jd.blockchain.ledger.ParticipantNode; | |||||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||||
import org.springframework.core.io.ClassPathResource; | import org.springframework.core.io.ClassPathResource; | ||||
import com.jd.blockchain.consensus.ConsensusProvider; | import com.jd.blockchain.consensus.ConsensusProvider; | ||||
import com.jd.blockchain.consensus.ConsensusSettings; | import com.jd.blockchain.consensus.ConsensusSettings; | ||||
import com.jd.blockchain.crypto.AddressEncoding; | |||||
import com.jd.blockchain.crypto.AsymmetricKeypair; | |||||
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.PrivKey; | |||||
import com.jd.blockchain.crypto.PubKey; | |||||
import com.jd.blockchain.crypto.SignatureDigest; | |||||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||||
import com.jd.blockchain.ledger.CryptoSetting; | import com.jd.blockchain.ledger.CryptoSetting; | ||||
import com.jd.blockchain.ledger.ParticipantNode; | |||||
import com.jd.blockchain.ledger.core.CryptoConfig; | import com.jd.blockchain.ledger.core.CryptoConfig; | ||||
import com.jd.blockchain.ledger.core.LedgerInitDecision; | import com.jd.blockchain.ledger.core.LedgerInitDecision; | ||||
import com.jd.blockchain.ledger.core.LedgerInitProposal; | import com.jd.blockchain.ledger.core.LedgerInitProposal; | ||||
@@ -29,6 +36,8 @@ import com.jd.blockchain.tools.initializer.Prompter; | |||||
import com.jd.blockchain.tools.initializer.web.InitConsensusServiceFactory; | import com.jd.blockchain.tools.initializer.web.InitConsensusServiceFactory; | ||||
import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | ||||
import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | ||||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||||
import com.jd.blockchain.utils.Bytes; | |||||
import com.jd.blockchain.utils.concurrent.ThreadInvoker; | import com.jd.blockchain.utils.concurrent.ThreadInvoker; | ||||
import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | ||||
import com.jd.blockchain.utils.io.FileUtils; | import com.jd.blockchain.utils.io.FileUtils; | ||||
@@ -229,7 +238,7 @@ public class Utils { | |||||
private int id; | private int id; | ||||
private String address; | |||||
private Bytes address; | |||||
private String name; | private String name; | ||||
@@ -243,7 +252,7 @@ public class Utils { | |||||
this.id = id; | this.id = id; | ||||
this.name = name; | this.name = name; | ||||
this.pubKey = pubKey; | this.pubKey = pubKey; | ||||
this.address = pubKey.toBase58(); | |||||
this.address = AddressEncoding.generateAddress(pubKey); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -252,7 +261,7 @@ public class Utils { | |||||
} | } | ||||
@Override | @Override | ||||
public String getAddress() { | |||||
public Bytes getAddress() { | |||||
return address; | return address; | ||||
} | } | ||||
@@ -166,7 +166,8 @@ public class LedgerInitCommand { | |||||
// generate binding config; | // generate binding config; | ||||
BindingConfig bindingConf = new BindingConfig(); | BindingConfig bindingConf = new BindingConfig(); | ||||
bindingConf.getParticipant().setAddress(ledgerInitProperties.getConsensusParticipant(currId).getAddress()); | |||||
bindingConf.getParticipant() | |||||
.setAddress(ledgerInitProperties.getConsensusParticipant(currId).getAddress().toBase58()); | |||||
String encodedPrivKey = KeyGenCommand.encodePrivKey(privKey, base58Pwd); | String encodedPrivKey = KeyGenCommand.encodePrivKey(privKey, base58Pwd); | ||||
bindingConf.getParticipant().setPk(encodedPrivKey); | bindingConf.getParticipant().setPk(encodedPrivKey); | ||||
bindingConf.getParticipant().setPassword(base58Pwd); | bindingConf.getParticipant().setPassword(base58Pwd); | ||||
@@ -9,12 +9,11 @@ import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import org.springframework.util.ResourceUtils; | |||||
import com.jd.blockchain.crypto.AddressEncoding; | import com.jd.blockchain.crypto.AddressEncoding; | ||||
import com.jd.blockchain.crypto.PubKey; | import com.jd.blockchain.crypto.PubKey; | ||||
import com.jd.blockchain.ledger.ParticipantNode; | import com.jd.blockchain.ledger.ParticipantNode; | ||||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | import com.jd.blockchain.tools.keygen.KeyGenCommand; | ||||
import com.jd.blockchain.utils.Bytes; | |||||
import com.jd.blockchain.utils.PropertiesUtils; | import com.jd.blockchain.utils.PropertiesUtils; | ||||
import com.jd.blockchain.utils.codec.HexUtils; | import com.jd.blockchain.utils.codec.HexUtils; | ||||
import com.jd.blockchain.utils.io.FileUtils; | import com.jd.blockchain.utils.io.FileUtils; | ||||
@@ -250,7 +249,7 @@ public class LedgerInitProperties { | |||||
private int id; | private int id; | ||||
private String address; | |||||
private Bytes address; | |||||
private String name; | private String name; | ||||
@@ -271,7 +270,7 @@ public class LedgerInitProperties { | |||||
} | } | ||||
@Override | @Override | ||||
public String getAddress() { | |||||
public Bytes getAddress() { | |||||
return address; | return address; | ||||
} | } | ||||
@@ -305,7 +304,7 @@ public class LedgerInitProperties { | |||||
public void setPubKey(PubKey pubKey) { | public void setPubKey(PubKey pubKey) { | ||||
this.pubKey = pubKey; | this.pubKey = pubKey; | ||||
this.address = AddressEncoding.generateAddress(pubKey).toBase58(); | |||||
this.address = AddressEncoding.generateAddress(pubKey); | |||||
} | } | ||||
} | } | ||||