| @@ -8,12 +8,4 @@ | |||
| <version>1.1.0-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>base</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>org.slf4j</groupId> | |||
| <artifactId>slf4j-api</artifactId> | |||
| </dependency> | |||
| </dependencies> | |||
| </project> | |||
| @@ -75,7 +75,6 @@ | |||
| <dependency> | |||
| <groupId>commons-io</groupId> | |||
| <artifactId>commons-io</artifactId> | |||
| <version>${commons-io.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| @@ -98,18 +97,13 @@ | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-web</artifactId> | |||
| <exclusions> | |||
| <exclusion> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-logging</artifactId> | |||
| </exclusion> | |||
| </exclusions> | |||
| </dependency> | |||
| <dependency> | |||
| <!-- <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-log4j2</artifactId> | |||
| </dependency> | |||
| </dependency> --> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| @@ -1,7 +1,9 @@ | |||
| package com.jd.blockchain.ledger.core; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import java.util.Map.Entry; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import org.springframework.stereotype.Component; | |||
| @@ -10,26 +12,31 @@ import com.jd.blockchain.ledger.core.handles.ContractCodeDeployOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.DataAccountKVSetOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.DataAccountRegisterOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.JVMContractEventSendOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.RolesConfigureOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.UserAuthorizeOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.UserRegisterOperationHandle; | |||
| @Component | |||
| public class DefaultOperationHandleRegisteration implements OperationHandleRegisteration { | |||
| private List<OperationHandle> opHandles = new ArrayList<>(); | |||
| private static Map<Class<?>, OperationHandle> DEFAULT_HANDLES = new HashMap<>(); | |||
| public DefaultOperationHandleRegisteration() { | |||
| initDefaultHandles(); | |||
| private Map<Class<?>, OperationHandle> handles = new ConcurrentHashMap<>(); | |||
| private Map<Class<?>, OperationHandle> cacheMapping = new ConcurrentHashMap<>(); | |||
| static { | |||
| addDefaultHandle(new RolesConfigureOperationHandle()); | |||
| addDefaultHandle(new UserAuthorizeOperationHandle()); | |||
| addDefaultHandle(new DataAccountKVSetOperationHandle()); | |||
| addDefaultHandle(new DataAccountRegisterOperationHandle()); | |||
| addDefaultHandle(new UserRegisterOperationHandle()); | |||
| addDefaultHandle(new ContractCodeDeployOperationHandle()); | |||
| addDefaultHandle(new JVMContractEventSendOperationHandle()); | |||
| } | |||
| /** | |||
| * 针对不采用bean依赖注入的方式来处理; | |||
| */ | |||
| private void initDefaultHandles() { | |||
| opHandles.add(new DataAccountKVSetOperationHandle()); | |||
| opHandles.add(new DataAccountRegisterOperationHandle()); | |||
| opHandles.add(new UserRegisterOperationHandle()); | |||
| opHandles.add(new ContractCodeDeployOperationHandle()); | |||
| opHandles.add(new JVMContractEventSendOperationHandle()); | |||
| private static void addDefaultHandle(OperationHandle handle) { | |||
| DEFAULT_HANDLES.put(handle.getOperationType(), handle); | |||
| } | |||
| /** | |||
| @@ -37,9 +44,32 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis | |||
| * | |||
| * @param handle | |||
| */ | |||
| public void insertAsTopPriority(OperationHandle handle) { | |||
| opHandles.remove(handle); | |||
| opHandles.add(0, handle); | |||
| public void registerHandle(OperationHandle handle) { | |||
| handles.put(handle.getOperationType(), handle); | |||
| } | |||
| private OperationHandle getRegisteredHandle(Class<?> operationType) { | |||
| OperationHandle hdl = handles.get(operationType); | |||
| if (hdl == null) { | |||
| for (Entry<Class<?>, OperationHandle> entry : handles.entrySet()) { | |||
| if (entry.getKey().isAssignableFrom(operationType)) { | |||
| hdl = entry.getValue(); | |||
| } | |||
| } | |||
| } | |||
| return hdl; | |||
| } | |||
| private OperationHandle getDefaultHandle(Class<?> operationType) { | |||
| OperationHandle hdl = DEFAULT_HANDLES.get(operationType); | |||
| if (hdl == null) { | |||
| for (Entry<Class<?>, OperationHandle> entry : DEFAULT_HANDLES.entrySet()) { | |||
| if (entry.getKey().isAssignableFrom(operationType)) { | |||
| hdl = entry.getValue(); | |||
| } | |||
| } | |||
| } | |||
| return hdl; | |||
| } | |||
| /* | |||
| @@ -51,12 +81,19 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis | |||
| */ | |||
| @Override | |||
| public OperationHandle getHandle(Class<?> operationType) { | |||
| for (OperationHandle handle : opHandles) { | |||
| if (handle.support(operationType)) { | |||
| return handle; | |||
| OperationHandle hdl = cacheMapping.get(operationType); | |||
| if (hdl != null) { | |||
| return hdl; | |||
| } | |||
| hdl = getRegisteredHandle(operationType); | |||
| if (hdl == null) { | |||
| hdl = getDefaultHandle(operationType); | |||
| if (hdl == null) { | |||
| throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
| } | |||
| } | |||
| throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
| cacheMapping.put(operationType, hdl); | |||
| return hdl; | |||
| } | |||
| } | |||
| @@ -16,7 +16,7 @@ import com.jd.blockchain.ledger.LedgerMetadata_V2; | |||
| import com.jd.blockchain.ledger.LedgerSettings; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
| import com.jd.blockchain.ledger.UserRoleSettings; | |||
| import com.jd.blockchain.ledger.UserRolesSettings; | |||
| import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
| import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; | |||
| import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
| @@ -105,7 +105,7 @@ public class LedgerAdminDataset implements Transactional, LedgerAdminInfo { | |||
| } | |||
| @Override | |||
| public UserRoleSettings getUserRoles() { | |||
| public UserRolesSettings getUserRoles() { | |||
| return userRoles; | |||
| } | |||
| @@ -14,7 +14,7 @@ import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
| import com.jd.blockchain.ledger.RolePrivileges; | |||
| import com.jd.blockchain.ledger.RolesPolicy; | |||
| import com.jd.blockchain.ledger.TransactionPermission; | |||
| import com.jd.blockchain.ledger.UserRoleSettings; | |||
| import com.jd.blockchain.ledger.UserRolesSettings; | |||
| import com.jd.blockchain.ledger.UserRoles; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| @@ -28,7 +28,7 @@ public class LedgerSecurityManagerImpl implements LedgerSecurityManager { | |||
| private RolePrivilegeSettings rolePrivilegeSettings; | |||
| private UserRoleSettings userRolesSettings; | |||
| private UserRolesSettings userRolesSettings; | |||
| // 用户的权限配置 | |||
| private Map<Bytes, UserRolesPrivileges> userPrivilegesCache = new ConcurrentHashMap<>(); | |||
| @@ -36,7 +36,7 @@ public class LedgerSecurityManagerImpl implements LedgerSecurityManager { | |||
| private Map<Bytes, UserRoles> userRolesCache = new ConcurrentHashMap<>(); | |||
| private Map<String, RolePrivileges> rolesPrivilegeCache = new ConcurrentHashMap<>(); | |||
| public LedgerSecurityManagerImpl(RolePrivilegeSettings rolePrivilegeSettings, UserRoleSettings userRolesSettings) { | |||
| public LedgerSecurityManagerImpl(RolePrivilegeSettings rolePrivilegeSettings, UserRolesSettings userRolesSettings) { | |||
| this.rolePrivilegeSettings = rolePrivilegeSettings; | |||
| this.userRolesSettings = userRolesSettings; | |||
| } | |||
| @@ -11,7 +11,7 @@ public interface OperationHandle { | |||
| * @param operationType | |||
| * @return | |||
| */ | |||
| boolean support(Class<?> operationType); | |||
| Class<?> getOperationType(); | |||
| /** | |||
| * 同步解析和执行操作; | |||
| @@ -283,4 +283,10 @@ public class RolePrivilegeDataset implements Transactional, MerkleProvable, Role | |||
| public boolean isReadonly() { | |||
| return dataset.isReadonly(); | |||
| } | |||
| @Override | |||
| public boolean contains(String roleName) { | |||
| Bytes key = encodeKey(roleName); | |||
| return dataset.getVersion(key) > -1; | |||
| } | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| package com.jd.blockchain.ledger.core; | |||
| import java.util.Collection; | |||
| import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.AuthorizationException; | |||
| @@ -7,8 +9,8 @@ import com.jd.blockchain.ledger.CryptoSetting; | |||
| import com.jd.blockchain.ledger.LedgerException; | |||
| import com.jd.blockchain.ledger.RoleSet; | |||
| import com.jd.blockchain.ledger.RolesPolicy; | |||
| import com.jd.blockchain.ledger.UserRoleSettings; | |||
| import com.jd.blockchain.ledger.UserRoles; | |||
| import com.jd.blockchain.ledger.UserRolesSettings; | |||
| import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
| import com.jd.blockchain.storage.service.VersioningKVEntry; | |||
| import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
| @@ -21,7 +23,7 @@ import com.jd.blockchain.utils.Transactional; | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| public class UserRoleDataset implements Transactional, MerkleProvable, UserRoleSettings { | |||
| public class UserRoleDataset implements Transactional, MerkleProvable, UserRolesSettings { | |||
| private MerkleDataSet dataset; | |||
| @@ -84,6 +86,25 @@ public class UserRoleDataset implements Transactional, MerkleProvable, UserRoleS | |||
| } | |||
| } | |||
| /** | |||
| * 加入新的用户角色授权; <br> | |||
| * | |||
| * 如果该用户的授权已经存在,则引发 {@link LedgerException} 异常; | |||
| * | |||
| * @param userAddress | |||
| * @param rolesPolicy | |||
| * @param roles | |||
| */ | |||
| @Override | |||
| public void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, Collection<String> roles) { | |||
| UserRoles roleAuth = new UserRoles(userAddress, -1, rolesPolicy); | |||
| roleAuth.addRoles(roles); | |||
| long nv = setUserRolesAuthorization(roleAuth); | |||
| if (nv < 0) { | |||
| throw new AuthorizationException("Roles authorization of User[" + userAddress + "] already exists!"); | |||
| } | |||
| } | |||
| /** | |||
| * 设置用户角色授权; <br> | |||
| * 如果版本校验不匹配,则返回 -1; | |||
| @@ -32,9 +32,14 @@ public abstract class AbstractLedgerOperationHandle<T extends Operation> impleme | |||
| this.SUPPORTED_OPERATION_TYPE = supportedOperationType; | |||
| } | |||
| // @Override | |||
| // public final boolean support(Class<?> operationType) { | |||
| // return SUPPORTED_OPERATION_TYPE.isAssignableFrom(operationType); | |||
| // } | |||
| @Override | |||
| public final boolean support(Class<?> operationType) { | |||
| return SUPPORTED_OPERATION_TYPE.isAssignableFrom(operationType); | |||
| public Class<?> getOperationType() { | |||
| return SUPPORTED_OPERATION_TYPE; | |||
| } | |||
| @Override | |||
| @@ -22,11 +22,11 @@ import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
| import com.jd.blockchain.ledger.core.TransactionRequestExtension; | |||
| @Service | |||
| public abstract class AbtractContractEventHandle implements OperationHandle { | |||
| public abstract class AbtractContractEventSendOperationHandle implements OperationHandle { | |||
| @Override | |||
| public boolean support(Class<?> operationType) { | |||
| return ContractEventSendOperation.class.isAssignableFrom(operationType); | |||
| public Class<?> getOperationType() { | |||
| return ContractEventSendOperation.class; | |||
| } | |||
| @Override | |||
| @@ -1,13 +1,13 @@ | |||
| package com.jd.blockchain.ledger.core.handles; | |||
| import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; | |||
| import com.jd.blockchain.contract.engine.ContractCode; | |||
| import com.jd.blockchain.contract.engine.ContractEngine; | |||
| import com.jd.blockchain.contract.engine.ContractServiceProviders; | |||
| import com.jd.blockchain.ledger.core.ContractAccount; | |||
| import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; | |||
| public class JVMContractEventSendOperationHandle extends AbtractContractEventHandle { | |||
| public class JVMContractEventSendOperationHandle extends AbtractContractEventSendOperationHandle { | |||
| private static final ContractEngine JVM_ENGINE; | |||
| @@ -0,0 +1,49 @@ | |||
| package com.jd.blockchain.ledger.core.handles; | |||
| import com.jd.blockchain.ledger.LedgerPermission; | |||
| import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
| import com.jd.blockchain.ledger.RolePrivileges; | |||
| import com.jd.blockchain.ledger.RolesConfigureOperation; | |||
| import com.jd.blockchain.ledger.RolesConfigureOperation.RolePrivilegeEntry; | |||
| import com.jd.blockchain.ledger.core.LedgerDataset; | |||
| import com.jd.blockchain.ledger.core.LedgerService; | |||
| import com.jd.blockchain.ledger.core.MultiIdsPolicy; | |||
| import com.jd.blockchain.ledger.core.OperationHandleContext; | |||
| import com.jd.blockchain.ledger.core.SecurityContext; | |||
| import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
| import com.jd.blockchain.ledger.core.TransactionRequestExtension; | |||
| public class RolesConfigureOperationHandle extends AbstractLedgerOperationHandle<RolesConfigureOperation> { | |||
| public RolesConfigureOperationHandle() { | |||
| super(RolesConfigureOperation.class); | |||
| } | |||
| @Override | |||
| protected void doProcess(RolesConfigureOperation operation, LedgerDataset newBlockDataset, | |||
| TransactionRequestExtension request, LedgerDataset previousBlockDataset, | |||
| OperationHandleContext handleContext, LedgerService ledgerService) { | |||
| // 权限校验; | |||
| SecurityPolicy securityPolicy = SecurityContext.getContextUsersPolicy(); | |||
| securityPolicy.checkEndpoints(LedgerPermission.CONFIGURE_ROLES, MultiIdsPolicy.AT_LEAST_ONE); | |||
| // 操作账本; | |||
| RolePrivilegeEntry[] rpcfgs = operation.getRoles(); | |||
| RolePrivilegeSettings rpSettings = newBlockDataset.getAdminDataset().getRolePrivileges(); | |||
| if (rpcfgs != null) { | |||
| for (RolePrivilegeEntry rpcfg : rpcfgs) { | |||
| RolePrivileges rp = rpSettings.getRolePrivilege(rpcfg.getRoleName()); | |||
| if (rp == null) { | |||
| rpSettings.addRolePrivilege(rpcfg.getRoleName(), rpcfg.getEnableLedgerPermissions(), | |||
| rpcfg.getEnableTransactionPermissions()); | |||
| } else { | |||
| rp.enable(rpcfg.getEnableLedgerPermissions()); | |||
| rp.enable(rpcfg.getEnableTransactionPermissions()); | |||
| rp.disable(rpcfg.getDisableLedgerPermissions()); | |||
| rp.disable(rpcfg.getDisableTransactionPermissions()); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,72 @@ | |||
| package com.jd.blockchain.ledger.core.handles; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import com.jd.blockchain.ledger.LedgerPermission; | |||
| import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
| import com.jd.blockchain.ledger.RolesPolicy; | |||
| import com.jd.blockchain.ledger.UserAuthorizeOperation; | |||
| import com.jd.blockchain.ledger.UserAuthorizeOperation.UserRolesEntry; | |||
| import com.jd.blockchain.ledger.UserRoles; | |||
| import com.jd.blockchain.ledger.UserRolesSettings; | |||
| import com.jd.blockchain.ledger.core.LedgerDataset; | |||
| import com.jd.blockchain.ledger.core.LedgerService; | |||
| import com.jd.blockchain.ledger.core.MultiIdsPolicy; | |||
| import com.jd.blockchain.ledger.core.OperationHandleContext; | |||
| import com.jd.blockchain.ledger.core.SecurityContext; | |||
| import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
| import com.jd.blockchain.ledger.core.TransactionRequestExtension; | |||
| public class UserAuthorizeOperationHandle extends AbstractLedgerOperationHandle<UserAuthorizeOperation> { | |||
| public UserAuthorizeOperationHandle() { | |||
| super(UserAuthorizeOperation.class); | |||
| } | |||
| @Override | |||
| protected void doProcess(UserAuthorizeOperation operation, LedgerDataset newBlockDataset, | |||
| TransactionRequestExtension request, LedgerDataset previousBlockDataset, | |||
| OperationHandleContext handleContext, LedgerService ledgerService) { | |||
| // 权限校验; | |||
| SecurityPolicy securityPolicy = SecurityContext.getContextUsersPolicy(); | |||
| securityPolicy.checkEndpoints(LedgerPermission.CONFIGURE_ROLES, MultiIdsPolicy.AT_LEAST_ONE); | |||
| // 操作账本; | |||
| UserRolesEntry[] urcfgs = operation.getUserRolesAuthorizations(); | |||
| UserRolesSettings urSettings = newBlockDataset.getAdminDataset().getUserRoles(); | |||
| RolePrivilegeSettings rolesSettings = newBlockDataset.getAdminDataset().getRolePrivileges(); | |||
| if (urcfgs != null) { | |||
| for (UserRolesEntry urcfg : urcfgs) { | |||
| // | |||
| String[] authRoles = urcfg.getAuthorizedRoles(); | |||
| List<String> validRoles = new ArrayList<String>(); | |||
| if (authRoles != null) { | |||
| for (String r : authRoles) { | |||
| if (rolesSettings.contains(r)) { | |||
| validRoles.add(r); | |||
| } | |||
| } | |||
| } | |||
| UserRoles ur = urSettings.getUserRoles(urcfg.getUserAddress()); | |||
| if (ur == null) { | |||
| RolesPolicy policy = urcfg.getPolicy(); | |||
| if (policy == null) { | |||
| policy = RolesPolicy.UNION; | |||
| } | |||
| urSettings.addUserRoles(urcfg.getUserAddress(), policy, validRoles); | |||
| } else { | |||
| ur.addRoles(validRoles); | |||
| ur.removeRoles(urcfg.getUnauthorizedRoles()); | |||
| // 如果请求中设置了策略,才进行更新; | |||
| RolesPolicy policy = urcfg.getPolicy(); | |||
| if (policy != null) { | |||
| ur.setPolicy(policy); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,13 +1,12 @@ | |||
| package com.jd.blockchain.ledger.core.serialize; | |||
| import java.lang.reflect.Type; | |||
| import com.alibaba.fastjson.serializer.JSONSerializer; | |||
| import com.alibaba.fastjson.serializer.ObjectSerializer; | |||
| import com.alibaba.fastjson.serializer.SerializeWriter; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import java.lang.reflect.Type; | |||
| public class LedgerBlockSerializer implements ObjectSerializer { | |||
| @Override | |||
| @@ -8,10 +8,10 @@ import com.jd.blockchain.contract.engine.ContractCode; | |||
| import com.jd.blockchain.contract.jvm.AbstractContractCode; | |||
| import com.jd.blockchain.contract.jvm.ContractDefinition; | |||
| import com.jd.blockchain.ledger.core.ContractAccount; | |||
| import com.jd.blockchain.ledger.core.handles.AbtractContractEventHandle; | |||
| import com.jd.blockchain.ledger.core.handles.AbtractContractEventSendOperationHandle; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| public class ContractInvokingHandle extends AbtractContractEventHandle { | |||
| public class ContractInvokingHandle extends AbtractContractEventSendOperationHandle { | |||
| private Map<Bytes, ContractCode> contractInstances = new ConcurrentHashMap<Bytes, ContractCode>(); | |||
| @@ -61,7 +61,7 @@ public class ContractInvokingTest { | |||
| // 注册合约处理器; | |||
| DefaultOperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration(); | |||
| opReg.insertAsTopPriority(contractInvokingHandle); | |||
| opReg.registerHandle(contractInvokingHandle); | |||
| // 发布指定地址合约 | |||
| deploy(ledgerRepo, ledgerManager, opReg, ledgerHash, contractKey); | |||
| @@ -30,7 +30,7 @@ import com.jd.blockchain.ledger.RolePrivilegeSettings; | |||
| import com.jd.blockchain.ledger.RolePrivileges; | |||
| import com.jd.blockchain.ledger.RolesPolicy; | |||
| import com.jd.blockchain.ledger.TransactionPermission; | |||
| import com.jd.blockchain.ledger.UserRoleSettings; | |||
| import com.jd.blockchain.ledger.UserRolesSettings; | |||
| import com.jd.blockchain.ledger.UserRoles; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerAdminDataset; | |||
| @@ -92,7 +92,7 @@ public class LedgerAdminDatasetTest { | |||
| testStorage); | |||
| ledgerAdminDataset.getRolePrivileges().addRolePrivilege("DEFAULT", | |||
| new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.REGISTER_USER, | |||
| new LedgerPermission[] { LedgerPermission.CONFIGURE_ROLES, LedgerPermission.REGISTER_USER, | |||
| LedgerPermission.APPROVE_TX }, | |||
| new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION, | |||
| TransactionPermission.CONTRACT_OPERATION }); | |||
| @@ -225,7 +225,7 @@ public class LedgerAdminDatasetTest { | |||
| } | |||
| private void verifyRealoadingRoleAuthorizations(LedgerAdminInfo actualAccount, | |||
| RolePrivilegeSettings expRolePrivilegeSettings, UserRoleSettings expUserRoleSettings) { | |||
| RolePrivilegeSettings expRolePrivilegeSettings, UserRolesSettings expUserRoleSettings) { | |||
| // 验证基本信息; | |||
| RolePrivilegeSettings actualRolePrivileges = actualAccount.getRolePrivileges(); | |||
| RolePrivileges[] expRPs = expRolePrivilegeSettings.getRolePrivileges(); | |||
| @@ -239,7 +239,7 @@ public class LedgerAdminDatasetTest { | |||
| assertArrayEquals(expRP.getTransactionPrivilege().toBytes(), actualRP.getTransactionPrivilege().toBytes()); | |||
| } | |||
| UserRoleSettings actualUserRoleSettings = actualAccount.getUserRoles(); | |||
| UserRolesSettings actualUserRoleSettings = actualAccount.getUserRoles(); | |||
| UserRoles[] expUserRoles = expUserRoleSettings.getUserRoles(); | |||
| assertEquals(expUserRoles.length, actualUserRoleSettings.getUserCount()); | |||
| @@ -10,7 +10,7 @@ public interface LedgerAdminInfo { | |||
| ParticipantNode[] getParticipants(); | |||
| UserRoleSettings getUserRoles(); | |||
| UserRolesSettings getUserRoles(); | |||
| RolePrivilegeSettings getRolePrivileges(); | |||
| @@ -15,57 +15,61 @@ import com.jd.blockchain.consts.DataCodes; | |||
| public enum LedgerPermission { | |||
| /** | |||
| * 授权角色权限;<br> | |||
| * 包括:创建角色、设置角色的权限代码、分配用户角色; | |||
| * 配置角色的权限;<br> | |||
| */ | |||
| AUTHORIZE_ROLES((byte) 0x01), | |||
| CONFIGURE_ROLES((byte) 0x01), | |||
| /** | |||
| * 授权用户角色;<br> | |||
| */ | |||
| AUTHORIZE_USER_ROLES((byte) 0x02), | |||
| /** | |||
| * 设置共识协议;<br> | |||
| */ | |||
| SET_CONSENSUS((byte) 0x02), | |||
| SET_CONSENSUS((byte) 0x03), | |||
| /** | |||
| * 设置密码体系;<br> | |||
| */ | |||
| SET_CRYPTO((byte) 0x03), | |||
| SET_CRYPTO((byte) 0x04), | |||
| /** | |||
| * 注册参与方;<br> | |||
| */ | |||
| REGISTER_PARTICIPANT((byte) 0x04), | |||
| REGISTER_PARTICIPANT((byte) 0x05), | |||
| /** | |||
| * 注册用户;<br> | |||
| * | |||
| * 如果不具备此项权限,则无法注册用户; | |||
| */ | |||
| REGISTER_USER((byte) 0x05), | |||
| REGISTER_USER((byte) 0x11), | |||
| /** | |||
| * 注册数据账户;<br> | |||
| */ | |||
| REGISTER_DATA_ACCOUNT((byte) 0x06), | |||
| REGISTER_DATA_ACCOUNT((byte) 0x12), | |||
| /** | |||
| * 注册合约;<br> | |||
| */ | |||
| REGISTER_CONTRACT((byte) 0x07), | |||
| REGISTER_CONTRACT((byte) 0x13), | |||
| /** | |||
| * 升级合约 | |||
| */ | |||
| UPGRADE_CONTRACT((byte) 0x08), | |||
| UPGRADE_CONTRACT((byte) 0x14), | |||
| /** | |||
| * 设置用户属性;<br> | |||
| */ | |||
| SET_USER_ATTRIBUTES((byte) 0x09), | |||
| SET_USER_ATTRIBUTES((byte) 0x15), | |||
| /** | |||
| * 写入数据账户;<br> | |||
| */ | |||
| WRITE_DATA_ACCOUNT((byte) 0x0A), | |||
| WRITE_DATA_ACCOUNT((byte) 0x16), | |||
| /** | |||
| * 参与方核准交易;<br> | |||
| @@ -74,16 +78,14 @@ public enum LedgerPermission { | |||
| * <p> | |||
| * 只对交易请求的节点签名列表{@link TransactionRequest#getNodeSignatures()}的用户产生影响; | |||
| */ | |||
| APPROVE_TX((byte) 0x0B), | |||
| APPROVE_TX((byte) 0x0C), | |||
| /** | |||
| * 参与方共识交易;<br> | |||
| * | |||
| * 如果不具备此项权限,则无法作为共识节点接入并对交易进行共识; | |||
| */ | |||
| CONSENSUS_TX((byte) 0x0C); | |||
| CONSENSUS_TX((byte) 0x0D); | |||
| @EnumField(type = PrimitiveType.INT8) | |||
| public final byte CODE; | |||
| @@ -155,4 +155,6 @@ public interface RolePrivilegeSettings { | |||
| long disablePermissions(String roleName, LedgerPermission[] ledgerPermissions, | |||
| TransactionPermission[] txPermissions); | |||
| boolean contains(String r); | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| package com.jd.blockchain.ledger; | |||
| import java.util.Collection; | |||
| import java.util.Set; | |||
| import java.util.TreeSet; | |||
| @@ -72,6 +73,24 @@ public class UserRoles implements RoleSet { | |||
| } | |||
| } | |||
| public void addRoles(Collection<String> roles) { | |||
| for (String r : roles) { | |||
| this.roles.add(r); | |||
| } | |||
| } | |||
| public void removeRoles(String... roles) { | |||
| for (String r : roles) { | |||
| this.roles.remove(r); | |||
| } | |||
| } | |||
| public void removeRoles(Collection<String> roles) { | |||
| for (String r : roles) { | |||
| this.roles.remove(r); | |||
| } | |||
| } | |||
| /** | |||
| * 设置角色集合;<br> | |||
| * 注意,这不是追加;现有的不在参数指定范围的角色将被移除; | |||
| @@ -1,8 +1,10 @@ | |||
| package com.jd.blockchain.ledger; | |||
| import java.util.Collection; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| public interface UserRoleSettings { | |||
| public interface UserRolesSettings { | |||
| /** | |||
| * 单一用户可被授权的角色数量的最大值; | |||
| @@ -51,6 +53,17 @@ public interface UserRoleSettings { | |||
| * @param roles | |||
| */ | |||
| void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, String... roles); | |||
| /** | |||
| * 加入新的用户角色授权; <br> | |||
| * | |||
| * 如果该用户的授权已经存在,则引发 {@link LedgerException} 异常; | |||
| * | |||
| * @param userAddress | |||
| * @param rolesPolicy | |||
| * @param roles | |||
| */ | |||
| void addUserRoles(Bytes userAddress, RolesPolicy rolesPolicy, Collection<String> roles); | |||
| /** | |||
| * 更新用户角色授权; <br> | |||
| @@ -54,18 +54,12 @@ | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-web</artifactId> | |||
| <exclusions> | |||
| <exclusion> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-logging</artifactId> | |||
| </exclusion> | |||
| </exclusions> | |||
| </dependency> | |||
| <dependency> | |||
| <!-- <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-log4j2</artifactId> | |||
| </dependency> | |||
| </dependency> --> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| @@ -8,11 +8,6 @@ | |||
| <artifactId>spring-boot-starter-parent</artifactId> | |||
| <version>2.0.6.RELEASE</version> | |||
| </parent> | |||
| <!--<parent> --> | |||
| <!--<groupId>org.sonatype.oss</groupId> --> | |||
| <!--<artifactId>oss-parent</artifactId> --> | |||
| <!--<version>7</version> --> | |||
| <!--</parent> --> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>jdchain-root</artifactId> | |||
| @@ -45,9 +40,6 @@ | |||
| <explorer.version>0.7.0.RELEASE</explorer.version> | |||
| <ump-explorer.version>1.0.0-SNAPSHOT</ump-explorer.version> | |||
| <commons-io.version>2.4</commons-io.version> | |||
| <!-- <spring.framework.version>4.3.4.RELEASE</spring.framework.version> --> | |||
| <!-- <spring.mongo.version>1.9.3.RELEASE</spring.mongo.version> <spring.dao.version>2.0.8</spring.dao.version> | |||
| <spring.security.version>4.2.0.RELEASE</spring.security.version> --> | |||
| <mongo.driver.version>3.3.0</mongo.driver.version> | |||
| <shiro.version>1.2.2</shiro.version> | |||
| <aspectj.version>1.8.8</aspectj.version> | |||
| @@ -85,6 +77,10 @@ | |||
| </properties> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-logging</artifactId> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>junit</groupId> | |||
| <artifactId>junit</artifactId> | |||
| @@ -54,7 +54,7 @@ public class AssetContractImpl implements EventProcessingAware, AssetContract { | |||
| KVDataObject currTotal = (KVDataObject) kvEntries[0]; | |||
| long newTotal = currTotal.longValue() + amount; | |||
| eventContext.getLedger().dataAccount(ASSET_ADDRESS).setInt64(KEY_TOTAL, newTotal, currTotal.getVersion()); | |||
| // 分配到持有者账户; | |||
| KVDataObject holderAmount = (KVDataObject) kvEntries[1]; | |||
| long newHodlerAmount = holderAmount.longValue() + amount; | |||
| @@ -72,18 +72,18 @@ | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-web</artifactId> | |||
| <exclusions> | |||
| <!-- <exclusions> | |||
| <exclusion> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-logging</artifactId> | |||
| </exclusion> | |||
| </exclusions> | |||
| </exclusions> --> | |||
| </dependency> | |||
| <dependency> | |||
| <!-- <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-log4j2</artifactId> | |||
| </dependency> | |||
| </dependency> --> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| @@ -96,15 +96,18 @@ public class LedgerInitPropertiesTest { | |||
| TransactionPermission.CONTRACT_OPERATION }, roleDefault.getTransactionPermissions()); | |||
| RoleInitData roleAdmin = rolesInitDatas.get("ADMIN"); | |||
| assertArrayEquals(new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.SET_CONSENSUS, | |||
| LedgerPermission.SET_CRYPTO, LedgerPermission.REGISTER_PARTICIPANT, | |||
| LedgerPermission.REGISTER_USER }, roleAdmin.getLedgerPermissions()); | |||
| assertArrayEquals( | |||
| new LedgerPermission[] { LedgerPermission.CONFIGURE_ROLES, LedgerPermission.AUTHORIZE_USER_ROLES, | |||
| LedgerPermission.SET_CONSENSUS, LedgerPermission.SET_CRYPTO, | |||
| LedgerPermission.REGISTER_PARTICIPANT, LedgerPermission.REGISTER_USER }, | |||
| roleAdmin.getLedgerPermissions()); | |||
| assertArrayEquals(new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION }, | |||
| roleAdmin.getTransactionPermissions()); | |||
| RoleInitData roleManager = rolesInitDatas.get("MANAGER"); | |||
| assertArrayEquals( | |||
| new LedgerPermission[] { LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT, | |||
| new LedgerPermission[] { LedgerPermission.CONFIGURE_ROLES, LedgerPermission.AUTHORIZE_USER_ROLES, | |||
| LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT, | |||
| LedgerPermission.REGISTER_CONTRACT, LedgerPermission.UPGRADE_CONTRACT, | |||
| LedgerPermission.SET_USER_ATTRIBUTES, LedgerPermission.WRITE_DATA_ACCOUNT }, | |||
| roleManager.getLedgerPermissions()); | |||
| @@ -127,7 +130,7 @@ public class LedgerInitPropertiesTest { | |||
| // 验证参与方信息; | |||
| assertEquals(4, initProps.getConsensusParticipantCount()); | |||
| ConsensusParticipantConfig part0 = initProps.getConsensusParticipant(0); | |||
| assertEquals("jd.com", part0.getName()); | |||
| PubKey pubKey0 = KeyGenCommand.decodePubKey("3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9"); | |||
| @@ -135,26 +138,25 @@ public class LedgerInitPropertiesTest { | |||
| assertEquals("127.0.0.1", part0.getInitializerAddress().getHost()); | |||
| assertEquals(8800, part0.getInitializerAddress().getPort()); | |||
| assertEquals(true, part0.getInitializerAddress().isSecure()); | |||
| assertArrayEquals(new String[] {"ADMIN", "MANAGER"}, part0.getRoles()); | |||
| assertArrayEquals(new String[] { "ADMIN", "MANAGER" }, part0.getRoles()); | |||
| assertEquals(RolesPolicy.UNION, part0.getRolesPolicy()); | |||
| ConsensusParticipantConfig part1 = initProps.getConsensusParticipant(1); | |||
| assertEquals(false, part1.getInitializerAddress().isSecure()); | |||
| PubKey pubKey1 = KeyGenCommand.decodePubKey("3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX"); | |||
| assertEquals(pubKey1, part1.getPubKey()); | |||
| assertArrayEquals(new String[] { "MANAGER"}, part1.getRoles()); | |||
| assertArrayEquals(new String[] { "MANAGER" }, part1.getRoles()); | |||
| assertEquals(RolesPolicy.UNION, part1.getRolesPolicy()); | |||
| ConsensusParticipantConfig part2 = initProps.getConsensusParticipant(2); | |||
| assertEquals("7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe", part2.getPubKey().toBase58()); | |||
| assertArrayEquals(new String[] { "MANAGER"}, part2.getRoles()); | |||
| assertArrayEquals(new String[] { "MANAGER" }, part2.getRoles()); | |||
| assertEquals(RolesPolicy.UNION, part2.getRolesPolicy()); | |||
| ConsensusParticipantConfig part3 = initProps.getConsensusParticipant(3); | |||
| PubKey pubKey3 = KeyGenCommand.decodePubKey("3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk"); | |||
| assertEquals(pubKey3, part3.getPubKey()); | |||
| assertArrayEquals(new String[] { "GUEST"}, part3.getRoles()); | |||
| assertArrayEquals(new String[] { "GUEST" }, part3.getRoles()); | |||
| assertEquals(RolesPolicy.INTERSECT, part3.getRolesPolicy()); | |||
| } finally { | |||
| @@ -37,11 +37,11 @@ security.role.DEFAULT.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION | |||
| # 其它角色的配置示例; | |||
| # 系统管理员角色:只能操作全局性的参数配置和用户注册,只能执行直接操作指令; | |||
| security.role.ADMIN.ledger-privileges=AUTHORIZE_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, REGISTER_USER | |||
| security.role.ADMIN.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, REGISTER_USER | |||
| security.role.ADMIN.tx-privileges=DIRECT_OPERATION | |||
| # 业务主管角色:只能够执行账本数据相关的操作,包括注册用户、注册数据账户、注册合约、升级合约、写入数据等;能够执行直接操作指令和调用合约; | |||
| security.role.MANAGER.ledger-privileges=REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT, | |||
| security.role.MANAGER.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT, | |||
| security.role.MANAGER.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION | |||
| # 访客角色:不具备任何的账本权限,只有数据读取的操作;也只能够通过调用合约来读取数据; | |||
| @@ -57,18 +57,19 @@ import com.jd.blockchain.ledger.TransactionState; | |||
| import com.jd.blockchain.ledger.UserInfo; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.DefaultOperationHandleRegisteration; | |||
| import com.jd.blockchain.ledger.core.LedgerDataset; | |||
| import com.jd.blockchain.ledger.core.LedgerEditor; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQueryService; | |||
| import com.jd.blockchain.ledger.core.LedgerRepository; | |||
| import com.jd.blockchain.ledger.core.LedgerSecurityManager; | |||
| import com.jd.blockchain.ledger.core.OperationHandleRegisteration; | |||
| import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
| import com.jd.blockchain.ledger.core.TransactionBatchProcessor; | |||
| import com.jd.blockchain.mocker.config.MockerConstant; | |||
| import com.jd.blockchain.mocker.config.PresetAnswerPrompter; | |||
| import com.jd.blockchain.mocker.handler.MockerContractExeHandle; | |||
| import com.jd.blockchain.mocker.handler.MockerOperationHandleRegister; | |||
| import com.jd.blockchain.mocker.proxy.ContractProxy; | |||
| import com.jd.blockchain.service.TransactionBatchResultHandle; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| @@ -91,7 +92,7 @@ public class MockerNodeContext implements BlockchainQueryService { | |||
| private DbConnectionFactory dbConnFactory = new MemoryDBConnFactory(); | |||
| private MockerOperationHandleRegister opHandler = new MockerOperationHandleRegister(); | |||
| private DefaultOperationHandleRegisteration opHandler = new DefaultOperationHandleRegisteration(); | |||
| private MockerContractExeHandle contractExeHandle = new MockerContractExeHandle(); | |||
| @@ -194,7 +195,7 @@ public class MockerNodeContext implements BlockchainQueryService { | |||
| contractExeHandle.initLedger(ledgerManager, ledgerHash); | |||
| opHandler.registerHandler(contractExeHandle); | |||
| opHandler.registerHandle(contractExeHandle); | |||
| return this; | |||
| } | |||
| @@ -73,8 +73,8 @@ public class MockerContractExeHandle implements OperationHandle { | |||
| } | |||
| @Override | |||
| public boolean support(Class<?> operationType) { | |||
| return ContractEventSendOperation.class.isAssignableFrom(operationType); | |||
| public Class<?> getOperationType() { | |||
| return ContractEventSendOperation.class; | |||
| } | |||
| public void initLedger(LedgerManager ledgerManager, HashDigest ledgerHash) { | |||
| @@ -1,54 +1,54 @@ | |||
| package com.jd.blockchain.mocker.handler; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import com.jd.blockchain.ledger.LedgerException; | |||
| import com.jd.blockchain.ledger.core.OperationHandle; | |||
| import com.jd.blockchain.ledger.core.OperationHandleRegisteration; | |||
| import com.jd.blockchain.ledger.core.handles.ContractCodeDeployOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.DataAccountKVSetOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.DataAccountRegisterOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.UserRegisterOperationHandle; | |||
| public class MockerOperationHandleRegister implements OperationHandleRegisteration { | |||
| private List<OperationHandle> opHandles = new ArrayList<>(); | |||
| public MockerOperationHandleRegister() { | |||
| initDefaultHandles(); | |||
| } | |||
| /** | |||
| * 针对不采用bean依赖注入的方式来处理; | |||
| */ | |||
| private void initDefaultHandles(){ | |||
| opHandles.add(new DataAccountKVSetOperationHandle()); | |||
| opHandles.add(new DataAccountRegisterOperationHandle()); | |||
| opHandles.add(new UserRegisterOperationHandle()); | |||
| opHandles.add(new ContractCodeDeployOperationHandle()); | |||
| // opHandles.add(new ContractEventSendOperationHandle()); | |||
| } | |||
| public List<OperationHandle> getOpHandles() { | |||
| return opHandles; | |||
| } | |||
| public void registerHandler(OperationHandle operationHandle) { | |||
| opHandles.add(operationHandle); | |||
| } | |||
| public void removeHandler(OperationHandle operationHandle) { | |||
| opHandles.remove(operationHandle); | |||
| } | |||
| @Override | |||
| public OperationHandle getHandle(Class<?> operationType) { | |||
| for (OperationHandle handle : opHandles) { | |||
| if (handle.support(operationType)) { | |||
| return handle; | |||
| } | |||
| } | |||
| throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
| } | |||
| } | |||
| //package com.jd.blockchain.mocker.handler; | |||
| // | |||
| //import java.util.ArrayList; | |||
| //import java.util.List; | |||
| // | |||
| //import com.jd.blockchain.ledger.LedgerException; | |||
| //import com.jd.blockchain.ledger.core.OperationHandle; | |||
| //import com.jd.blockchain.ledger.core.OperationHandleRegisteration; | |||
| //import com.jd.blockchain.ledger.core.handles.ContractCodeDeployOperationHandle; | |||
| //import com.jd.blockchain.ledger.core.handles.DataAccountKVSetOperationHandle; | |||
| //import com.jd.blockchain.ledger.core.handles.DataAccountRegisterOperationHandle; | |||
| //import com.jd.blockchain.ledger.core.handles.UserRegisterOperationHandle; | |||
| // | |||
| //public class MockerOperationHandleRegister implements OperationHandleRegisteration { | |||
| // | |||
| // private List<OperationHandle> opHandles = new ArrayList<>(); | |||
| // | |||
| // public MockerOperationHandleRegister() { | |||
| // initDefaultHandles(); | |||
| // } | |||
| // | |||
| // /** | |||
| // * 针对不采用bean依赖注入的方式来处理; | |||
| // */ | |||
| // private void initDefaultHandles(){ | |||
| // opHandles.add(new DataAccountKVSetOperationHandle()); | |||
| // opHandles.add(new DataAccountRegisterOperationHandle()); | |||
| // opHandles.add(new UserRegisterOperationHandle()); | |||
| // opHandles.add(new ContractCodeDeployOperationHandle()); | |||
| //// opHandles.add(new ContractEventSendOperationHandle()); | |||
| // } | |||
| // | |||
| // public List<OperationHandle> getOpHandles() { | |||
| // return opHandles; | |||
| // } | |||
| // | |||
| // public void registerHandler(OperationHandle operationHandle) { | |||
| // opHandles.add(operationHandle); | |||
| // } | |||
| // | |||
| // public void removeHandler(OperationHandle operationHandle) { | |||
| // opHandles.remove(operationHandle); | |||
| // } | |||
| // | |||
| // @Override | |||
| // public OperationHandle getHandle(Class<?> operationType) { | |||
| // for (OperationHandle handle : opHandles) { | |||
| // if (handle.support(operationType)) { | |||
| // return handle; | |||
| // } | |||
| // } | |||
| // throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
| // } | |||
| //} | |||
| @@ -51,7 +51,7 @@ public class StringUtils { | |||
| */ | |||
| public static String[] splitToArray(String str, String delimiter, boolean trimElement, boolean ignoreEmptyElement) { | |||
| if (str == null) { | |||
| return null; | |||
| return EMPTY_ARRAY; | |||
| } | |||
| if (trimElement) { | |||
| str = str.trim(); | |||