| @@ -6,18 +6,11 @@ import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import com.jd.blockchain.ledger.core.handles.*; | |||
| import org.springframework.stereotype.Component; | |||
| import com.jd.blockchain.ledger.LedgerException; | |||
| import com.jd.blockchain.ledger.Operation; | |||
| 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.LedgerInitOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.RolesConfigureOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.UserAuthorizeOperationHandle; | |||
| import com.jd.blockchain.ledger.core.handles.UserRegisterOperationHandle; | |||
| import com.jd.blockchain.transaction.ContractCodeDeployOpTemplate; | |||
| import com.jd.blockchain.transaction.ContractEventSendOpTemplate; | |||
| import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; | |||
| @@ -50,6 +43,10 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis | |||
| registerDefaultHandle(new ContractCodeDeployOperationHandle()); | |||
| registerDefaultHandle(new JVMContractEventSendOperationHandle()); | |||
| registerDefaultHandle(new ParticipantRegisterOperationHandle()); | |||
| registerDefaultHandle(new ParticipantStateUpdateOperationHandle()); | |||
| } | |||
| private static void registerDefaultHandle(OperationHandle handle) { | |||
| @@ -1,365 +0,0 @@ | |||
| package com.jd.blockchain.ledger.core; | |||
| import com.jd.blockchain.ledger.LedgerMetadata; | |||
| import com.jd.blockchain.ledger.LedgerSetting; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
| import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.HashFunction; | |||
| import com.jd.blockchain.ledger.LedgerException; | |||
| import com.jd.blockchain.ledger.LedgerInitSetting; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
| import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; | |||
| import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.Transactional; | |||
| public class LedgerAdminAccount implements Transactional, LedgerAdministration { | |||
| static { | |||
| DataContractRegistry.register(LedgerMetadata.class); | |||
| } | |||
| private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminAccount.class); | |||
| public static final String LEDGER_META_PREFIX = "MTA" + LedgerConsts.KEY_SEPERATOR; | |||
| public static final String LEDGER_PARTICIPANT_PREFIX = "PAR" + LedgerConsts.KEY_SEPERATOR; | |||
| public static final String LEDGER_PRIVILEGE_PREFIX = "PVL" + LedgerConsts.KEY_SEPERATOR; | |||
| private final Bytes metaPrefix; | |||
| private final Bytes privilegePrefix; | |||
| private LedgerMetadata origMetadata; | |||
| private LedgerMetadataImpl metadata; | |||
| /** | |||
| * 原来的账本设置; | |||
| * | |||
| * <br> | |||
| * 对 LedgerMetadata 修改的新配置不能立即生效,需要达成共识后,在下一次区块计算中才生效; | |||
| */ | |||
| private LedgerSetting previousSetting; | |||
| /** | |||
| * 账本的参与节点; | |||
| */ | |||
| private ParticipantDataSet participants; | |||
| // /** | |||
| // * 账本的全局权限设置; | |||
| // */ | |||
| // private PrivilegeDataSet privileges; | |||
| private ExPolicyKVStorage settingsStorage; | |||
| private HashDigest adminAccountHash; | |||
| private boolean readonly; | |||
| private boolean updated; | |||
| public HashDigest getHash() { | |||
| return adminAccountHash; | |||
| } | |||
| public boolean isReadonly() { | |||
| return readonly; | |||
| } | |||
| /** | |||
| * 初始化账本的管理账户; | |||
| * | |||
| * <br> | |||
| * | |||
| * 只在新建账本时调用此方法; | |||
| * | |||
| * @param ledgerSeed | |||
| * @param setting | |||
| * @param partiList | |||
| * @param exPolicyStorage | |||
| * @param versioningStorage | |||
| */ | |||
| public LedgerAdminAccount(LedgerInitSetting initSetting, String keyPrefix, ExPolicyKVStorage exPolicyStorage, | |||
| VersioningKVStorage versioningStorage) { | |||
| this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX); | |||
| this.privilegePrefix = Bytes.fromString(keyPrefix + LEDGER_PRIVILEGE_PREFIX); | |||
| ParticipantNode[] parties = initSetting.getConsensusParticipants(); | |||
| if (parties.length == 0) { | |||
| throw new LedgerException("No participant!"); | |||
| } | |||
| // 检查参与者列表是否已经按照 id 升序排列,并且 id 不冲突; | |||
| // 注:参与者的 id 要求从 0 开始编号,顺序依次递增,不允许跳空; | |||
| for (int i = 0; i < parties.length; i++) { | |||
| // if (parties[i].getAddress() != i) { | |||
| // throw new LedgerException("The id of participant isn't match the order of the | |||
| // participant list!"); | |||
| // } | |||
| } | |||
| // 初始化元数据; | |||
| this.metadata = new LedgerMetadataImpl(); | |||
| this.metadata.setSeed(initSetting.getLedgerSeed()); | |||
| // 新配置; | |||
| this.metadata.setting = new LedgerConfiguration(initSetting.getConsensusProvider(), | |||
| initSetting.getConsensusSettings(), initSetting.getCryptoSetting()); | |||
| this.previousSetting = new LedgerConfiguration(initSetting.getConsensusProvider(), | |||
| initSetting.getConsensusSettings(), initSetting.getCryptoSetting()); | |||
| this.adminAccountHash = null; | |||
| // 基于原配置初始化参与者列表; | |||
| String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX; | |||
| this.participants = new ParticipantDataSet(previousSetting.getCryptoSetting(), partiPrefix, exPolicyStorage, | |||
| versioningStorage); | |||
| for (ParticipantNode p : parties) { | |||
| this.participants.addConsensusParticipant(p); | |||
| } | |||
| // 初始化其它属性; | |||
| this.settingsStorage = exPolicyStorage; | |||
| this.readonly = false; | |||
| } | |||
| public LedgerAdminAccount(HashDigest adminAccountHash, String keyPrefix, ExPolicyKVStorage kvStorage, | |||
| VersioningKVStorage versioningKVStorage, boolean readonly) { | |||
| this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX); | |||
| this.privilegePrefix = Bytes.fromString(keyPrefix + LEDGER_PRIVILEGE_PREFIX); | |||
| this.settingsStorage = kvStorage; | |||
| this.readonly = readonly; | |||
| this.origMetadata = loadAndVerifySettings(adminAccountHash); | |||
| this.metadata = new LedgerMetadataImpl(origMetadata); | |||
| // 复制记录一份配置作为上一个区块的原始配置,该实例仅供读取,不做修改,也不会回写到存储; | |||
| this.previousSetting = new LedgerConfiguration(metadata.getSetting()); | |||
| this.adminAccountHash = adminAccountHash; | |||
| // this.privileges = new PrivilegeDataSet(metadata.getPrivilegesHash(), | |||
| // metadata.getSetting().getCryptoSetting(), | |||
| // PrefixAppender.prefix(LEDGER_PRIVILEGE_PREFIX, kvStorage), | |||
| // PrefixAppender.prefix(LEDGER_PRIVILEGE_PREFIX, versioningKVStorage), | |||
| // readonly); | |||
| // this.participants = new ParticipantDataSet(metadata.getParticipantsHash(), | |||
| // previousSetting.getCryptoSetting(), | |||
| // PrefixAppender.prefix(LEDGER_PARTICIPANT_PREFIX, kvStorage), | |||
| // PrefixAppender.prefix(LEDGER_PARTICIPANT_PREFIX, versioningKVStorage), | |||
| // readonly); | |||
| String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX; | |||
| this.participants = new ParticipantDataSet(metadata.getParticipantsHash(), previousSetting.getCryptoSetting(), | |||
| partiPrefix, kvStorage, versioningKVStorage, readonly); | |||
| } | |||
| private LedgerMetadata loadAndVerifySettings(HashDigest adminAccountHash) { | |||
| // String base58Hash = adminAccountHash.toBase58(); | |||
| // String key = encodeMetadataKey(base58Hash); | |||
| Bytes key = encodeMetadataKey(adminAccountHash); | |||
| byte[] bytes = settingsStorage.get(key); | |||
| HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm()); | |||
| if (!hashFunc.verify(adminAccountHash, bytes)) { | |||
| LOGGER.error("The hash verification of ledger settings fail! --[HASH=" + key + "]"); | |||
| throw new LedgerException("The hash verification of ledger settings fail!"); | |||
| } | |||
| return deserializeMetadata(bytes); | |||
| } | |||
| private Bytes encodeMetadataKey(HashDigest metadataHash) { | |||
| // return LEDGER_META_PREFIX + metadataHash; | |||
| // return metaPrefix + metadataHash; | |||
| return metaPrefix.concat(metadataHash); | |||
| } | |||
| /* | |||
| * (non-Javadoc) | |||
| * | |||
| * @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata() | |||
| */ | |||
| @Override | |||
| public LedgerMetadata getMetadata() { | |||
| return metadata; | |||
| } | |||
| /** | |||
| * 返回原来的账本配置; | |||
| * | |||
| * <br> | |||
| * 此方法总是返回从上一个区块加载的账本配置,即时调用 {@link #setLedgerSetting(LedgerSetting)} 做出了新的更改; | |||
| * | |||
| * @return | |||
| */ | |||
| public LedgerSetting getPreviousSetting() { | |||
| return previousSetting; | |||
| } | |||
| /** | |||
| * 返回当前设置的账本配置; | |||
| * | |||
| * @return | |||
| */ | |||
| public LedgerSetting getSetting() { | |||
| return metadata.getSetting(); | |||
| } | |||
| /** | |||
| * 更新账本配置; | |||
| * | |||
| * @param ledgerSetting | |||
| */ | |||
| public void setLedgerSetting(LedgerSetting ledgerSetting) { | |||
| if (readonly) { | |||
| throw new IllegalArgumentException("This merkle dataset is readonly!"); | |||
| } | |||
| metadata.setSetting(ledgerSetting); | |||
| } | |||
| @Override | |||
| public long getParticipantCount() { | |||
| return participants.getParticipantCount(); | |||
| } | |||
| // /* | |||
| // * (non-Javadoc) | |||
| // * | |||
| // * @see | |||
| // * | |||
| // com.jd.blockchain.ledger.core.LedgerAdministration#getParticipant(java.lang. | |||
| // * String) | |||
| // */ | |||
| // @Override | |||
| // public ParticipantNode getParticipant(int id) { | |||
| // return participants.getParticipant(id); | |||
| // } | |||
| @Override | |||
| public ParticipantNode[] getParticipants() { | |||
| return participants.getParticipants(); | |||
| } | |||
| /** | |||
| * 加入新的参与方; 如果指定的参与方已经存在,则引发 LedgerException 异常; | |||
| * | |||
| * @param participant | |||
| */ | |||
| public void addParticipant(ParticipantNode participant) { | |||
| participants.addConsensusParticipant(participant); | |||
| } | |||
| /** | |||
| * 更新参与方的状态参数; | |||
| * | |||
| * @param participant | |||
| */ | |||
| public void updateParticipant(ParticipantNode participant) { | |||
| participants.updateConsensusParticipant(participant); | |||
| } | |||
| @Override | |||
| public boolean isUpdated() { | |||
| return updated || participants.isUpdated(); | |||
| } | |||
| @Override | |||
| public void commit() { | |||
| if (!isUpdated()) { | |||
| return; | |||
| } | |||
| participants.commit(); | |||
| metadata.setParticipantsHash(participants.getRootHash()); | |||
| // 基于之前的密码配置来计算元数据的哈希; | |||
| byte[] metadataBytes = serializeMetadata(metadata); | |||
| HashFunction hashFunc = Crypto | |||
| .getHashFunction(previousSetting.getCryptoSetting().getHashAlgorithm()); | |||
| HashDigest metadataHash = hashFunc.hash(metadataBytes); | |||
| if (adminAccountHash == null || !adminAccountHash.equals(metadataHash)) { | |||
| // update modify; | |||
| // String base58MetadataHash = metadataHash.toBase58(); | |||
| // String metadataKey = encodeMetadataKey(base58MetadataHash); | |||
| Bytes metadataKey = encodeMetadataKey(metadataHash); | |||
| boolean nx = settingsStorage.set(metadataKey, metadataBytes, ExPolicy.NOT_EXISTING); | |||
| if (!nx) { | |||
| // 有可能发生了并发写入冲突,不同的节点都向同一个存储服务器上写入数据; | |||
| // throw new LedgerException( | |||
| // "Ledger metadata already exist! --[LedgerMetadataHash=" + base58MetadataHash | |||
| // + "]"); | |||
| // LOGGER.warn("Ledger metadata already exist! --[MetadataHash=" + | |||
| // base58MetadataHash + "]"); | |||
| } | |||
| adminAccountHash = metadataHash; | |||
| } | |||
| updated = false; | |||
| } | |||
| private LedgerMetadata deserializeMetadata(byte[] bytes) { | |||
| return BinaryProtocol.decode(bytes); | |||
| } | |||
| private byte[] serializeMetadata(LedgerMetadataImpl config) { | |||
| return BinaryProtocol.encode(config, LedgerMetadata.class); | |||
| } | |||
| @Override | |||
| public void cancel() { | |||
| if (!isUpdated()) { | |||
| return; | |||
| } | |||
| participants.cancel(); | |||
| metadata = new LedgerMetadataImpl(origMetadata); | |||
| } | |||
| public static class LedgerMetadataImpl implements LedgerMetadata { | |||
| private byte[] seed; | |||
| private LedgerSetting setting; | |||
| private HashDigest participantsHash; | |||
| public LedgerMetadataImpl() { | |||
| } | |||
| public LedgerMetadataImpl(LedgerMetadata metadata) { | |||
| this.seed = metadata.getSeed(); | |||
| this.setting = metadata.getSetting(); | |||
| this.participantsHash = metadata.getParticipantsHash(); | |||
| } | |||
| @Override | |||
| public byte[] getSeed() { | |||
| return seed; | |||
| } | |||
| @Override | |||
| public LedgerSetting getSetting() { | |||
| return setting; | |||
| } | |||
| @Override | |||
| public HashDigest getParticipantsHash() { | |||
| return participantsHash; | |||
| } | |||
| public void setSeed(byte[] seed) { | |||
| this.seed = seed; | |||
| } | |||
| public void setSetting(LedgerSetting setting) { | |||
| // copy a new instance; | |||
| this.setting = new LedgerConfiguration(setting); | |||
| } | |||
| public void setParticipantsHash(HashDigest participantsHash) { | |||
| this.participantsHash = participantsHash; | |||
| } | |||
| } | |||
| } | |||
| @@ -268,6 +268,8 @@ public class LedgerAdminDataset implements Transactional, LedgerAdminDataQuery, | |||
| * | |||
| * @return | |||
| */ | |||
| @Override | |||
| public LedgerSettings getSettings() { | |||
| return settings; | |||
| } | |||
| @@ -309,6 +311,16 @@ public class LedgerAdminDataset implements Transactional, LedgerAdminDataQuery, | |||
| participants.addConsensusParticipant(participant); | |||
| } | |||
| /** | |||
| * 更新参与方的状态参数; | |||
| * | |||
| * @param participant | |||
| */ | |||
| public void updateParticipant(ParticipantNode participant) { | |||
| participants.updateConsensusParticipant(participant); | |||
| } | |||
| @Override | |||
| public boolean isUpdated() { | |||
| return updated || participants.isUpdated() || rolePrivileges.isUpdated() || userRoles.isUpdated(); | |||
| @@ -1,4 +1,4 @@ | |||
| package com.jd.blockchain.ledger.core.impl.handles; | |||
| package com.jd.blockchain.ledger.core.handles; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| @@ -6,66 +6,51 @@ import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.*; | |||
| import com.jd.blockchain.ledger.core.*; | |||
| import com.jd.blockchain.ledger.core.impl.OperationHandleContext; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| public class ParticipantRegisterOperationHandle implements OperationHandle { | |||
| @Override | |||
| public BytesValue process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext, | |||
| LedgerDataSet previousBlockDataset, OperationHandleContext handleContext, LedgerService ledgerService) { | |||
| ParticipantRegisterOperation participantRegOp = (ParticipantRegisterOperation) op; | |||
| public class ParticipantRegisterOperationHandle extends AbstractLedgerOperationHandle<ParticipantRegisterOperation> { | |||
| public ParticipantRegisterOperationHandle() { | |||
| super(ParticipantRegisterOperation.class); | |||
| } | |||
| LedgerAdminAccount adminAccount = dataset.getAdminAccount(); | |||
| @Override | |||
| protected void doProcess(ParticipantRegisterOperation op, LedgerDataset newBlockDataset, | |||
| TransactionRequestExtension requestContext, LedgerDataQuery previousBlockDataset, | |||
| OperationHandleContext handleContext, LedgerService ledgerService) { | |||
| ParticipantInfo participantInfo = participantRegOp.getParticipantInfo(); | |||
| // 权限校验; | |||
| SecurityPolicy securityPolicy = SecurityContext.getContextUsersPolicy(); | |||
| securityPolicy.checkEndpointPermission(LedgerPermission.REGISTER_PARTICIPANT, MultiIDsPolicy.AT_LEAST_ONE); | |||
| // ConsensusProvider provider = ConsensusProviders.getProvider(adminAccount.getSetting().getConsensusProvider()); | |||
| ParticipantRegisterOperation participantRegOp = (ParticipantRegisterOperation) op; | |||
| ParticipantNode participantNode = new PartNode((int)(adminAccount.getParticipantCount()), participantInfo.getName(), participantInfo.getPubKey(), ParticipantNodeState.REGISTED); | |||
| LedgerAdminDataset adminAccountDataSet = newBlockDataset.getAdminDataset(); | |||
| // LedgerAdminAccount.LedgerMetadataImpl metadata = (LedgerAdminAccount.LedgerMetadataImpl) adminAccount.getMetadata(); | |||
| ParticipantInfo participantInfo = participantRegOp.getParticipantInfo(); | |||
| ParticipantNode participantNode = new PartNode((int)(adminAccountDataSet.getParticipantCount()), participantInfo.getName(), participantInfo.getPubKey(), ParticipantNodeState.REGISTED); | |||
| PubKey pubKey = participantNode.getPubKey(); | |||
| BlockchainIdentityData identityData = new BlockchainIdentityData(pubKey); | |||
| //update consensus setting | |||
| // Bytes newConsensusSettings = provider.getSettingsFactory().getConsensusSettingsBuilder().updateSettings(metadata.getSetting().getConsensusSetting(), participantInfo); | |||
| // LedgerSetting ledgerSetting = new LedgerConfiguration(adminAccount.getSetting().getConsensusProvider(), | |||
| // newConsensusSettings, metadata.getSetting().getCryptoSetting()); | |||
| // metadata.setSetting(ledgerSetting); | |||
| // metadata.setViewId(metadata.getViewId() + 1); | |||
| // //reg participant as user | |||
| // dataset.getUserAccountSet().register(identityData.getAddress(), pubKey); | |||
| //add new participant as consensus node | |||
| adminAccount.addParticipant(participantNode); | |||
| // Build UserRegisterOperation; | |||
| adminAccountDataSet.addParticipant(participantNode); | |||
| // Build UserRegisterOperation; | |||
| UserRegisterOperation userRegOp = null;// | |||
| handleContext.handle(userRegOp); | |||
| return null; | |||
| } | |||
| @Override | |||
| public boolean support(Class<?> operationType) { | |||
| return ParticipantRegisterOperation.class.isAssignableFrom(operationType); | |||
| } | |||
| private static class PartNode implements ParticipantNode { | |||
| private int id; | |||
| private String address; | |||
| private Bytes address; | |||
| private String name; | |||
| @@ -77,7 +62,7 @@ public class ParticipantRegisterOperationHandle implements OperationHandle { | |||
| this.id = id; | |||
| this.name = name; | |||
| this.pubKey = pubKey; | |||
| this.address = AddressEncoding.generateAddress(pubKey).toBase58(); | |||
| this.address = AddressEncoding.generateAddress(pubKey); | |||
| this.participantNodeState = participantNodeState; | |||
| } | |||
| @@ -87,7 +72,7 @@ public class ParticipantRegisterOperationHandle implements OperationHandle { | |||
| } | |||
| @Override | |||
| public String getAddress() { | |||
| public Bytes getAddress() { | |||
| return address; | |||
| } | |||
| @@ -107,4 +92,5 @@ public class ParticipantRegisterOperationHandle implements OperationHandle { | |||
| } | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| package com.jd.blockchain.ledger.core.impl.handles; | |||
| package com.jd.blockchain.ledger.core.handles; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| @@ -6,28 +6,30 @@ import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.*; | |||
| import com.jd.blockchain.ledger.core.*; | |||
| import com.jd.blockchain.ledger.core.impl.OperationHandleContext; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| public class ParticipantStateUpdateOperationHandle implements OperationHandle { | |||
| @Override | |||
| public boolean support(Class<?> operationType) { | |||
| return ParticipantStateUpdateOperation.class.isAssignableFrom(operationType); | |||
| public class ParticipantStateUpdateOperationHandle extends AbstractLedgerOperationHandle<ParticipantStateUpdateOperation> { | |||
| public ParticipantStateUpdateOperationHandle() { | |||
| super(ParticipantStateUpdateOperation.class); | |||
| } | |||
| @Override | |||
| public BytesValue process(Operation op, LedgerDataSet newBlockDataset, TransactionRequestContext requestContext, LedgerDataSet previousBlockDataset, OperationHandleContext handleContext, LedgerService ledgerService) { | |||
| protected void doProcess(ParticipantStateUpdateOperation op, LedgerDataset newBlockDataset, | |||
| TransactionRequestExtension requestContext, LedgerDataQuery previousBlockDataset, | |||
| OperationHandleContext handleContext, LedgerService ledgerService) { | |||
| ParticipantStateUpdateOperation stateUpdateOperation = (ParticipantStateUpdateOperation) op; | |||
| // 权限校验; | |||
| SecurityPolicy securityPolicy = SecurityContext.getContextUsersPolicy(); | |||
| securityPolicy.checkEndpointPermission(LedgerPermission.REGISTER_PARTICIPANT, MultiIDsPolicy.AT_LEAST_ONE); | |||
| LedgerAdminAccount adminAccount = newBlockDataset.getAdminAccount(); | |||
| ParticipantStateUpdateOperation stateUpdateOperation = (ParticipantStateUpdateOperation) op; | |||
| ConsensusProvider provider = ConsensusProviders.getProvider(adminAccount.getSetting().getConsensusProvider()); | |||
| LedgerAdminDataset adminAccountDataSet = newBlockDataset.getAdminDataset(); | |||
| LedgerAdminAccount.LedgerMetadataImpl metadata = (LedgerAdminAccount.LedgerMetadataImpl) adminAccount.getMetadata(); | |||
| ConsensusProvider provider = ConsensusProviders.getProvider(adminAccountDataSet.getSettings().getConsensusProvider()); | |||
| ParticipantNode[] participants = adminAccount.getParticipants(); | |||
| ParticipantNode[] participants = adminAccountDataSet.getParticipants(); | |||
| ParticipantNode participantNode = null; | |||
| @@ -39,25 +41,24 @@ public class ParticipantStateUpdateOperationHandle implements OperationHandle { | |||
| } | |||
| //update consensus setting | |||
| ParticipantInfo participantInfo = new ParticipantInfoData("", participantNode.getName(), participantNode.getPubKey(), stateUpdateOperation.getStateUpdateInfo().getNetworkAddress()); | |||
| ParticipantInfo participantInfo = new ParticipantInfoData(participantNode.getName(), participantNode.getPubKey(), stateUpdateOperation.getStateUpdateInfo().getNetworkAddress()); | |||
| Bytes newConsensusSettings = provider.getSettingsFactory().getConsensusSettingsBuilder().updateSettings(metadata.getSetting().getConsensusSetting(), participantInfo); | |||
| Bytes newConsensusSettings = provider.getSettingsFactory().getConsensusSettingsBuilder().updateSettings(adminAccountDataSet.getSettings().getConsensusSetting(), participantInfo); | |||
| LedgerSetting ledgerSetting = new LedgerConfiguration(adminAccount.getSetting().getConsensusProvider(), | |||
| newConsensusSettings, metadata.getSetting().getCryptoSetting()); | |||
| LedgerSettings ledgerSetting = new LedgerConfiguration(adminAccountDataSet.getSettings().getConsensusProvider(), | |||
| newConsensusSettings, adminAccountDataSet.getPreviousSetting().getCryptoSetting()); | |||
| metadata.setSetting(ledgerSetting); | |||
| adminAccountDataSet.setLedgerSetting(ledgerSetting); | |||
| adminAccount.updateParticipant(participantNode); | |||
| adminAccountDataSet.updateParticipant(participantNode); | |||
| return null; | |||
| } | |||
| private static class PartNode implements ParticipantNode { | |||
| private int id; | |||
| private String address; | |||
| private Bytes address; | |||
| private String name; | |||
| @@ -69,7 +70,7 @@ public class ParticipantStateUpdateOperationHandle implements OperationHandle { | |||
| this.id = id; | |||
| this.name = name; | |||
| this.pubKey = pubKey; | |||
| this.address = AddressEncoding.generateAddress(pubKey).toBase58(); | |||
| this.address = AddressEncoding.generateAddress(pubKey); | |||
| this.participantNodeState = participantNodeState; | |||
| } | |||
| @@ -79,7 +80,7 @@ public class ParticipantStateUpdateOperationHandle implements OperationHandle { | |||
| } | |||
| @Override | |||
| public String getAddress() { | |||
| public Bytes getAddress() { | |||
| return address; | |||
| } | |||
| @@ -1,61 +0,0 @@ | |||
| package com.jd.blockchain.ledger.core.impl; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import com.jd.blockchain.ledger.core.impl.handles.*; | |||
| import org.springframework.stereotype.Component; | |||
| import com.jd.blockchain.ledger.LedgerException; | |||
| import com.jd.blockchain.ledger.core.OperationHandle; | |||
| @Component | |||
| public class DefaultOperationHandleRegisteration implements OperationHandleRegisteration { | |||
| private List<OperationHandle> opHandles = new ArrayList<>(); | |||
| public DefaultOperationHandleRegisteration() { | |||
| initDefaultHandles(); | |||
| } | |||
| /** | |||
| * 针对不采用bean依赖注入的方式来处理; | |||
| */ | |||
| private void initDefaultHandles() { | |||
| opHandles.add(new DataAccountKVSetOperationHandle()); | |||
| opHandles.add(new DataAccountRegisterOperationHandle()); | |||
| opHandles.add(new UserRegisterOperationHandle()); | |||
| opHandles.add(new ParticipantRegisterOperationHandle()); | |||
| opHandles.add(new ContractCodeDeployOperationHandle()); | |||
| opHandles.add(new JVMContractEventSendOperationHandle()); | |||
| opHandles.add(new ParticipantStateUpdateOperationHandle()); | |||
| } | |||
| /** | |||
| * 以最高优先级插入一个操作处理器; | |||
| * | |||
| * @param handle | |||
| */ | |||
| public void insertAsTopPriority(OperationHandle handle) { | |||
| opHandles.remove(handle); | |||
| opHandles.add(0, handle); | |||
| } | |||
| /* | |||
| * (non-Javadoc) | |||
| * | |||
| * @see | |||
| * com.jd.blockchain.ledger.core.impl.OperationHandleRegisteration#getHandle( | |||
| * java.lang.Class) | |||
| */ | |||
| @Override | |||
| public OperationHandle getHandle(Class<?> operationType) { | |||
| for (OperationHandle handle : opHandles) { | |||
| if (handle.support(operationType)) { | |||
| return handle; | |||
| } | |||
| } | |||
| throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
| } | |||
| } | |||
| @@ -18,12 +18,12 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
| public interface ParticipantInfo { | |||
| /** | |||
| * regist or unregist; | |||
| * regist or unregist, temporarily not available to users | |||
| * | |||
| * @return | |||
| */ | |||
| @DataField(order = 0, primitiveType = PrimitiveType.TEXT) | |||
| String getFlag(); | |||
| // @DataField(order = 0, primitiveType = PrimitiveType.TEXT) | |||
| // String getFlag(); | |||
| /** | |||
| * 参与者名称; | |||
| @@ -18,24 +18,14 @@ public class ParticipantInfoData implements ParticipantInfo { | |||
| private NetworkAddress networkAddress; | |||
| private String flag;//代表注册参与方或者删除参与方 | |||
| // private String flag;//代表注册参与方或者删除参与方 | |||
| public ParticipantInfoData(String flag, String name, PubKey pubKey, NetworkAddress networkAddress) { | |||
| this.flag = flag; | |||
| public ParticipantInfoData(String name, PubKey pubKey, NetworkAddress networkAddress) { | |||
| this.name = name; | |||
| this.pubKey = pubKey; | |||
| this.networkAddress = networkAddress; | |||
| } | |||
| @Override | |||
| public String getFlag() { | |||
| return flag; | |||
| } | |||
| public void setFlag(String flag) { | |||
| this.flag = flag; | |||
| } | |||
| @Override | |||
| public String getName() { | |||
| return name; | |||
| @@ -10,27 +10,13 @@ package com.jd.blockchain.sdk.converters; | |||
| import java.lang.reflect.Field; | |||
| import com.jd.blockchain.ledger.*; | |||
| 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.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; | |||
| @@ -214,8 +200,7 @@ public class ClientResolveUtil { | |||
| JSONObject pubKeyObj = currConsensusParticipant.getJSONObject("pubKey"); | |||
| String pubKeyBase58 = pubKeyObj.getString("value"); | |||
| // 生成ParticipantNode对象 | |||
| ParticipantCertData participantCertData = new ParticipantCertData(id, addressBase58, name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes())); | |||
| new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes())); | |||
| ParticipantCertData participantCertData = new ParticipantCertData(id, address, name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes())); | |||
| participantNodes[i] = participantCertData; | |||
| } | |||
| ledgerInitSettingData.setConsensusParticipants(participantNodes); | |||
| @@ -309,7 +294,7 @@ public class ClientResolveUtil { | |||
| this.pubKey = participantNode.getPubKey(); | |||
| } | |||
| public ParticipantCertData(int id, String address, String name, PubKey pubKey) { | |||
| public ParticipantCertData(int id, Bytes address, String name, PubKey pubKey) { | |||
| this.id = id; | |||
| this.address = address; | |||
| this.name = name; | |||
| @@ -332,14 +317,11 @@ public class ClientResolveUtil { | |||
| return pubKey; | |||
| } | |||
| @Override | |||
| public int getId() { | |||
| return id; | |||
| } | |||
| public void setId(int id) { | |||
| this.id = id; | |||
| } | |||
| @Override | |||
| public ParticipantNodeState getParticipantNodeState() { | |||
| return participantNodeState; | |||
| @@ -72,9 +72,9 @@ public class SDK_GateWay_Participant_Regist_Test_ { | |||
| //existed signer | |||
| AsymmetricKeypair keyPair = new BlockchainKeypair(pubKey, privKey); | |||
| PrivKey privKey = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV, SDKDemo_Constant.PASSWORD); | |||
| PrivKey privKey = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV, SDKDemo_Constant.PASSWORD); | |||
| PubKey pubKey = KeyGenCommand.decodePubKey(PUB); | |||
| PubKey pubKey = KeyGenUtils.decodePubKey(PUB); | |||
| System.out.println("Address = "+AddressEncoding.generateAddress(pubKey)); | |||
| @@ -82,7 +82,7 @@ public class SDK_GateWay_Participant_Regist_Test_ { | |||
| NetworkAddress networkAddress = new NetworkAddress("127.0.0.1", 20000); | |||
| ParticipantInfo participantInfo = new ParticipantInfoData("add","Peer4", user.getPubKey(), networkAddress); | |||
| ParticipantInfo participantInfo = new ParticipantInfoData("Peer4", user.getPubKey(), networkAddress); | |||
| // 注册参与方 | |||
| txTemp.participants().register(participantInfo); | |||
| @@ -71,9 +71,9 @@ public class SDK_GateWay_Participant_State_Update_Test_ { | |||
| //existed signer | |||
| AsymmetricKeypair keyPair = new BlockchainKeypair(pubKey, privKey); | |||
| PrivKey privKey = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV, SDKDemo_Constant.PASSWORD); | |||
| PrivKey privKey = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV, SDKDemo_Constant.PASSWORD); | |||
| PubKey pubKey = KeyGenCommand.decodePubKey(PUB); | |||
| PubKey pubKey = KeyGenUtils.decodePubKey(PUB); | |||
| System.out.println("Address = "+AddressEncoding.generateAddress(pubKey)); | |||
| @@ -88,7 +88,7 @@ public class Utils { | |||
| public static ParticipantNode[] loadParticipantNodes() { | |||
| ParticipantNode[] participantNodes = new ParticipantNode[PUB_KEYS.length]; | |||
| for (int i = 0; i < PUB_KEYS.length; i++) { | |||
| participantNodes[i] = new PartNode(i, KeyGenCommand.decodePubKey(PUB_KEYS[i])); | |||
| participantNodes[i] = new PartNode(i, KeyGenUtils.decodePubKey(PUB_KEYS[i]), ParticipantNodeState.CONSENSUSED); | |||
| } | |||
| return participantNodes; | |||
| } | |||
| @@ -175,7 +175,7 @@ public class IntegrationBase { | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| ParticipantInfoData participantInfoData = new ParticipantInfoData("add", "peer4", participant.getPubKey(), new NetworkAddress("127.0.0.1", 20000)); | |||
| ParticipantInfoData participantInfoData = new ParticipantInfoData("peer4", participant.getPubKey(), new NetworkAddress("127.0.0.1", 20000)); | |||
| txTpl.participants().register(participantInfoData); | |||
| @@ -201,7 +201,7 @@ public class IntegrationBase { | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| ParticipantInfoData participantInfoData = new ParticipantInfoData("add", "peer4", participantKeyPair.getPubKey(), new NetworkAddress("127.0.0.1", 20000)); | |||
| ParticipantInfoData participantInfoData = new ParticipantInfoData("peer4", participantKeyPair.getPubKey(), new NetworkAddress("127.0.0.1", 20000)); | |||
| ParticipantStateUpdateInfo stateUpdateInfo = new ParticipantStateUpdateInfoData(participantKeyPair.getPubKey(), ParticipantNodeState.CONSENSUSED, participantInfoData.getNetworkAddress()); | |||
| @@ -151,7 +151,7 @@ public class IntegrationTest4Bftsmart { | |||
| } | |||
| } | |||
| long participantCount = ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| long participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| long userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotalCount(); | |||
| @@ -162,28 +162,28 @@ public class IntegrationTest4Bftsmart { | |||
| participantResponse = IntegrationBase.testSDK_RegisterParticipant(adminKey, ledgerHash, blockchainService); | |||
| } | |||
| participantCount = ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotalCount(); | |||
| System.out.printf("after add participant: participantCount = %d, userCount = %d\r\n", (int)participantCount, (int)userCount); | |||
| BftsmartConsensusSettings consensusSettings = (BftsmartConsensusSettings) ConsensusProviders.getProvider(BFTSMART_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminAccount().getSetting().getConsensusSetting().toBytes()); | |||
| BftsmartConsensusSettings consensusSettings = (BftsmartConsensusSettings) ConsensusProviders.getProvider(BFTSMART_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo().getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state before ,old consensus env node num = %d\r\n", consensusSettings.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| if (isParticipantStateUpdate) { | |||
| IntegrationBase.testSDK_UpdateParticipantState(adminKey, new BlockchainKeypair(participantResponse.getKeyPair().getPubKey(), participantResponse.getKeyPair().getPrivKey()), ledgerHash, blockchainService); | |||
| } | |||
| BftsmartConsensusSettings consensusSettingsNew = (BftsmartConsensusSettings) ConsensusProviders.getProvider(BFTSMART_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getSetting().getConsensusSetting().toBytes()); | |||
| BftsmartConsensusSettings consensusSettingsNew = (BftsmartConsensusSettings) ConsensusProviders.getProvider(BFTSMART_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state after ,new consensus env node num = %d\r\n", consensusSettingsNew.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| try { | |||
| @@ -147,7 +147,7 @@ public class IntegrationTest4MQ { | |||
| integrationBase.testSDK_Contract(adminKey, ledgerHash, blockchainService,ledgerRepository); | |||
| } | |||
| long participantCount = ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| long participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| long userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotalCount(); | |||
| @@ -158,30 +158,30 @@ public class IntegrationTest4MQ { | |||
| participantResponse = IntegrationBase.testSDK_RegisterParticipant(adminKey, ledgerHash, blockchainService); | |||
| } | |||
| participantCount = ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotalCount(); | |||
| System.out.printf("after add participant: participantCount = %d, userCount = %d\r\n", (int)participantCount, (int)userCount); | |||
| MsgQueueConsensusSettings consensusSettings = (MsgQueueConsensusSettings) ConsensusProviders.getProvider(MQ_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminAccount().getSetting().getConsensusSetting().toBytes()); | |||
| MsgQueueConsensusSettings consensusSettings = (MsgQueueConsensusSettings) ConsensusProviders.getProvider(MQ_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo().getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state before ,old consensus env node num = %d\r\n", consensusSettings.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| if (isParticipantStateUpdate) { | |||
| IntegrationBase.testSDK_UpdateParticipantState(adminKey, new BlockchainKeypair(participantResponse.getKeyPair().getPubKey(), participantResponse.getKeyPair().getPrivKey()), ledgerHash, blockchainService); | |||
| } | |||
| BftsmartConsensusSettings consensusSettingsNew = (BftsmartConsensusSettings) ConsensusProviders.getProvider(MQ_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getSetting().getConsensusSetting().toBytes()); | |||
| BftsmartConsensusSettings consensusSettingsNew = (BftsmartConsensusSettings) ConsensusProviders.getProvider(MQ_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state after ,new consensus env node num = %d\r\n", consensusSettingsNew.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminAccount(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||