Browse Source

Passed verification of the testcases for RolePrivilegeDataSet and UserRolesDataSet;

tags/1.1.0
huanghaiquan 5 years ago
parent
commit
cab12e9083
34 changed files with 889 additions and 577 deletions
  1. +1
    -0
      source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java
  2. +10
    -8
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java
  3. +2
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java
  4. +29
    -24
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java
  5. +4
    -3
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java
  6. +6
    -7
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantDataSet.java
  7. +1
    -1
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java
  8. +22
    -20
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataSet.java
  9. +19
    -1
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java
  10. +9
    -10
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java
  11. +17
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java
  12. +5
    -1
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java
  13. +139
    -57
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java
  14. +2
    -2
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java
  15. +3
    -3
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java
  16. +4
    -4
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java
  17. +2
    -2
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java
  18. +14
    -13
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java
  19. +12
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java
  20. +70
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/RolePrivilegeDataSetTest.java
  21. +62
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/UserRoleDataSetTest.java
  22. +17
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AuthorizationException.java
  23. +1
    -1
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerAdminInfo.java
  24. +1
    -1
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java
  25. +3
    -2
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java
  26. +4
    -3
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ConsensusParticipantData.java
  27. +1
    -1
      source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusRealmImpl.java
  28. +371
    -348
      source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
  29. +0
    -15
      source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java
  30. +35
    -0
      source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java
  31. +0
    -32
      source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java
  32. +17
    -8
      source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java
  33. +2
    -1
      source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitCommand.java
  34. +4
    -5
      source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java

+ 1
- 0
source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java View File

@@ -67,6 +67,7 @@ public interface DataCodes {

// contract types of metadata;
public static final int METADATA = 0x600;
public static final int METADATA_V2 = 0x601;
public static final int METADATA_INIT_SETTING = 0x610;



+ 10
- 8
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminAccount.java View File

@@ -25,6 +25,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo {
static {
DataContractRegistry.register(LedgerMetadata.class);
DataContractRegistry.register(LedgerMetadata_V2.class);
}
private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminAccount.class);
@@ -40,7 +41,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo {
private final Bytes rolePrivilegePrefix;
private final Bytes userRolePrefix;
private LedgerMetadata origMetadata;
private LedgerMetadata_V2 origMetadata;
private LedgerMetadataImpl metadata;
@@ -225,7 +226,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo {
return BinaryProtocol.encode(setting, LedgerSettings.class);
}
private LedgerMetadata loadAndVerifyMetadata(HashDigest adminAccountHash) {
private LedgerMetadata_V2 loadAndVerifyMetadata(HashDigest adminAccountHash) {
Bytes key = encodeMetadataKey(adminAccountHash);
byte[] bytes = storage.get(key);
HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm());
@@ -253,7 +254,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo {
* @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata()
*/
@Override
public LedgerMetadata getMetadata() {
public LedgerMetadata_V2 getMetadata() {
return metadata;
}
@@ -325,7 +326,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo {
@Override
public boolean isUpdated() {
return updated || participants.isUpdated();
return updated || participants.isUpdated() || rolePrivileges.isUpdated() || userRoles.isUpdated();
}
@Override
@@ -392,12 +393,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo {
updated = false;
}
private LedgerMetadata deserializeMetadata(byte[] bytes) {
private LedgerMetadata_V2 deserializeMetadata(byte[] bytes) {
return BinaryProtocol.decode(bytes);
}
private byte[] serializeMetadata(LedgerMetadataImpl config) {
return BinaryProtocol.encode(config, LedgerMetadata.class);
return BinaryProtocol.encode(config, LedgerMetadata_V2.class);
}
@Override
@@ -426,11 +427,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo {
public LedgerMetadataImpl() {
}
public LedgerMetadataImpl(LedgerMetadata metadata) {
public LedgerMetadataImpl(LedgerMetadata_V2 metadata) {
this.seed = metadata.getSeed();
// this.setting = metadata.getSetting();
this.participantsHash = metadata.getParticipantsHash();
this.settingsHash = metadata.getSettingsHash();
this.rolePrivilegesHash = metadata.getRolePrivilegesHash();
this.userRolesHash = metadata.getUserRolesHash();
}
@Override


+ 2
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerPermission.java View File

@@ -15,10 +15,10 @@ import com.jd.blockchain.consts.DataCodes;
public enum LedgerPermission {

/**
* 设置角色权限;<br>
* 授权角色权限;<br>
* 包括:创建角色、设置角色的权限代码、分配用户角色;
*/
SET_ROLE_PERMISSION((byte) 0x01),
AUTHORIZE_ROLES((byte) 0x01),

/**
* 设置共识协议;<br>


+ 29
- 24
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java View File

@@ -8,6 +8,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy;
import com.jd.blockchain.storage.service.VersioningKVEntry;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.storage.service.utils.BufferedKVStorage;
import com.jd.blockchain.storage.service.utils.VersioningKVData;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
import com.jd.blockchain.utils.io.BytesUtils;
@@ -62,12 +63,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable {
/**
* 创建一个新的 MerkleDataSet;
*
* @param setting
* 密码设置;
* @param exPolicyStorage
* 默克尔树的存储;
* @param versioningStorage
* 数据的存储;
* @param setting 密码设置;
* @param exPolicyStorage 默克尔树的存储;
* @param versioningStorage 数据的存储;
*/
public MerkleDataSet(CryptoSetting setting, String keyPrefix, ExPolicyKVStorage exPolicyStorage,
VersioningKVStorage versioningStorage) {
@@ -149,7 +147,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable {
}
return values;
}
public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) {
if (count > LedgerConsts.MAX_LIST_COUNT) {
throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!");
@@ -158,16 +156,19 @@ public class MerkleDataSet implements Transactional, MerkleProvable {
throw new IllegalArgumentException("Index out of bound!");
}
VersioningKVEntry[] values = new VersioningKVEntry[count];
byte[] bytesValue;
for (int i = 0; i < count; i++) {
MerkleDataNode dataNode = merkleTree.getData(fromIndex + i);
Bytes dataKey = encodeDataKey(dataNode.getKey());
values[i] = valueStorage.getEntry(dataKey, dataNode.getVersion());
bytesValue = valueStorage.get(dataKey, dataNode.getVersion());
values[i] = new VersioningKVData(dataNode.getKey(), dataNode.getVersion(), bytesValue);
}
return values;
}
/**
* get the data at the specific index;
*
* @param fromIndex
* @return
*/
@@ -179,15 +180,15 @@ public class MerkleDataSet implements Transactional, MerkleProvable {
/**
* get the key at the specific index;
*
* @param fromIndex
* @return
*/
public String getKeyAtIndex(int fromIndex) {
MerkleDataNode dataNode = merkleTree.getData(fromIndex);
return new String(dataNode.getKey().toBytes());
return new String(dataNode.getKey().toBytes());
}
/**
* Create or update the value associated the specified key if the version
* checking is passed.<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 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>
* If the key is new created success, then return 0; <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 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>
* If the key is new created success, then return 0; <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) {
return null;
}
return valueStorage.getEntry(key, latestVersion);
Bytes dataKey = encodeDataKey(key);
byte[] value = valueStorage.get(dataKey, latestVersion);
if (value == null) {
return null;
}
return new VersioningKVData(key, latestVersion, value);
}
public VersioningKVEntry getDataEntry(Bytes key, long version) {
@@ -441,7 +441,12 @@ public class MerkleDataSet implements Transactional, MerkleProvable {
return null;
}
version = version < 0 ? latestVersion : version;
return valueStorage.getEntry(key, version);
Bytes dataKey = encodeDataKey(key);
byte[] value = valueStorage.get(dataKey, version);
if (value == null) {
return null;
}
return new VersioningKVData(key, version, value);
}
public MerkleDataEntry getMerkleEntry(Bytes key, long version) {


+ 4
- 3
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java View File

@@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.utils.Bytes;
/**
* 参与方证书数据对象;
@@ -12,7 +13,7 @@ import com.jd.blockchain.ledger.ParticipantNode;
public class ParticipantCertData implements ParticipantNode {
private int id;
private String address;
private Bytes address;
private String name;
private PubKey pubKey;
@@ -26,14 +27,14 @@ public class ParticipantCertData implements ParticipantNode {
this.pubKey = participantNode.getPubKey();
}
public ParticipantCertData(String address, String name, PubKey pubKey) {
public ParticipantCertData(Bytes address, String name, PubKey pubKey) {
this.address = address;
this.name = name;
this.pubKey = pubKey;
}
@Override
public String getAddress() {
public Bytes getAddress() {
return address;
}


+ 6
- 7
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantDataSet.java View File

@@ -73,9 +73,8 @@ public class ParticipantDataSet implements Transactional, MerkleProvable {
}
}

private Bytes encodeKey(String address) {
// return id + "";
return Bytes.fromString(address);
private Bytes encodeKey(Bytes address) {
return address;
}

/**
@@ -87,7 +86,7 @@ public class ParticipantDataSet implements Transactional, MerkleProvable {
* @param address
* @return
*/
public ParticipantNode getParticipant(String address) {
public ParticipantNode getParticipant(Bytes address) {
Bytes key = encodeKey(address);
byte[] bytes = dataset.getValue(key);
if (bytes == null) {
@@ -95,11 +94,11 @@ public class ParticipantDataSet implements Transactional, MerkleProvable {
}
return BinaryProtocol.decode(bytes);
}
public ParticipantNode[] getParticipants() {
byte[][] bytes = dataset.getLatestValues(0, (int)dataset.getDataCount());
byte[][] bytes = dataset.getLatestValues(0, (int) dataset.getDataCount());
ParticipantNode[] pns = new ParticipantNode[bytes.length];
for (int i = 0; i < pns.length; i++) {
pns[i] = BinaryProtocol.decode(bytes[i]);
}


+ 1
- 1
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/PrivilegeSet.java View File

@@ -17,7 +17,7 @@ public interface PrivilegeSet {
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
LedgerPrivilege getLedgerPrivilege();

@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
@DataField(order = 2, primitiveType = PrimitiveType.BYTES)
TransactionPrivilege getTransactionPrivilege();

}

+ 22
- 20
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeDataSet.java View File

@@ -12,11 +12,6 @@ import com.jd.blockchain.utils.Transactional;

public class RolePrivilegeDataSet implements Transactional, MerkleProvable, RolePrivilegeSettings {

/**
* 角色名称的最大 Unicode 字符数;
*/
public static final int MAX_ROLE_NAME_LENGTH = 20;

private MerkleDataSet dataset;

public RolePrivilegeDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage,
@@ -60,22 +55,30 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role
}

/**
* 加入新的角色授权; <br>
*
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常;
*
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符;
* @param ledgerPrivilege
* @param txPrivilege
*
*/
@Override
public void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) {
RolePrivileges roleAuth = new RolePrivileges(roleName, -1, ledgerPrivilege,
txPrivilege);
public long addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) {
RolePrivileges roleAuth = new RolePrivileges(roleName, -1, ledgerPrivilege, txPrivilege);
long nv = setRolePrivilege(roleAuth);
if (nv < 0) {
throw new LedgerException("Role[" + roleName + "] already exist!");
}
return nv;
}

@Override
public long addRolePrivilege(String roleName, LedgerPermission[] ledgerPermissions,
TransactionPermission[] txPermissions) {
LedgerPrivilege ledgerPrivilege = new LedgerPrivilege();
for (LedgerPermission lp : ledgerPermissions) {
ledgerPrivilege.enable(lp);
}
TransactionPrivilege txPrivilege = new TransactionPrivilege();
for (TransactionPermission tp : txPermissions) {
txPrivilege.enable(tp);
}
return addRolePrivilege(roleName, ledgerPrivilege, txPrivilege);
}

/**
@@ -144,7 +147,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role
roleAuth.getTransactionPrivilege().enable(permissions);
return setRolePrivilege(roleAuth);
}
/**
* 禁止角色指定的权限; <br>
* 如果角色不存在,则返回 -1;
@@ -162,7 +165,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role
roleAuth.getLedgerPrivilege().disable(permissions);
return setRolePrivilege(roleAuth);
}
/**
* 禁止角色指定的权限; <br>
* 如果角色不存在,则返回 -1;
@@ -248,7 +251,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role
PrivilegeSet privilege = BinaryProtocol.decode(kv.getValue());
return new RolePrivileges(roleName, kv.getVersion(), privilege);
}
@Override
public RolePrivileges[] getRolePrivileges(int index, int count) {
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count);
@@ -256,8 +259,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role
PrivilegeSet privilege;
for (int i = 0; i < pns.length; i++) {
privilege = BinaryProtocol.decode(kvEntries[i].getValue());
pns[i] = new RolePrivileges(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(),
privilege);
pns[i] = new RolePrivileges(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), privilege);
}
return pns;
}


+ 19
- 1
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/RolePrivilegeSettings.java View File

@@ -3,6 +3,11 @@ package com.jd.blockchain.ledger.core;
import com.jd.blockchain.ledger.LedgerException;

public interface RolePrivilegeSettings {
/**
* 角色名称的最大 Unicode 字符数;
*/
public static final int MAX_ROLE_NAME_LENGTH = 20;

long getRoleCount();

@@ -15,7 +20,20 @@ public interface RolePrivilegeSettings {
* @param ledgerPrivilege
* @param txPrivilege
*/
void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege);
long addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege);

/**
* 加入新的角色授权; <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>


+ 9
- 10
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleDataSet.java View File

@@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core;

import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.AuthorizationException;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
@@ -11,12 +12,7 @@ import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;

public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleSettings {

/**
* 角色名称的最大 Unicode 字符数;
*/
public static final int MAX_ROLE_NAME_LENGTH = 20;

private MerkleDataSet dataset;

public UserRoleDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage,
@@ -55,7 +51,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS
}

@Override
public long getRoleCount() {
public long getUserCount() {
return dataset.getDataCount();
}

@@ -74,7 +70,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS
roleAuth.addRoles(roles);
long nv = setUserRolesAuthorization(roleAuth);
if (nv < 0) {
throw new LedgerException("Roles authorization of User[" + userAddress + "] already exists!");
throw new AuthorizationException("Roles authorization of User[" + userAddress + "] already exists!");
}
}

@@ -86,6 +82,9 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS
* @return
*/
private long setUserRolesAuthorization(UserRoles userRoles) {
if (userRoles.getRoleCount() > MAX_ROLES_PER_USER) {
throw new AuthorizationException("The number of roles exceeds the maximum range!");
}
byte[] rolesetBytes = BinaryProtocol.encode(userRoles, RoleSet.class);
return dataset.setValue(userRoles.getUserAddress(), rolesetBytes, userRoles.getVersion());
}
@@ -100,7 +99,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS
public void updateUserRoles(UserRoles userRoles) {
long nv = setUserRolesAuthorization(userRoles);
if (nv < 0) {
throw new LedgerException("Update to roles of user[" + userRoles.getUserAddress()
throw new AuthorizationException("Update to roles of user[" + userRoles.getUserAddress()
+ "] failed due to wrong version[" + userRoles.getVersion() + "] !");
}
}
@@ -146,7 +145,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS
}

@Override
public UserRoles[] getRoleAuthorizations() {
public UserRoles[] getUserRoles() {
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount());
UserRoles[] pns = new UserRoles[kvEntries.length];
RoleSet roleset;


+ 17
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoleSettings.java View File

@@ -5,7 +5,17 @@ import com.jd.blockchain.utils.Bytes;

public interface UserRoleSettings {

long getRoleCount();
/**
* 单一用户可被授权的角色数量的最大值;
*/
public static final int MAX_ROLES_PER_USER = 20;

/**
* 进行了授权的用户的数量;
*
* @return
*/
long getUserCount();

/**
* 加入新的用户角色授权; <br>
@@ -48,6 +58,11 @@ public interface UserRoleSettings {
*/
UserRoles getUserRoles(Bytes userAddress);

UserRoles[] getRoleAuthorizations();
/**
* 返回全部的用户授权;
*
* @return
*/
UserRoles[] getUserRoles();

}

+ 5
- 1
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserRoles.java View File

@@ -79,6 +79,10 @@ public class UserRoles implements RoleSet {
* @param roles
*/
public void setRoles(String[] roles) {

TreeSet<String> rs = new TreeSet<String>();
for (String r : roles) {
rs.add(r);
}
this.roles = rs;
}
}

+ 139
- 57
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerAdminAccountTest.java View File

@@ -1,5 +1,6 @@
package test.com.jd.blockchain.ledger;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -9,7 +10,6 @@ import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Random;

import com.jd.blockchain.ledger.LedgerMetadata;
import org.junit.Test;

import com.jd.blockchain.crypto.AddressEncoding;
@@ -21,15 +21,23 @@ import com.jd.blockchain.crypto.service.classic.ClassicCryptoService;
import com.jd.blockchain.crypto.service.sm.SMCryptoService;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.LedgerMetadata_V2;
import com.jd.blockchain.ledger.LedgerSettings;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.core.CryptoConfig;
import com.jd.blockchain.ledger.core.LedgerAdminAccount;
import com.jd.blockchain.ledger.core.LedgerConfiguration;
import com.jd.blockchain.ledger.core.LedgerPermission;
import com.jd.blockchain.ledger.core.RolePrivilegeSettings;
import com.jd.blockchain.ledger.core.RolePrivileges;
import com.jd.blockchain.ledger.core.RolesPolicy;
import com.jd.blockchain.ledger.core.TransactionPermission;
import com.jd.blockchain.ledger.core.UserRoleSettings;
import com.jd.blockchain.ledger.core.UserRoles;
import com.jd.blockchain.storage.service.utils.MemoryKVStorage;
import com.jd.blockchain.transaction.ConsensusParticipantData;
import com.jd.blockchain.transaction.LedgerInitSettingData;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.io.BytesUtils;
import com.jd.blockchain.utils.net.NetworkAddress;

public class LedgerAdminAccountTest {
@@ -40,7 +48,7 @@ public class LedgerAdminAccountTest {
private Random rand = new Random();

@Test
public void test() {
public void testSerialization() {
String keyPrefix = "";
LedgerInitSettingData initSetting = new LedgerInitSettingData();
ConsensusParticipantData[] parties = new ConsensusParticipantData[5];
@@ -49,7 +57,7 @@ public class LedgerAdminAccountTest {
bckeys[i] = BlockchainKeyGenerator.getInstance().generate();
parties[i] = new ConsensusParticipantData();
parties[i].setId(i);
parties[i].setAddress(AddressEncoding.generateAddress(bckeys[i].getPubKey()).toBase58());
parties[i].setAddress(AddressEncoding.generateAddress(bckeys[i].getPubKey()));
parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i));
parties[i].setName("Participant[" + i + "]");
parties[i].setPubKey(bckeys[i].getPubKey());
@@ -66,7 +74,6 @@ public class LedgerAdminAccountTest {
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) {
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]);
}

CryptoConfig cryptoSetting = new CryptoConfig();
cryptoSetting.setSupportedProviders(supportedProviders);
cryptoSetting.setAutoVerifyHash(true);
@@ -83,12 +90,20 @@ public class LedgerAdminAccountTest {
LedgerAdminAccount ledgerAdminAccount = new LedgerAdminAccount(initSetting, keyPrefix, testStorage,
testStorage);

ledgerAdminAccount.getRolePrivileges().addRolePrivilege("DEFAULT",
new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.REGISTER_USER,
LedgerPermission.APPROVE_TX },
new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION,
TransactionPermission.CONTRACT_OPERATION });

ledgerAdminAccount.getUserRoles().addUserRoles(parties[0].getAddress(), RolesPolicy.UNION, "DEFAULT");

// New created instance is updated until being committed;
assertTrue(ledgerAdminAccount.isUpdated());
// Hash of account is null until being committed;
assertNull(ledgerAdminAccount.getHash());

LedgerMetadata meta = ledgerAdminAccount.getMetadata();
LedgerMetadata_V2 meta = ledgerAdminAccount.getMetadata();
assertNull(meta.getParticipantsHash());

// Commit, and check the storage keys;
@@ -101,83 +116,145 @@ public class LedgerAdminAccountTest {

meta = ledgerAdminAccount.getMetadata();
assertNotNull(meta.getParticipantsHash());
assertNotNull(meta.getSettingsHash());
assertNotNull(meta.getRolePrivilegesHash());
assertNotNull(meta.getUserRolesHash());
assertNotNull(ledgerAdminAccount.getRolePrivileges().getRolePrivilege("DEFAULT"));

// ----------------------
// Reload account from storage with readonly mode, and check the integrity of
// data;
HashDigest adminAccHash = ledgerAdminAccount.getHash();
LedgerAdminAccount reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage,
LedgerAdminAccount reloadAdminAccount1 = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage,
testStorage, true);

LedgerMetadata_V2 meta2 = reloadAdminAccount1.getMetadata();
assertNotNull(meta2.getParticipantsHash());
assertNotNull(meta2.getSettingsHash());
assertNotNull(meta2.getRolePrivilegesHash());
assertNotNull(meta2.getUserRolesHash());
// verify realod settings of admin account;
verifyRealoadingSettings(reloadAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata());

verifyRealoadingSettings(reloadAdminAccount1, adminAccHash, ledgerAdminAccount.getMetadata(),
ledgerAdminAccount.getSettings());
// verify the consensus participant list;
verifyReadlingParities(reloadAdminAccount, parties1);

verifyRealoadingParities(reloadAdminAccount1, parties1);
// It will throw exeception because of this account is readonly;
verifyReadonlyState(reloadAdminAccount);
verifyReadonlyState(reloadAdminAccount1);

verifyRealoadingRoleAuthorizations(reloadAdminAccount1, ledgerAdminAccount.getRolePrivileges(),
ledgerAdminAccount.getUserRoles());

// --------------
// reload again with writing mode;
reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, false);
LedgerConfiguration newSetting = new LedgerConfiguration(reloadAdminAccount.getPreviousSetting());
// 重新加载,并进行修改;
LedgerAdminAccount reloadAdminAccount2 = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, false);
LedgerConfiguration newSetting = new LedgerConfiguration(reloadAdminAccount2.getPreviousSetting());
byte[] newCsSettingBytes = new byte[64];
rand.nextBytes(newCsSettingBytes);
newSetting.setConsensusSetting(new Bytes(newCsSettingBytes));
newSetting.getCryptoSetting().setAutoVerifyHash(false);
reloadAdminAccount.setLedgerSetting(newSetting);
reloadAdminAccount2.setLedgerSetting(newSetting);

reloadAdminAccount2.addParticipant(parties[4]);

reloadAdminAccount2.getRolePrivileges().addRolePrivilege("ADMIN",
new LedgerPermission[] { LedgerPermission.APPROVE_TX },
new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION });

reloadAdminAccount2.getRolePrivileges().disablePermissions("DEFAULT", TransactionPermission.CONTRACT_OPERATION);

reloadAdminAccount2.getUserRoles().addUserRoles(parties[1].getAddress(), RolesPolicy.UNION, "DEFAULT", "ADMIN");

reloadAdminAccount.addParticipant(parties[4]);
reloadAdminAccount.commit();
reloadAdminAccount2.commit();

LedgerSettings newlyLedgerSettings = reloadAdminAccount2.getSettings();

// record the new account hash;
HashDigest newAccHash = reloadAdminAccount.getHash();
LedgerMetadata newMeta = reloadAdminAccount.getMetadata();
HashDigest newAccHash = reloadAdminAccount2.getHash();
LedgerMetadata_V2 newMeta = reloadAdminAccount2.getMetadata();

// load the last version of account and verify again;
reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, true);
verifyRealoadingSettings(reloadAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata());
verifyReadlingParities(reloadAdminAccount, parties1);
verifyReadonlyState(reloadAdminAccount);
LedgerAdminAccount previousAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage,
testStorage, true);
verifyRealoadingSettings(previousAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata(),
ledgerAdminAccount.getSettings());
verifyRealoadingParities(previousAdminAccount, parties1);
verifyReadonlyState(previousAdminAccount);

// load the hash of new committing;
reloadAdminAccount = new LedgerAdminAccount(newAccHash, keyPrefix, testStorage, testStorage, true);
verifyRealoadingSettings(reloadAdminAccount, newAccHash, newMeta);
verifyReadlingParities(reloadAdminAccount, parties);
verifyReadonlyState(reloadAdminAccount);
// System.out.println("========= [LedgerAdminAccount Test] Show generated
// storage keys... =======");
// testStorage.printStoragedKeys();
LedgerAdminAccount newlyAdminAccount = new LedgerAdminAccount(newAccHash, keyPrefix, testStorage, testStorage,
true);
verifyRealoadingSettings(newlyAdminAccount, newAccHash, newMeta, newlyLedgerSettings);
verifyRealoadingParities(newlyAdminAccount, parties);
verifyReadonlyState(newlyAdminAccount);
// System.out.println("========= [LedgerAdminAccount Test] Show generated storage keys... =======");
// testStorage.printStoragedKeys();
}

private void verifyRealoadingSettings(LedgerAdminAccount actualAccount, HashDigest expHash,
LedgerMetadata expMeta) {
private void verifyRealoadingSettings(LedgerAdminAccount actualAccount, HashDigest expAccRootHash,
LedgerMetadata_V2 expMeta, LedgerSettings expLedgerSettings) {
// 验证基本信息;
assertFalse(actualAccount.isUpdated());
assertTrue(actualAccount.isReadonly());

assertEquals(expHash, actualAccount.getHash());
assertEquals(expAccRootHash, actualAccount.getHash());

// verify metadata;
LedgerMetadata rlmeta = actualAccount.getMetadata();
assertEquals(expMeta.getParticipantsHash(), rlmeta.getParticipantsHash());

assertTrue(BytesUtils.equals(expMeta.getSeed(), rlmeta.getSeed()));

assertNotNull(rlmeta.getSettingsHash());
assertEquals(expMeta.getSettingsHash(), rlmeta.getSettingsHash());
// assertTrue(expMeta.getSettings().getConsensusSetting().equals(rlmeta.getSettings().getConsensusSetting()));
// assertEquals(expMeta.getSettings().getConsensusProvider(), rlmeta.getSettings().getConsensusProvider());
//
// assertEquals(expMeta.getSettings().getCryptoSetting().getAutoVerifyHash(),
// rlmeta.getSettings().getCryptoSetting().getAutoVerifyHash());
// assertEquals(expMeta.getSettings().getCryptoSetting().getHashAlgorithm(),
// rlmeta.getSettings().getCryptoSetting().getHashAlgorithm());
LedgerMetadata_V2 actualMeta = actualAccount.getMetadata();
assertArrayEquals(expMeta.getSeed(), actualMeta.getSeed());
assertEquals(expMeta.getParticipantsHash(), actualMeta.getParticipantsHash());
assertNotNull(actualMeta.getSettingsHash());
assertEquals(expMeta.getSettingsHash(), actualMeta.getSettingsHash());
assertNotNull(actualMeta.getRolePrivilegesHash());
assertEquals(expMeta.getRolePrivilegesHash(), actualMeta.getRolePrivilegesHash());
assertNotNull(actualMeta.getUserRolesHash());
assertEquals(expMeta.getUserRolesHash(), actualMeta.getUserRolesHash());

LedgerSettings actualLedgerSettings = actualAccount.getSettings();

assertEquals(expLedgerSettings.getConsensusSetting(), actualLedgerSettings.getConsensusSetting());
assertEquals(expLedgerSettings.getConsensusProvider(), actualLedgerSettings.getConsensusProvider());

assertEquals(expLedgerSettings.getCryptoSetting().getAutoVerifyHash(),
actualLedgerSettings.getCryptoSetting().getAutoVerifyHash());
assertEquals(expLedgerSettings.getCryptoSetting().getHashAlgorithm(),
actualLedgerSettings.getCryptoSetting().getHashAlgorithm());
}

private void verifyRealoadingRoleAuthorizations(LedgerAdminAccount actualAccount,
RolePrivilegeSettings expRolePrivilegeSettings, UserRoleSettings expUserRoleSettings) {
// 验证基本信息;
RolePrivilegeSettings actualRolePrivileges = actualAccount.getRolePrivileges();
RolePrivileges[] expRPs = expRolePrivilegeSettings.getRolePrivileges();

assertEquals(expRPs.length, actualRolePrivileges.getRoleCount());

for (RolePrivileges expRP : expRPs) {
RolePrivileges actualRP = actualRolePrivileges.getRolePrivilege(expRP.getRoleName());
assertNotNull(actualRP);
assertArrayEquals(expRP.getLedgerPrivilege().toBytes(), actualRP.getLedgerPrivilege().toBytes());
assertArrayEquals(expRP.getTransactionPrivilege().toBytes(), actualRP.getTransactionPrivilege().toBytes());
}

UserRoleSettings actualUserRoleSettings = actualAccount.getUserRoles();
UserRoles[] expUserRoles = expUserRoleSettings.getUserRoles();
assertEquals(expUserRoles.length, actualUserRoleSettings.getUserCount());

for (UserRoles expUR : expUserRoles) {
UserRoles actualUR = actualAccount.getUserRoles().getUserRoles(expUR.getUserAddress());
assertNotNull(actualUR);
assertEquals(expUR.getPolicy(), actualUR.getPolicy());
String[] expRoles = expUR.getRoles();
Arrays.sort(expRoles);
String[] actualRoles = actualUR.getRoles();
Arrays.sort(actualRoles);
assertArrayEquals(expRoles, actualRoles);
}
}

private void verifyReadlingParities(LedgerAdminAccount actualAccount, ParticipantNode[] expParties) {
private void verifyRealoadingParities(LedgerAdminAccount actualAccount, ParticipantNode[] expParties) {
assertEquals(expParties.length, actualAccount.getParticipantCount());
ParticipantNode[] actualPaticipants = actualAccount.getParticipants();
assertEquals(expParties.length, actualPaticipants.length);
@@ -191,11 +268,16 @@ public class LedgerAdminAccountTest {
}
}

private void verifyReadonlyState(LedgerAdminAccount actualAccount) {
/**
* 验证指定账户是否只读;
*
* @param readonlyAccount
*/
private void verifyReadonlyState(LedgerAdminAccount readonlyAccount) {
ConsensusParticipantData newParti = new ConsensusParticipantData();
newParti.setId((int) actualAccount.getParticipantCount());
newParti.setId((int) readonlyAccount.getParticipantCount());
newParti.setHostAddress(
new NetworkAddress("192.168.10." + (10 + newParti.getAddress()), 10010 + 10 * newParti.getId()));
new NetworkAddress("192.168.10." + (10 + newParti.getId()), 10010 + 10 * newParti.getId()));
newParti.setName("Participant[" + newParti.getAddress() + "]");

BlockchainKeypair newKey = BlockchainKeyGenerator.getInstance().generate();
@@ -203,7 +285,7 @@ public class LedgerAdminAccountTest {

Throwable ex = null;
try {
actualAccount.addParticipant(newParti);
readonlyAccount.addParticipant(newParti);
} catch (Exception e) {
ex = e;
}
@@ -211,8 +293,8 @@ public class LedgerAdminAccountTest {

ex = null;
try {
LedgerConfiguration newLedgerSetting = new LedgerConfiguration(actualAccount.getSettings());
actualAccount.setLedgerSetting(newLedgerSetting);
LedgerConfiguration newLedgerSetting = new LedgerConfiguration(readonlyAccount.getSettings());
readonlyAccount.setLedgerSetting(newLedgerSetting);
} catch (Exception e) {
ex = e;
}


+ 2
- 2
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitOperationTest.java View File

@@ -76,7 +76,7 @@ public class LedgerInitOperationTest {
keys[i] = BlockchainKeyGenerator.getInstance().generate();
parties[i] = new ConsensusParticipantData();
// parties[i].setId(i);
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58());
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()));
parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i));
parties[i].setName("Participant[" + i + "]");
parties[i].setPubKey(keys[i].getPubKey());
@@ -117,7 +117,7 @@ public class LedgerInitOperationTest {

for (int i = 0; i < parties.length; i++) {
keys[i] = BlockchainKeyGenerator.getInstance().generate();
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58(),
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()),
"Participant[" + i + "]", keys[i].getPubKey());
}



+ 3
- 3
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerInitSettingSerializeTest.java View File

@@ -76,7 +76,7 @@ public class LedgerInitSettingSerializeTest {
keys[i] = BlockchainKeyGenerator.getInstance().generate();
parties[i] = new ConsensusParticipantData();
// parties[i].setId(i);
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58());
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()));
parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i));
parties[i].setName("Participant[" + i + "]");
parties[i].setPubKey(keys[i].getPubKey());
@@ -84,7 +84,7 @@ public class LedgerInitSettingSerializeTest {
ConsensusParticipantData[] parties1 = Arrays.copyOf(parties, 4);

ledgerInitSettingData.setConsensusParticipants(parties1);
byte[] encode = BinaryProtocol.encode(ledgerInitSettingData, LedgerInitSetting.class);

LedgerInitSetting decode = BinaryProtocol.decode(encode);
@@ -121,7 +121,7 @@ public class LedgerInitSettingSerializeTest {

for (int i = 0; i < parties.length; i++) {
keys[i] = BlockchainKeyGenerator.getInstance().generate();
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58(),
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()),
"Participant[" + i + "]", keys[i].getPubKey());
}



+ 4
- 4
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java View File

@@ -209,7 +209,7 @@ public class LedgerManagerTest {
parties[0].setName("John");
AsymmetricKeypair kp0 = signatureFunction.generateKeypair();
parties[0].setPubKey(kp0.getPubKey());
parties[0].setAddress(AddressEncoding.generateAddress(kp0.getPubKey()).toBase58());
parties[0].setAddress(AddressEncoding.generateAddress(kp0.getPubKey()));
parties[0].setHostAddress(new NetworkAddress("127.0.0.1", 9000));

parties[1] = new ConsensusParticipantData();
@@ -217,7 +217,7 @@ public class LedgerManagerTest {
parties[1].setName("Mary");
AsymmetricKeypair kp1 = signatureFunction.generateKeypair();
parties[1].setPubKey(kp1.getPubKey());
parties[1].setAddress(AddressEncoding.generateAddress(kp1.getPubKey()).toBase58());
parties[1].setAddress(AddressEncoding.generateAddress(kp1.getPubKey()));
parties[1].setHostAddress(new NetworkAddress("127.0.0.1", 9010));

parties[2] = new ConsensusParticipantData();
@@ -225,7 +225,7 @@ public class LedgerManagerTest {
parties[2].setName("Jerry");
AsymmetricKeypair kp2 = signatureFunction.generateKeypair();
parties[2].setPubKey(kp2.getPubKey());
parties[2].setAddress(AddressEncoding.generateAddress(kp2.getPubKey()).toBase58());
parties[2].setAddress(AddressEncoding.generateAddress(kp2.getPubKey()));
parties[2].setHostAddress(new NetworkAddress("127.0.0.1", 9020));

parties[3] = new ConsensusParticipantData();
@@ -233,7 +233,7 @@ public class LedgerManagerTest {
parties[3].setName("Tom");
AsymmetricKeypair kp3 = signatureFunction.generateKeypair();
parties[3].setPubKey(kp3.getPubKey());
parties[3].setAddress(AddressEncoding.generateAddress(kp3.getPubKey()).toBase58());
parties[3].setAddress(AddressEncoding.generateAddress(kp3.getPubKey()));
parties[3].setHostAddress(new NetworkAddress("127.0.0.1", 9030));

initSetting.setConsensusParticipants(parties);


+ 2
- 2
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerMetaDataTest.java View File

@@ -78,7 +78,7 @@ public class LedgerMetaDataTest {
// LedgerConfiguration ledgerConfiguration = new LedgerConfiguration(consensusProvider,
// new Bytes(consensusSettingBytes), cryptoConfig);
HashDigest settingsHash = Crypto.getHashFunction("SHA256").hash(consensusSettingBytes);
LedgerAdminAccount.LedgerMetadataImpl ledgerMetadata = new LedgerAdminAccount.LedgerMetadataImpl();

ledgerMetadata.setSeed(seed);
@@ -188,7 +188,7 @@ public class LedgerMetaDataTest {
String name = "John";
// NetworkAddress consensusAddress = new NetworkAddress("192.168.1.1", 9001,
// false);
String address = AddressEncoding.generateAddress(pubKey).toBase58();
Bytes address = AddressEncoding.generateAddress(pubKey);
ParticipantCertData participantCertData = new ParticipantCertData(address, name, pubKey);

// encode and decode


+ 14
- 13
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java View File

@@ -72,7 +72,7 @@ public class LedgerTestUtils {
parties[i].setId(0);
parties[i].setName("Parti-" + i);
parties[i].setPubKey(partiKeys[i].getPubKey());
parties[i].setAddress(AddressEncoding.generateAddress(partiKeys[i].getPubKey()).toBase58());
parties[i].setAddress(AddressEncoding.generateAddress(partiKeys[i].getPubKey()));
parties[i].setHostAddress(new NetworkAddress("192.168.1." + (10 + i), 9000));

}
@@ -125,13 +125,13 @@ public class LedgerTestUtils {

return txReqBuilder.buildRequest();
}
public static TransactionRequest createTxRequest_DataAccountReg(BlockchainKeypair dataAccountID, HashDigest ledgerHash,
BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) {
public static TransactionRequest createTxRequest_DataAccountReg(BlockchainKeypair dataAccountID,
HashDigest ledgerHash, BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) {
TxBuilder txBuilder = new TxBuilder(ledgerHash);
txBuilder.dataAccounts().register(dataAccountID.getIdentity());
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
if (signers != null) {
for (BlockchainKeypair signer : signers) {
@@ -141,16 +141,17 @@ public class LedgerTestUtils {
if (nodeKeypair != null) {
txReqBuilder.signAsNode(nodeKeypair);
}
return txReqBuilder.buildRequest();
}
public static TransactionRequest createTxRequest_DataAccountWrite(Bytes dataAccountAddress, String key, String value, long version, HashDigest ledgerHash,
BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) {

public static TransactionRequest createTxRequest_DataAccountWrite(Bytes dataAccountAddress, String key,
String value, long version, HashDigest ledgerHash, BlockchainKeypair nodeKeypair,
BlockchainKeypair... signers) {
TxBuilder txBuilder = new TxBuilder(ledgerHash);
txBuilder.dataAccount(dataAccountAddress).setText(key, value, version);
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
if (signers != null) {
for (BlockchainKeypair signer : signers) {
@@ -160,7 +161,7 @@ public class LedgerTestUtils {
if (nodeKeypair != null) {
txReqBuilder.signAsNode(nodeKeypair);
}
return txReqBuilder.buildRequest();
}



+ 12
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/MerkleDataSetTest.java View File

@@ -58,6 +58,18 @@ public class MerkleDataSetTest {
mds.setValue("C", "C".getBytes(), -1);

mds.commit();

byte[] va = mds.getValue("A");
assertNotNull(va);
assertEquals("A", new String(va));
byte[] vc = mds.getValue("C");
VersioningKVEntry ventry = mds.getDataEntry("C");
assertNotNull(vc);
assertNotNull(ventry);
assertEquals("C", new String(vc));
assertEquals("C", ventry.getKey().toUTF8String());

HashDigest root1 = mds.getRootHash();

// 1个KV项的存储KEY的数量= 1 + 1(保存SN) + Merkle节点数量;


+ 70
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/RolePrivilegeDataSetTest.java View File

@@ -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));
}

}

+ 62
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/UserRoleDataSetTest.java View File

@@ -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());
}

}

+ 17
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/AuthorizationException.java View File

@@ -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);
}

}

+ 1
- 1
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerAdminInfo.java View File

@@ -9,7 +9,7 @@ import com.jd.blockchain.consts.DataCodes;
public interface LedgerAdminInfo {

@DataField(order = 1, refContract = true)
LedgerMetadata getMetadata();
LedgerMetadata_V2 getMetadata();

@DataField(order = 2, refContract = true)
LedgerSettings getSettings();


+ 1
- 1
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerMetadata_V2.java View File

@@ -13,7 +13,7 @@ import com.jd.blockchain.crypto.HashDigest;
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.METADATA, name = "LEDGER-METADATA-V2")
@DataContract(code = DataCodes.METADATA_V2, name = "LEDGER-METADATA-V2")
public interface LedgerMetadata_V2 extends LedgerMetadata {

/**


+ 3
- 2
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ParticipantNode.java View File

@@ -5,6 +5,7 @@ import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.utils.Bytes;

/**
* 参与方节点;
@@ -30,8 +31,8 @@ public interface ParticipantNode {// extends ConsensusNode, ParticipantInfo {
*
* @return
*/
@DataField(order = 1, primitiveType = PrimitiveType.TEXT)
String getAddress();
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
Bytes getAddress();

/**
* 参与者名称;


+ 4
- 3
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ConsensusParticipantData.java View File

@@ -2,13 +2,14 @@ package com.jd.blockchain.transaction;

import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.net.NetworkAddress;

public class ConsensusParticipantData implements ParticipantNode {
private int id;
private String address;
private Bytes address;

private String name;

@@ -48,11 +49,11 @@ public class ConsensusParticipantData implements ParticipantNode {
this.pubKey = pubKey;
}

public String getAddress() {
public Bytes getAddress() {
return address;
}

public void setAddress(String address) {
public void setAddress(Bytes address) {
this.address = address;
}


+ 1
- 1
source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusRealmImpl.java View File

@@ -16,7 +16,7 @@ public class ConsensusRealmImpl implements ConsensusRealm {

public ConsensusRealmImpl(ParticipantNode[] nodeList) {
this.nodes = nodeList;
String[] addrs = new String[nodes.length];
Bytes[] addrs = new Bytes[nodes.length];
int i = 0;
for (ParticipantNode n : nodes) {
addrs[i++] = n.getAddress();


+ 371
- 348
source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java View File

@@ -8,19 +8,41 @@
*/
package com.jd.blockchain.sdk.converters;

import java.lang.reflect.Field;

import org.apache.commons.codec.binary.Base64;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jd.blockchain.crypto.CryptoProvider;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.transaction.*;
import com.jd.blockchain.ledger.BlockchainIdentityData;
import com.jd.blockchain.ledger.BytesData;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.BytesValueEncoding;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
import com.jd.blockchain.ledger.ContractEventSendOperation;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
import com.jd.blockchain.ledger.DataType;
import com.jd.blockchain.ledger.KVDataEntry;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.Operation;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.transaction.ContractCodeDeployOpTemplate;
import com.jd.blockchain.transaction.ContractEventSendOpTemplate;
import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate;
import com.jd.blockchain.transaction.DataAccountRegisterOpTemplate;
import com.jd.blockchain.transaction.KVData;
import com.jd.blockchain.transaction.LedgerInitOpTemplate;
import com.jd.blockchain.transaction.LedgerInitSettingData;
import com.jd.blockchain.transaction.UserRegisterOpTemplate;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.codec.Base58Utils;
import com.jd.blockchain.utils.codec.HexUtils;
import com.jd.blockchain.utils.io.BytesUtils;
import org.apache.commons.codec.binary.Base64;

import java.lang.reflect.Field;

/**
*
@@ -31,347 +53,348 @@ import java.lang.reflect.Field;

public class ClientResolveUtil {

public static KVDataEntry[] read(KVDataEntry[] kvDataEntries) {
if (kvDataEntries == null || kvDataEntries.length == 0) {
return kvDataEntries;
}
KVDataEntry[] resolveKvDataEntries = new KVDataEntry[kvDataEntries.length];
// kvDataEntries是代理对象,需要处理
for (int i = 0; i < kvDataEntries.length; i++) {
KVDataEntry kvDataEntry = kvDataEntries[i];
String key = kvDataEntry.getKey();
long version = kvDataEntry.getVersion();
DataType dataType = kvDataEntry.getType();
KvData innerKvData = new KvData(key, version, dataType);
Object valueObj = kvDataEntry.getValue();
switch (dataType) {
case NIL:
break;
case BYTES:
case TEXT:
case JSON:
innerKvData.setValue(valueObj.toString());
break;
case INT32:
innerKvData.setValue(Integer.parseInt(valueObj.toString()));
break;
case INT64:
innerKvData.setValue(Long.parseLong(valueObj.toString()));
break;
default:
throw new IllegalStateException("Unsupported value type[" + dataType + "] to resolve!");
}
resolveKvDataEntries[i] = innerKvData;
}
return resolveKvDataEntries;
}

public static Operation read(Operation operation) {

try {
// Class
Class<?> clazz = operation.getClass();
Field field = clazz.getSuperclass().getDeclaredField("h");
field.setAccessible(true);
Object object = field.get(operation);
if (object instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) object;
if (jsonObject.containsKey("accountID")) {
return convertDataAccountRegisterOperation(jsonObject);
} else if (jsonObject.containsKey("userID")) {
return convertUserRegisterOperation(jsonObject);
} else if (jsonObject.containsKey("contractID")) {
return convertContractCodeDeployOperation(jsonObject);
} else if (jsonObject.containsKey("writeSet")) {
return convertDataAccountKVSetOperation(jsonObject);
} else if (jsonObject.containsKey("initSetting")) {
return convertLedgerInitOperation(jsonObject);
} else if (jsonObject.containsKey("contractAddress")) {
return convertContractEventSendOperation(jsonObject);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}

return null;
}

public static Object readValueByBytesValue(BytesValue bytesValue) {
DataType dataType = bytesValue.getType();
Bytes saveVal = bytesValue.getValue();
Object showVal;
switch (dataType) {
case BYTES:
// return hex
showVal = HexUtils.encode(saveVal.toBytes());
break;
case TEXT:
case JSON:
showVal = saveVal.toUTF8String();
break;
case INT64:
showVal = BytesUtils.toLong(saveVal.toBytes());
break;
default:
showVal = HexUtils.encode(saveVal.toBytes());
break;
}
return showVal;
}

public static DataAccountRegisterOperation convertDataAccountRegisterOperation(JSONObject jsonObject) {
JSONObject account = jsonObject.getJSONObject("accountID");
return new DataAccountRegisterOpTemplate(blockchainIdentity(account));
}

public static DataAccountKVSetOperation convertDataAccountKVSetOperation(JSONObject jsonObject) {
// 写入集合处理
JSONArray writeSetObj = jsonObject.getJSONArray("writeSet");
JSONObject accountAddrObj = jsonObject.getJSONObject("accountAddress");
String addressBase58 = accountAddrObj.getString("value");
Bytes address = Bytes.fromBase58(addressBase58);

DataAccountKVSetOpTemplate kvOperation = new DataAccountKVSetOpTemplate(address);
for (int i = 0; i <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;
}
}
}

+ 0
- 15
source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/MemoryKVStorage.java View File

@@ -12,11 +12,6 @@ import com.jd.blockchain.utils.io.BytesMap;

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 VersioningKVStorageMap verStorage = new VersioningKVStorageMap();

@@ -38,10 +33,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage,
@Override
public long set(Bytes key, byte[] value, long version) {
return verStorage.set(key, value, version);
// if (v > -1) {
// keys.add(key);
// }
// return v;
}

@Override
@@ -57,10 +48,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage,
@Override
public boolean set(Bytes key, byte[] value, ExPolicy ex) {
return exStorage.set(key, value, ex);
// if (ok) {
// keys.add(key);
// }
// return ok;
}

@Override
@@ -81,12 +68,10 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage,
HashSet<Bytes> keySet = new HashSet<>(exStorage.keySet());
keySet.addAll(verStorage.keySet());
return keySet;
// return storageMap.keySet();
}

public int getStorageCount() {
return exStorage.getCount() + verStorage.getCount();
// return storageMap.size();
}

// public void printStoragedKeys() {


+ 35
- 0
source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVData.java View File

@@ -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;
}

}

+ 0
- 32
source/storage/storage-service/src/main/java/com/jd/blockchain/storage/service/utils/VersioningKVStorageMap.java View File

@@ -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 {
//


+ 17
- 8
source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java View File

@@ -6,16 +6,23 @@ import java.util.Map;
import java.util.Properties;
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 com.jd.blockchain.consensus.ConsensusProvider;
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.ParticipantNode;
import com.jd.blockchain.ledger.core.CryptoConfig;
import com.jd.blockchain.ledger.core.LedgerInitDecision;
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.LedgerInitConsensusService;
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.AsyncCallback;
import com.jd.blockchain.utils.io.FileUtils;
@@ -229,7 +238,7 @@ public class Utils {

private int id;

private String address;
private Bytes address;

private String name;

@@ -243,7 +252,7 @@ public class Utils {
this.id = id;
this.name = name;
this.pubKey = pubKey;
this.address = pubKey.toBase58();
this.address = AddressEncoding.generateAddress(pubKey);
}

@Override
@@ -252,7 +261,7 @@ public class Utils {
}

@Override
public String getAddress() {
public Bytes getAddress() {
return address;
}



+ 2
- 1
source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitCommand.java View File

@@ -166,7 +166,8 @@ public class LedgerInitCommand {

// generate binding config;
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);
bindingConf.getParticipant().setPk(encodedPrivKey);
bindingConf.getParticipant().setPassword(base58Pwd);


+ 4
- 5
source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java View File

@@ -9,12 +9,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.springframework.util.ResourceUtils;

import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.tools.keygen.KeyGenCommand;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.PropertiesUtils;
import com.jd.blockchain.utils.codec.HexUtils;
import com.jd.blockchain.utils.io.FileUtils;
@@ -250,7 +249,7 @@ public class LedgerInitProperties {

private int id;

private String address;
private Bytes address;

private String name;

@@ -271,7 +270,7 @@ public class LedgerInitProperties {
}

@Override
public String getAddress() {
public Bytes getAddress() {
return address;
}

@@ -305,7 +304,7 @@ public class LedgerInitProperties {

public void setPubKey(PubKey pubKey) {
this.pubKey = pubKey;
this.address = AddressEncoding.generateAddress(pubKey).toBase58();
this.address = AddressEncoding.generateAddress(pubKey);
}

}


Loading…
Cancel
Save