| @@ -8,12 +8,18 @@ import com.jd.blockchain.ledger.BlockchainIdentityData; | |||
| import com.jd.blockchain.ledger.DigitalSignature; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitException; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.LedgerInitSetting; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.RoleInitSettings; | |||
| import com.jd.blockchain.ledger.RolesConfigureOperation; | |||
| import com.jd.blockchain.ledger.SecurityInitSettings; | |||
| import com.jd.blockchain.ledger.TransactionBuilder; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| import com.jd.blockchain.ledger.TransactionRequest; | |||
| import com.jd.blockchain.ledger.UserAuthInitSettings; | |||
| import com.jd.blockchain.ledger.UserAuthorizeOperation; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.service.TransactionBatchResultHandle; | |||
| import com.jd.blockchain.storage.service.KVStorageService; | |||
| import com.jd.blockchain.transaction.SignatureUtils; | |||
| @@ -74,23 +80,64 @@ public class LedgerInitializer { | |||
| return null; | |||
| } | |||
| public static LedgerInitializer create(LedgerInitSetting initSetting) { | |||
| return create(initSetting, createDefaultSecurityInitSettings()); | |||
| } | |||
| // public static LedgerInitializer create(LedgerInitSetting initSetting) { | |||
| // return create(initSetting, createDefaultSecurityInitSettings()); | |||
| // } | |||
| public static LedgerInitializer create(LedgerInitSetting initSetting, SecurityInitSettings securityInitSettings) { | |||
| // 生成初始化交易; | |||
| TransactionBuilder initTxBuilder = new TxBuilder(null);// 账本初始化交易的账本 hash 为 null; | |||
| // 生成创世交易; | |||
| TransactionContent initTxContent = buildGenesisTransaction(initSetting, securityInitSettings); | |||
| return new LedgerInitializer(initSetting, initTxContent); | |||
| } | |||
| /** | |||
| * 根据初始化配置,生成创始交易; | |||
| * <p> | |||
| * | |||
| * “创世交易”按顺序由以下操作组成:<br> | |||
| * (1) 账本初始化 {@link LedgerInitOperation}:此操作仅用于锚定了原始的交易配置,对应的 | |||
| * {@link OperationHandle} 执行空操作,由“创世交易”其余的操作来表达对账本的实际修改;<br> | |||
| * (2) 注册用户 {@link UserRegisterOperation}:有一项或者多项;<br> | |||
| * (3) 配置角色 {@link RolesConfigureOperation}:有一项或者多项;<br> | |||
| * (4) 授权用户 {@link UserAuthorizeOperation}:有一项或者多项;<br> | |||
| * | |||
| * @param initSetting | |||
| * @param securityInitSettings | |||
| * @return | |||
| */ | |||
| public static TransactionContent buildGenesisTransaction(LedgerInitSetting initSetting, | |||
| SecurityInitSettings securityInitSettings) { | |||
| // 账本初始化交易的账本 hash 为 null; | |||
| TransactionBuilder initTxBuilder = new TxBuilder(null); | |||
| // 定义账本初始化操作; | |||
| initTxBuilder.ledgers().create(initSetting); | |||
| // TODO: 注册参与方; 目前由 LedgerInitSetting 定义,在 LedgerAdminDataset 中解释执行; | |||
| // 注册用户; | |||
| for (ParticipantNode p : initSetting.getConsensusParticipants()) { | |||
| // TODO:暂时只支持注册用户的初始化操作; | |||
| BlockchainIdentity superUserId = new BlockchainIdentityData(p.getPubKey()); | |||
| initTxBuilder.users().register(superUserId); | |||
| } | |||
| // 账本初始化配置声明的创建时间来初始化交易时间戳;注:不能用本地时间,因为共识节点之间的本地时间系统不一致; | |||
| TransactionContent initTxContent = initTxBuilder.prepareContent(initSetting.getCreatedTime()); | |||
| return new LedgerInitializer(initSetting, initTxContent); | |||
| // 配置角色; | |||
| for (RoleInitSettings roleSettings : securityInitSettings.getRoles()) { | |||
| initTxBuilder.security().roles().configure(roleSettings.getRoleName()) | |||
| .enable(roleSettings.getLedgerPermissions()).enable(roleSettings.getTransactionPermissions()); | |||
| } | |||
| // 授权用户; | |||
| for (UserAuthInitSettings userAuthSettings : securityInitSettings.getUserAuthorizations()) { | |||
| initTxBuilder.security().authorziations().forUser(userAuthSettings.getUserAddress()) | |||
| .authorize(userAuthSettings.getRoles()) | |||
| .setPolicy(userAuthSettings.getPolicy()); | |||
| } | |||
| // 账本初始化配置声明的创建时间来初始化交易时间戳;注:不能用本地时间,因为共识节点之间的本地时间系统不一致; | |||
| return initTxBuilder.prepareContent(initSetting.getCreatedTime()); | |||
| } | |||
| public SignatureDigest signTransaction(PrivKey privKey) { | |||
| @@ -15,6 +15,7 @@ import com.jd.blockchain.consts.Global; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.CryptoProperties; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.PropertiesUtils; | |||
| import com.jd.blockchain.utils.StringUtils; | |||
| @@ -72,6 +73,10 @@ public class LedgerInitProperties { | |||
| // 密码服务提供者列表,以英文逗点“,”分隔;必须; | |||
| public static final String CRYPTO_SERVICE_PROVIDERS = "crypto.service-providers"; | |||
| // 从存储中加载账本数据时,是否校验哈希;可选; | |||
| public static final String CRYPTO_VRIFY_HASH = "crypto.verify-hash"; | |||
| // 哈希算法; | |||
| public static final String CRYPTO_HASH_ALGORITHM = "crypto.hash-algorithm"; | |||
| public static final String CRYPTO_SERVICE_PROVIDERS_SPLITTER = ","; | |||
| @@ -81,13 +86,15 @@ public class LedgerInitProperties { | |||
| private RoleInitData[] roles; | |||
| private List<ConsensusParticipantConfig> consensusParticipants = new ArrayList<>(); | |||
| private List<ParticipantProperties> consensusParticipants = new ArrayList<>(); | |||
| private String consensusProvider; | |||
| private Properties consensusConfig; | |||
| private String[] cryptoProviders; | |||
| // private String[] cryptoProviders; | |||
| private CryptoProperties cryptoProperties = new CryptoProperties(); | |||
| private long createdTime; | |||
| @@ -115,7 +122,7 @@ public class LedgerInitProperties { | |||
| return consensusParticipants.size(); | |||
| } | |||
| public List<ConsensusParticipantConfig> getConsensusParticipants() { | |||
| public List<ParticipantProperties> getConsensusParticipants() { | |||
| return consensusParticipants; | |||
| } | |||
| @@ -127,12 +134,15 @@ public class LedgerInitProperties { | |||
| return consensusParticipants.toArray(participantNodes); | |||
| } | |||
| public String[] getCryptoProviders() { | |||
| return cryptoProviders.clone(); | |||
| public CryptoProperties getCryptoProperties() { | |||
| return cryptoProperties; | |||
| } | |||
| public void setCryptoProviders(String[] cryptoProviders) { | |||
| this.cryptoProviders = cryptoProviders; | |||
| public void setCryptoProperties(CryptoProperties cryptoProperties) { | |||
| if (cryptoProperties == null) { | |||
| cryptoProperties = new CryptoProperties(); | |||
| } | |||
| this.cryptoProperties = cryptoProperties; | |||
| } | |||
| /** | |||
| @@ -141,8 +151,8 @@ public class LedgerInitProperties { | |||
| * @param id 从 1 开始; 小于等于 {@link #getConsensusParticipantCount()}; | |||
| * @return | |||
| */ | |||
| public ConsensusParticipantConfig getConsensusParticipant(int id) { | |||
| for (ConsensusParticipantConfig p : consensusParticipants) { | |||
| public ParticipantProperties getConsensusParticipant(int id) { | |||
| for (ParticipantProperties p : consensusParticipants) { | |||
| if (p.getId() == id) { | |||
| return p; | |||
| } | |||
| @@ -159,7 +169,7 @@ public class LedgerInitProperties { | |||
| this.ledgerSeed = ledgerSeed; | |||
| } | |||
| public void addConsensusParticipant(ConsensusParticipantConfig participant) { | |||
| public void addConsensusParticipant(ParticipantProperties participant) { | |||
| consensusParticipants.add(participant); | |||
| } | |||
| @@ -249,7 +259,14 @@ public class LedgerInitProperties { | |||
| for (int i = 0; i < cryptoProviders.length; i++) { | |||
| cryptoProviders[i] = cryptoProviders[i].trim(); | |||
| } | |||
| initProps.cryptoProviders = cryptoProviders; | |||
| initProps.cryptoProperties.setProviders(cryptoProviders); | |||
| // 哈希校验选项; | |||
| boolean verifyHash = PropertiesUtils.getBooleanOptional(props, CRYPTO_VRIFY_HASH, false); | |||
| initProps.cryptoProperties.setVerifyHash(verifyHash); | |||
| // 哈希算法; | |||
| String hashAlgorithm = PropertiesUtils.getOptionalProperty(props, CRYPTO_HASH_ALGORITHM); | |||
| initProps.cryptoProperties.setHashAlgorithm(hashAlgorithm); | |||
| // 解析参与方节点列表; | |||
| int partCount = getInt(PropertiesUtils.getRequiredProperty(props, PART_COUNT)); | |||
| @@ -260,7 +277,7 @@ public class LedgerInitProperties { | |||
| throw new IllegalArgumentException(String.format("Property[%s] is less than 4!", PART_COUNT)); | |||
| } | |||
| for (int i = 0; i < partCount; i++) { | |||
| ConsensusParticipantConfig parti = new ConsensusParticipantConfig(); | |||
| ParticipantProperties parti = new ParticipantProperties(); | |||
| parti.setId(i); | |||
| @@ -363,13 +380,47 @@ public class LedgerInitProperties { | |||
| this.roles = roles; | |||
| } | |||
| public static class CryptoProperties { | |||
| private String[] providers; | |||
| private boolean verifyHash; | |||
| private String hashAlgorithm; | |||
| public String[] getProviders() { | |||
| return providers; | |||
| } | |||
| public void setProviders(String[] providers) { | |||
| this.providers = providers; | |||
| } | |||
| public boolean isVerifyHash() { | |||
| return verifyHash; | |||
| } | |||
| public void setVerifyHash(boolean verifyHash) { | |||
| this.verifyHash = verifyHash; | |||
| } | |||
| public String getHashAlgorithm() { | |||
| return hashAlgorithm; | |||
| } | |||
| public void setHashAlgorithm(String hashAlgorithm) { | |||
| this.hashAlgorithm = hashAlgorithm; | |||
| } | |||
| } | |||
| /** | |||
| * 参与方配置信息; | |||
| * | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| public static class ConsensusParticipantConfig implements ParticipantNode { | |||
| public static class ParticipantProperties implements ParticipantNode { | |||
| private int id; | |||
| @@ -1,34 +1,54 @@ | |||
| package com.jd.blockchain.ledger; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.LinkedHashMap; | |||
| import java.util.Map; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| public class SecurityInitData implements SecurityInitSettings { | |||
| private List<RoleInitData> roles = new ArrayList<RoleInitData>(); | |||
| private Map<String, RoleInitData> roles = new LinkedHashMap<>(); | |||
| private Map<Bytes, UserAuthInitData> userAuthentications = new LinkedHashMap<>(); | |||
| @Override | |||
| public RoleInitData[] getRoles() { | |||
| return roles.toArray(new RoleInitData[roles.size()]); | |||
| return roles.values().toArray(new RoleInitData[roles.size()]); | |||
| } | |||
| public int getRolesCount() { | |||
| return roles.size(); | |||
| } | |||
| public void setRoles(RoleInitData[] roles) { | |||
| List<RoleInitData> list = new ArrayList<RoleInitData>(); | |||
| Map<String, RoleInitData> newRoles = new LinkedHashMap<>(); | |||
| for (RoleInitData r : roles) { | |||
| list.add(r); | |||
| newRoles.put(r.getRoleName(), r); | |||
| } | |||
| this.roles = list; | |||
| this.roles = newRoles; | |||
| } | |||
| public void add(String roleName, LedgerPermission[] ledgerPermissions, | |||
| public boolean containsRole(String roleName) { | |||
| return roles.containsKey(roleName); | |||
| } | |||
| public void addRole(String roleName, LedgerPermission[] ledgerPermissions, | |||
| TransactionPermission[] transactionPermissions) { | |||
| RoleInitData roleInitData = new RoleInitData(roleName, ledgerPermissions, transactionPermissions); | |||
| roles.add(roleInitData); | |||
| roles.put(roleName, roleInitData); | |||
| } | |||
| @Override | |||
| public UserAuthInitSettings[] getUserAuthorizations() { | |||
| // TODO Auto-generated method stub | |||
| return null; | |||
| public UserAuthInitData[] getUserAuthorizations() { | |||
| return userAuthentications.values().toArray(new UserAuthInitData[userAuthentications.size()]); | |||
| } | |||
| public void addUserAuthencation(Bytes address, String[] roles, RolesPolicy policy) { | |||
| UserAuthInitData userAuth = new UserAuthInitData(); | |||
| userAuth.setUserAddress(address); | |||
| userAuth.setRoles(roles); | |||
| userAuth.setPolicy(policy); | |||
| userAuthentications.put(address, userAuth); | |||
| } | |||
| } | |||
| @@ -0,0 +1,40 @@ | |||
| package com.jd.blockchain.ledger; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| public class UserAuthInitData implements UserAuthInitSettings { | |||
| private Bytes userAddress; | |||
| private String[] roles; | |||
| private RolesPolicy policy; | |||
| public void setUserAddress(Bytes userAddress) { | |||
| this.userAddress = userAddress; | |||
| } | |||
| public void setRoles(String[] roles) { | |||
| this.roles = roles; | |||
| } | |||
| public void setPolicy(RolesPolicy policy) { | |||
| this.policy = policy; | |||
| } | |||
| @Override | |||
| public Bytes getUserAddress() { | |||
| return userAddress; | |||
| } | |||
| @Override | |||
| public String[] getRoles() { | |||
| return roles; | |||
| } | |||
| @Override | |||
| public RolesPolicy getPolicy() { | |||
| return policy; | |||
| } | |||
| } | |||
| @@ -1,22 +1,22 @@ | |||
| package com.jd.blockchain.transaction; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.ledger.CryptoSetting; | |||
| import com.jd.blockchain.ledger.LedgerInitSetting; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| public class LedgerInitData implements LedgerInitSetting { | |||
| public class LedgerInitData implements LedgerInitSetting { | |||
| private byte[] ledgerSeed; | |||
| private ParticipantNode[] consensusParticipants; | |||
| private CryptoSetting cryptoSetting; | |||
| private String consensusProvider; | |||
| private Bytes consensusSettings; | |||
| private long createdTime; | |||
| @Override | |||
| @@ -55,11 +55,15 @@ public class LedgerInitData implements LedgerInitSetting { | |||
| this.consensusSettings = consensusSettings; | |||
| } | |||
| public void setConsensusSettings(byte[] consensusSettings) { | |||
| this.consensusSettings = new Bytes(consensusSettings); | |||
| } | |||
| @Override | |||
| public String getConsensusProvider() { | |||
| return consensusProvider; | |||
| } | |||
| public void setConsensusProvider(String consensusProvider) { | |||
| this.consensusProvider = consensusProvider; | |||
| } | |||
| @@ -68,7 +72,7 @@ public class LedgerInitData implements LedgerInitSetting { | |||
| public long getCreatedTime() { | |||
| return createdTime; | |||
| } | |||
| public void setCreatedTime(long createdTime) { | |||
| this.createdTime = createdTime; | |||
| } | |||
| @@ -23,7 +23,7 @@ import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ConsensusParticipantConfig; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ParticipantProperties; | |||
| import com.jd.blockchain.ledger.LedgerPermission; | |||
| import com.jd.blockchain.ledger.RoleInitData; | |||
| import com.jd.blockchain.ledger.RolesPolicy; | |||
| @@ -145,7 +145,7 @@ public class LedgerInitPropertiesTest { | |||
| assertEquals("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", | |||
| initProps.getConsensusProvider()); | |||
| String[] cryptoProviders = initProps.getCryptoProviders(); | |||
| String[] cryptoProviders = initProps.getCryptoProperties().getProviders(); | |||
| assertEquals(2, cryptoProviders.length); | |||
| assertEquals("com.jd.blockchain.crypto.service.classic.ClassicCryptoService", cryptoProviders[0]); | |||
| assertEquals("com.jd.blockchain.crypto.service.sm.SMCryptoService", cryptoProviders[1]); | |||
| @@ -153,7 +153,7 @@ public class LedgerInitPropertiesTest { | |||
| // 验证参与方信息; | |||
| assertEquals(4, initProps.getConsensusParticipantCount()); | |||
| ConsensusParticipantConfig part0 = initProps.getConsensusParticipant(0); | |||
| ParticipantProperties part0 = initProps.getConsensusParticipant(0); | |||
| assertEquals("jd.com", part0.getName()); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey("3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9"); | |||
| assertEquals(pubKey0, part0.getPubKey()); | |||
| @@ -163,19 +163,19 @@ public class LedgerInitPropertiesTest { | |||
| assertArrayEquals(new String[] { "ADMIN", "MANAGER" }, part0.getRoles()); | |||
| assertEquals(RolesPolicy.UNION, part0.getRolesPolicy()); | |||
| ConsensusParticipantConfig part1 = initProps.getConsensusParticipant(1); | |||
| ParticipantProperties part1 = initProps.getConsensusParticipant(1); | |||
| assertEquals(false, part1.getInitializerAddress().isSecure()); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey("3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX"); | |||
| assertEquals(pubKey1, part1.getPubKey()); | |||
| assertArrayEquals(new String[] { "MANAGER" }, part1.getRoles()); | |||
| assertEquals(RolesPolicy.UNION, part1.getRolesPolicy()); | |||
| ConsensusParticipantConfig part2 = initProps.getConsensusParticipant(2); | |||
| ParticipantProperties part2 = initProps.getConsensusParticipant(2); | |||
| assertEquals("7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe", part2.getPubKey().toBase58()); | |||
| assertArrayEquals(new String[] { "MANAGER" }, part2.getRoles()); | |||
| assertEquals(RolesPolicy.UNION, part2.getRolesPolicy()); | |||
| ConsensusParticipantConfig part3 = initProps.getConsensusParticipant(3); | |||
| ParticipantProperties part3 = initProps.getConsensusParticipant(3); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey("3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk"); | |||
| assertEquals(pubKey3, part3.getPubKey()); | |||
| assertArrayEquals(new String[] { "GUEST" }, part3.getRoles()); | |||
| @@ -48,17 +48,17 @@ public class SecurityInitDataTest { | |||
| SecurityInitData securityInitData = new SecurityInitData(); | |||
| securityInitData.add("DEFAULT", | |||
| securityInitData.addRole("DEFAULT", | |||
| new LedgerPermission[] { LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT }, | |||
| new TransactionPermission[] { TransactionPermission.CONTRACT_OPERATION }); | |||
| securityInitData.add("ADMIN", | |||
| securityInitData.addRole("ADMIN", | |||
| new LedgerPermission[] { LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT }, | |||
| new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION, | |||
| TransactionPermission.CONTRACT_OPERATION }); | |||
| securityInitData.add("R1", | |||
| securityInitData.addRole("R1", | |||
| new LedgerPermission[] { LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT }, | |||
| null); | |||
| securityInitData.add("R2", null, new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION, | |||
| securityInitData.addRole("R2", null, new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION, | |||
| TransactionPermission.CONTRACT_OPERATION }); | |||
| String json = JSONSerializeUtils.serializeToJSON(securityInitData, true); | |||
| @@ -61,6 +61,12 @@ consensus.conf=classpath:bftsmart.config | |||
| crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ | |||
| com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
| #从存储中加载账本数据时,是否校验哈希;可选; | |||
| crypto.verify-hash=true | |||
| #哈希算法; | |||
| crypto.hash-algorithm=SHA256; | |||
| #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
| cons_parti.count=4 | |||
| @@ -398,9 +398,8 @@ public class ConsensusTest { | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps) { | |||
| return controller.prepareLocalPermission(id, privKey, setting, csProps); | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties initProps) { | |||
| return controller.prepareLocalPermission(id, privKey, initProps); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| @@ -186,9 +186,8 @@ public class GlobalPerformanceTest { | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = Utils.loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props, | |||
| Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -400,9 +399,8 @@ public class GlobalPerformanceTest { | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps) { | |||
| return controller.prepareLocalPermission(id, privKey, setting, csProps); | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties initProps) { | |||
| return controller.prepareLocalPermission(id, privKey, initProps); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| @@ -203,19 +203,18 @@ public class LedgerInitializeTest { | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties initProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, boolean autoVerifyHash) { | |||
| CryptoConfig cryptoSetting = new CryptoConfig(); | |||
| cryptoSetting.setAutoVerifyHash(autoVerifyHash); | |||
| cryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); | |||
| initProps.getCryptoProperties().setVerifyHash(autoVerifyHash); | |||
| initProps.getCryptoProperties().setHashAlgorithm("SHA256"); | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| partiKey = new AsymmetricKeypair(initProps.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); | |||
| return initProcess.initialize(currentId, privKey, initProps, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| @@ -42,6 +42,7 @@ import com.jd.blockchain.tools.initializer.LedgerInitCommand; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.HttpInitConsensServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| @@ -112,10 +113,12 @@ public class LedgerInitializeWebTest { | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| // 测试生成“账本初始化许可”; | |||
| LedgerInitProposal permission0 = testPreparePermisssion(node0, privkey0, initSetting, csProps); | |||
| LedgerInitProposal permission1 = testPreparePermisssion(node1, privkey1, initSetting, csProps); | |||
| LedgerInitProposal permission2 = testPreparePermisssion(node2, privkey2, initSetting, csProps); | |||
| LedgerInitProposal permission3 = testPreparePermisssion(node3, privkey3, initSetting, csProps); | |||
| LedgerInitConfiguration initConfig = LedgerInitConfiguration.create(initSetting); | |||
| initConfig.setConsensusSettings(csProvider, csProps); | |||
| LedgerInitProposal permission0 = testPreparePermisssion(node0, privkey0, initConfig); | |||
| LedgerInitProposal permission1 = testPreparePermisssion(node1, privkey1, initConfig); | |||
| LedgerInitProposal permission2 = testPreparePermisssion(node2, privkey2, initConfig); | |||
| LedgerInitProposal permission3 = testPreparePermisssion(node3, privkey3, initConfig); | |||
| TransactionContent initTxContent0 = node0.getInitTxContent(); | |||
| TransactionContent initTxContent1 = node1.getInitTxContent(); | |||
| @@ -206,8 +209,8 @@ public class LedgerInitializeWebTest { | |||
| } | |||
| private LedgerInitProposal testPreparePermisssion(NodeWebContext node, PrivKey privKey, | |||
| LedgerInitProperties setting, ConsensusSettings csProps) { | |||
| LedgerInitProposal permission = node.preparePermision(privKey, setting, csProps); | |||
| LedgerInitConfiguration setting) { | |||
| LedgerInitProposal permission = node.preparePermision(privKey, setting); | |||
| return permission; | |||
| } | |||
| @@ -457,9 +460,8 @@ public class LedgerInitializeWebTest { | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps) { | |||
| return controller.prepareLocalPermission(id, privKey, setting, csProps); | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitConfiguration initConfig) { | |||
| return controller.prepareLocalPermission(id, privKey, initConfig); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| @@ -26,6 +26,7 @@ import com.jd.blockchain.ledger.CryptoSetting; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerConfiguration; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| @@ -35,6 +36,7 @@ import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.InitConsensusServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| @@ -169,12 +171,16 @@ public class Utils { | |||
| ConsensusSettings csProps, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, | |||
| Prompter prompter, CryptoSetting cryptoSetting) { | |||
| LedgerInitConfiguration ledgerInitConfig = LedgerInitConfiguration.create(setting); | |||
| ledgerInitConfig.getLedgerSettings().setCryptoSetting(cryptoSetting); | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| @@ -27,6 +27,8 @@ import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.RolesConfigureOperation; | |||
| import com.jd.blockchain.ledger.UserAuthorizeOperation; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| @@ -57,6 +59,8 @@ public class LedgerInitializeTest { | |||
| static { | |||
| DataContractRegistry.register(LedgerInitOperation.class); | |||
| DataContractRegistry.register(UserRegisterOperation.class); | |||
| DataContractRegistry.register(RolesConfigureOperation.class); | |||
| DataContractRegistry.register(UserAuthorizeOperation.class); | |||
| } | |||
| private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
| @@ -257,13 +261,16 @@ public class LedgerInitializeTest { | |||
| cryptoSetting.setSupportedProviders(supportedProviders); | |||
| cryptoSetting.setAutoVerifyHash(autoVerifyHash); | |||
| cryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); | |||
| setting.getCryptoProperties().setHashAlgorithm("SHA256"); | |||
| setting.getCryptoProperties().setVerifyHash(autoVerifyHash); | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| @@ -10,7 +10,6 @@ import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import com.jd.blockchain.transaction.SignatureUtils; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.context.ConfigurableApplicationContext; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| @@ -40,9 +39,10 @@ import com.jd.blockchain.tools.initializer.LedgerInitCommand; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.HttpInitConsensServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.transaction.TxRequestBuilder; | |||
| import com.jd.blockchain.transaction.SignatureUtils; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.BytesUtils; | |||
| @@ -79,9 +79,8 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
| // 加载共识配置; | |||
| Properties props = loadConsensusSetting(consensusConfig.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(consensusConfig.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props, | |||
| Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -116,10 +115,12 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| // 测试生成“账本初始化许可”; | |||
| LedgerInitProposal permission0 = testPreparePermisssion(node0, privkey0, initSetting, csProps); | |||
| LedgerInitProposal permission1 = testPreparePermisssion(node1, privkey1, initSetting, csProps); | |||
| LedgerInitProposal permission2 = testPreparePermisssion(node2, privkey2, initSetting, csProps); | |||
| LedgerInitProposal permission3 = testPreparePermisssion(node3, privkey3, initSetting, csProps); | |||
| LedgerInitConfiguration initConfig = LedgerInitConfiguration.create(initSetting); | |||
| initConfig.setConsensusSettings(csProvider, csProps); | |||
| LedgerInitProposal permission0 = testPreparePermisssion(node0, privkey0, initConfig); | |||
| LedgerInitProposal permission1 = testPreparePermisssion(node1, privkey1, initConfig); | |||
| LedgerInitProposal permission2 = testPreparePermisssion(node2, privkey2, initConfig); | |||
| LedgerInitProposal permission3 = testPreparePermisssion(node3, privkey3, initConfig); | |||
| TransactionContent initTxContent0 = node0.getInitTxContent(); | |||
| TransactionContent initTxContent1 = node1.getInitTxContent(); | |||
| @@ -241,8 +242,8 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
| } | |||
| private LedgerInitProposal testPreparePermisssion(NodeWebContext node, PrivKey privKey, | |||
| LedgerInitProperties setting, ConsensusSettings csProps) { | |||
| LedgerInitProposal permission = node.preparePermision(privKey, setting, csProps); | |||
| LedgerInitConfiguration setting) { | |||
| LedgerInitProposal permission = node.preparePermision(privKey, setting); | |||
| assertEquals(node.getId(), permission.getParticipantId()); | |||
| assertNotNull(permission.getTransactionSignature()); | |||
| @@ -385,9 +386,8 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps) { | |||
| return controller.prepareLocalPermission(id, privKey, setting, csProps); | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitConfiguration setting) { | |||
| return controller.prepareLocalPermission(id, privKey, setting); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| @@ -15,7 +15,7 @@ | |||
| <module>tools-initializer</module> | |||
| <module>tools-initializer-booter</module> | |||
| <module>tools-capability</module> | |||
| <module>tools-mocker</module> | |||
| <!-- <module>tools-mocker</module> --> | |||
| <!-- <module>tools-package</module> --> | |||
| </modules> | |||
| </project> | |||
| @@ -16,7 +16,7 @@ import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ConsensusParticipantConfig; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ParticipantProperties; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig.BindingConfig; | |||
| import com.jd.blockchain.utils.ArgumentSet; | |||
| @@ -94,7 +94,7 @@ public class LedgerInitCommand { | |||
| // 加载全部公钥; | |||
| int currId = -1; | |||
| for (int i = 0; i < ledgerInitProperties.getConsensusParticipantCount(); i++) { | |||
| ConsensusParticipantConfig partiConf = ledgerInitProperties.getConsensusParticipant(i); | |||
| ParticipantProperties partiConf = ledgerInitProperties.getConsensusParticipant(i); | |||
| // String partiAddress = partiConf.getAddress(); | |||
| // if (partiAddress == null) { | |||
| // if (partiConf.getPubKeyPath() != null) { | |||
| @@ -4,6 +4,7 @@ import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.ledger.CryptoSetting; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| /** | |||
| * | |||
| @@ -28,13 +29,13 @@ public interface LedgerInitProcess { | |||
| /** | |||
| * @param currentId | |||
| * @param privKey | |||
| * @param ledgerInitProps | |||
| * @param ledgerInitConfig | |||
| * @param dbConnConfig | |||
| * @param prompter | |||
| * @param cryptoSetting | |||
| * @return | |||
| */ | |||
| HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, CryptoSetting cryptoSetting); | |||
| HashDigest initialize(int currentId, PrivKey privKey, LedgerInitConfiguration ledgerInitConfig, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter); | |||
| } | |||
| @@ -0,0 +1,281 @@ | |||
| package com.jd.blockchain.tools.initializer.web; | |||
| import java.util.Arrays; | |||
| import java.util.Comparator; | |||
| import java.util.LinkedHashSet; | |||
| import java.util.List; | |||
| import java.util.Properties; | |||
| import java.util.Set; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| 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.CryptoSetting; | |||
| import com.jd.blockchain.ledger.LedgerInitException; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.CryptoProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ParticipantProperties; | |||
| import com.jd.blockchain.ledger.LedgerPermission; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.SecurityInitData; | |||
| import com.jd.blockchain.ledger.TransactionPermission; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerSecurityManager; | |||
| import com.jd.blockchain.transaction.LedgerInitData; | |||
| import com.jd.blockchain.utils.StringUtils; | |||
| public class LedgerInitConfiguration { | |||
| private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
| SMCryptoService.class.getName() }; | |||
| private static final String DEFAULT_HASH_ALGORITHM = "SHA256"; | |||
| private ParticipantProperties[] participants; | |||
| private ConsensusConfig consensusConfiguration; | |||
| private CryptoConfig cryptoConfig; | |||
| private ConsensusConfig consensusConfig; | |||
| private LedgerInitData ledgerSettings; | |||
| private SecurityInitData securitySettings; | |||
| public ParticipantProperties[] getParticipants() { | |||
| return participants; | |||
| } | |||
| public int getParticipantCount() { | |||
| return participants.length; | |||
| } | |||
| /** | |||
| * @param id | |||
| * @return | |||
| */ | |||
| public ParticipantProperties getParticipant(int id) { | |||
| // 注:解析的过程确保了参与方列表是升序排列,且列表中第一个参与方的 id 为 0, id 以 1 递增; | |||
| return participants[id]; | |||
| } | |||
| public ConsensusConfig getConsensusConfiguration() { | |||
| return consensusConfiguration; | |||
| } | |||
| public CryptoConfig getCryptoConfig() { | |||
| return cryptoConfig; | |||
| } | |||
| public ConsensusConfig getConsensusConfig() { | |||
| return consensusConfig; | |||
| } | |||
| public LedgerInitData getLedgerSettings() { | |||
| return ledgerSettings; | |||
| } | |||
| public SecurityInitData getSecuritySettings() { | |||
| return securitySettings; | |||
| } | |||
| private LedgerInitConfiguration() { | |||
| } | |||
| public void setConsensusSettings(ConsensusProvider consensusProvider, ConsensusSettings consensusSettings) { | |||
| byte[] consensusSettingBytes = encodeConsensusSettings(consensusProvider, consensusSettings); | |||
| ledgerSettings.setConsensusProvider(consensusProvider.getName()); | |||
| ledgerSettings.setConsensusSettings(consensusSettingBytes); | |||
| } | |||
| public static LedgerInitConfiguration create(LedgerInitProperties ledgerInitProps) { | |||
| LedgerInitConfiguration ledgerConfig = new LedgerInitConfiguration(); | |||
| CryptoConfig cryptoConfig = createCryptoConfig(ledgerInitProps.getCryptoProperties()); | |||
| ledgerConfig.cryptoConfig = cryptoConfig; | |||
| ConsensusConfig consensusConfig = createConsensusConfig(ledgerInitProps); | |||
| ledgerConfig.consensusConfig = consensusConfig; | |||
| ParticipantProperties[] participants = resolveParticipants(ledgerInitProps); | |||
| ledgerConfig.participants = participants; | |||
| LedgerInitData ledgerSettings = createLedgerInitSettings(ledgerInitProps, cryptoConfig, consensusConfig, | |||
| participants); | |||
| ledgerConfig.ledgerSettings = ledgerSettings; | |||
| SecurityInitData securitySettings = createSecurityInitSettings(ledgerInitProps, participants); | |||
| ledgerConfig.securitySettings = securitySettings; | |||
| return ledgerConfig; | |||
| } | |||
| private static ConsensusConfig createConsensusConfig(LedgerInitProperties initProps) { | |||
| ConsensusProvider consensusProvider = ConsensusProviders.getProvider(initProps.getConsensusProvider()); | |||
| Properties csProps = initProps.getConsensusConfig(); | |||
| ConsensusSettings protocolSettings = consensusProvider.getSettingsFactory().getConsensusSettingsBuilder() | |||
| .createSettings(csProps, initProps.getConsensusParticipantNodes()); | |||
| ConsensusConfig config = new ConsensusConfig(); | |||
| config.setProvider(consensusProvider); | |||
| config.setProtocolSettings(protocolSettings); | |||
| return config; | |||
| } | |||
| private static CryptoConfig createCryptoConfig(CryptoProperties cryptoProperties) { | |||
| // 总是包含默认的提供者; | |||
| Set<String> cryptoProviderNames = new LinkedHashSet<String>(); | |||
| for (String providerName : SUPPORTED_PROVIDERS) { | |||
| cryptoProviderNames.add(providerName); | |||
| } | |||
| if (cryptoProperties.getProviders() != null) { | |||
| for (String providerName : cryptoProperties.getProviders()) { | |||
| cryptoProviderNames.add(providerName); | |||
| } | |||
| } | |||
| CryptoProvider[] cryptoProviders = new CryptoProvider[cryptoProviderNames.size()]; | |||
| int i = 0; | |||
| for (String providerName : cryptoProviderNames) { | |||
| cryptoProviders[i] = Crypto.getProvider(providerName); | |||
| i++; | |||
| } | |||
| String hashAlgorithmName = StringUtils.trim(cryptoProperties.getHashAlgorithm()); | |||
| hashAlgorithmName = hashAlgorithmName.length() == 0 ? DEFAULT_HASH_ALGORITHM : hashAlgorithmName; | |||
| CryptoAlgorithm hashAlgorithm = Crypto.getAlgorithm(hashAlgorithmName); | |||
| CryptoConfig cryptoConfig = new CryptoConfig(); | |||
| cryptoConfig.setSupportedProviders(cryptoProviders); | |||
| cryptoConfig.setAutoVerifyHash(cryptoProperties.isVerifyHash()); | |||
| cryptoConfig.setHashAlgorithm(hashAlgorithm); | |||
| return cryptoConfig; | |||
| } | |||
| private static SecurityInitData createSecurityInitSettings(LedgerInitProperties ledgerInitProps, | |||
| ParticipantProperties[] participants) { | |||
| // 设置角色; | |||
| SecurityInitData securityInitData = new SecurityInitData(); | |||
| securityInitData.setRoles(ledgerInitProps.getRoles()); | |||
| // 如果没有默认角色,则创建“默认”角色; | |||
| if (securityInitData.getRolesCount() == 0) { | |||
| securityInitData.addRole(LedgerSecurityManager.DEFAULT_ROLE, LedgerPermission.values(), | |||
| TransactionPermission.values()); | |||
| } else if (!securityInitData.containsRole(LedgerSecurityManager.DEFAULT_ROLE)) { | |||
| // 如果定义了角色,则必须显式地定义“默认”角色; | |||
| throw new LedgerInitException("Miss definition of role[DEFAULT]!"); | |||
| } | |||
| // 设置授权; | |||
| for (ParticipantProperties partiProps : participants) { | |||
| String[] roles = partiProps.getRoles(); | |||
| for (String role : roles) { | |||
| if (!securityInitData.containsRole(role)) { | |||
| throw new LedgerInitException( | |||
| String.format("The role[%s] authenticated to participant[%s-%s] is not defined!", role, | |||
| partiProps.getId(), partiProps.getName())); | |||
| } | |||
| } | |||
| securityInitData.addUserAuthencation(partiProps.getAddress(), roles, partiProps.getRolesPolicy()); | |||
| } | |||
| return securityInitData; | |||
| } | |||
| private static LedgerInitData createLedgerInitSettings(LedgerInitProperties ledgerProps, | |||
| CryptoSetting cryptoSetting, ConsensusConfig consensusConfig, ParticipantProperties[] participants) { | |||
| // 创建初始化配置; | |||
| LedgerInitData initSetting = new LedgerInitData(); | |||
| initSetting.setLedgerSeed(ledgerProps.getLedgerSeed()); | |||
| initSetting.setCryptoSetting(cryptoSetting); | |||
| initSetting.setConsensusParticipants(participants); | |||
| initSetting.setCreatedTime(ledgerProps.getCreatedTime()); | |||
| // 创建共识配置; | |||
| try { | |||
| byte[] consensusSettingsBytes = encodeConsensusSettings(consensusConfig.getProvider(), | |||
| consensusConfig.protocolSettings); | |||
| initSetting.setConsensusProvider(consensusConfig.getProvider().getName()); | |||
| initSetting.setConsensusSettings(consensusSettingsBytes); | |||
| } catch (Exception e) { | |||
| throw new LedgerInitException("Create default consensus config failed! --" + e.getMessage(), e); | |||
| } | |||
| return initSetting; | |||
| } | |||
| public static byte[] encodeConsensusSettings(ConsensusProvider consensusProvider, | |||
| ConsensusSettings consensusSettings) { | |||
| return consensusProvider.getSettingsFactory().getConsensusSettingsEncoder().encode(consensusSettings); | |||
| } | |||
| /** | |||
| * 解析参与方列表; | |||
| * | |||
| * @param ledgerInitProps | |||
| * @return | |||
| */ | |||
| private static ParticipantProperties[] resolveParticipants(LedgerInitProperties ledgerInitProps) { | |||
| List<ParticipantProperties> partiList = ledgerInitProps.getConsensusParticipants(); | |||
| ParticipantProperties[] parties = new ParticipantProperties[partiList.size()]; | |||
| parties = partiList.toArray(parties); | |||
| ParticipantProperties[] orderedParties = sortAndVerify(parties); | |||
| return orderedParties; | |||
| } | |||
| /** | |||
| * 对参与者列表按照 id 进行升序排列,并校验id是否从 1 开始且没有跳跃; | |||
| * | |||
| * @param parties | |||
| * @return | |||
| */ | |||
| private static ParticipantProperties[] sortAndVerify(ParticipantProperties[] parties) { | |||
| Arrays.sort(parties, new Comparator<ParticipantProperties>() { | |||
| @Override | |||
| public int compare(ParticipantProperties o1, ParticipantProperties o2) { | |||
| return o1.getId() - o2.getId(); | |||
| } | |||
| }); | |||
| for (int i = 0; i < parties.length; i++) { | |||
| if (parties[i].getId() != i) { | |||
| throw new LedgerInitException( | |||
| "The ids of participants are not match their positions in the participant-list!"); | |||
| } | |||
| } | |||
| return parties; | |||
| } | |||
| public static class ConsensusConfig { | |||
| private ConsensusProvider provider; | |||
| private ConsensusSettings protocolSettings; | |||
| public ConsensusSettings getProtocolSettings() { | |||
| return protocolSettings; | |||
| } | |||
| public void setProtocolSettings(ConsensusSettings protocolSettings) { | |||
| this.protocolSettings = protocolSettings; | |||
| } | |||
| public ConsensusProvider getProvider() { | |||
| return provider; | |||
| } | |||
| public void setProvider(ConsensusProvider provider) { | |||
| this.provider = provider; | |||
| } | |||
| } | |||
| } | |||
| @@ -3,9 +3,7 @@ package com.jd.blockchain.tools.initializer.web; | |||
| import java.io.IOException; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Comparator; | |||
| import java.util.List; | |||
| import java.util.Properties; | |||
| import java.util.Random; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.TimeUnit; | |||
| @@ -18,28 +16,19 @@ import org.springframework.web.bind.annotation.RequestMethod; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| 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.SignatureFunction; | |||
| 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.DigitalSignature; | |||
| import com.jd.blockchain.ledger.LedgerInitException; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ConsensusParticipantConfig; | |||
| import com.jd.blockchain.ledger.LedgerInitSetting; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ParticipantProperties; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| import com.jd.blockchain.ledger.TransactionRequest; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposalData; | |||
| @@ -51,9 +40,7 @@ import com.jd.blockchain.tools.initializer.InitializingStep; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.transaction.DigitalSignatureBlob; | |||
| import com.jd.blockchain.transaction.LedgerInitData; | |||
| import com.jd.blockchain.transaction.SignatureUtils; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.InvocationResult; | |||
| import com.jd.blockchain.utils.io.BytesUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| @@ -71,20 +58,17 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| DataContractRegistry.register(TransactionRequest.class); | |||
| } | |||
| private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
| SMCryptoService.class.getName() }; | |||
| private static final String DEFAULT_SIGN_ALGORITHM = "ED25519"; | |||
| private final SignatureFunction SIGN_FUNC; | |||
| private volatile LedgerInitProposal localPermission; | |||
| private volatile LedgerInitConfiguration ledgerInitConfig; | |||
| private volatile LedgerInitializer initializer; | |||
| private volatile int currentId = -1; | |||
| private volatile LedgerInitProposal localPermission; | |||
| private volatile LedgerInitSetting ledgerInitSetting; | |||
| private volatile int currentId = -1; | |||
| private volatile LedgerInitProposal[] permissions; | |||
| @@ -92,8 +76,6 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| private volatile Prompter prompter; | |||
| private volatile ConsensusProvider consensusProvider; | |||
| private volatile LedgerInitDecision localDecision; | |||
| private volatile DecisionResultHandle[] decisions; | |||
| @@ -138,35 +120,36 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| this.prompter = prompter; | |||
| } | |||
| private void setConsensusProvider(ConsensusProvider consensusProvider) { | |||
| this.consensusProvider = consensusProvider; | |||
| } | |||
| @Override | |||
| public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
| return initialize(currentId, privKey, ledgerInitProps, dbConnConfig, prompter, createDefaultCryptoSetting()); | |||
| LedgerInitConfiguration initConfig = LedgerInitConfiguration.create(ledgerInitProps); | |||
| return initialize(currentId, privKey, initConfig, dbConnConfig, prompter); | |||
| } | |||
| @Override | |||
| public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, CryptoSetting cryptoSetting) { | |||
| if (this.ledgerInitSetting != null) { | |||
| public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitConfiguration initConfig, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
| if (initConfig == null) { | |||
| throw new IllegalArgumentException("Ledger init configuration is null"); | |||
| } | |||
| if (this.ledgerInitConfig != null) { | |||
| throw new IllegalStateException("ledger init process has already started."); | |||
| } | |||
| setPrompter(prompter); | |||
| Properties csProps = ledgerInitProps.getConsensusConfig(); | |||
| ConsensusProvider csProvider = ConsensusProviders.getProvider(ledgerInitProps.getConsensusProvider()); | |||
| ConsensusSettings csSettings = csProvider.getSettingsFactory().getConsensusSettingsBuilder() | |||
| .createSettings(csProps, ledgerInitProps.getConsensusParticipantNodes()); | |||
| setConsensusProvider(csProvider); | |||
| // Properties csProps = ledgerInitProps.getConsensusConfig(); | |||
| // ConsensusProvider csProvider = ConsensusProviders.getProvider(ledgerInitProps.getConsensusProvider()); | |||
| // ConsensusSettings csSettings = csProvider.getSettingsFactory().getConsensusSettingsBuilder() | |||
| // .createSettings(csProps, ledgerInitProps.getConsensusParticipantNodes()); | |||
| // setConsensusProvider(csProvider); | |||
| prompter.info("Init settings and sign permision..."); | |||
| prepareLocalPermission(currentId, privKey, ledgerInitProps, csSettings, cryptoSetting); | |||
| this.ledgerInitConfig = initConfig; | |||
| prepareLocalPermission(currentId, privKey, ledgerInitConfig); | |||
| prompter.confirm(InitializingStep.PERMISSION_READY.toString(), | |||
| "Ledger init permission has already prepared! Any key to continue..."); | |||
| @@ -212,7 +195,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| // 生成签名决定; | |||
| this.localDecision = makeDecision(currentId, initializer.getLedgerHash(), privKey); | |||
| this.decisions = new DecisionResultHandle[this.ledgerInitSetting.getConsensusParticipants().length]; | |||
| this.decisions = new DecisionResultHandle[ledgerInitConfig.getParticipantCount()]; | |||
| for (int i = 0; i < decisions.length; i++) { | |||
| // 参与者的 id 是依次递增的; | |||
| this.decisions[i] = new DecisionResultHandle(i); | |||
| @@ -223,7 +206,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| } | |||
| private DigitalSignature[] getNodesSignatures() { | |||
| ParticipantNode[] parties = this.ledgerInitSetting.getConsensusParticipants(); | |||
| ParticipantNode[] parties = this.ledgerInitConfig.getParticipants(); | |||
| DigitalSignature[] signatures = new DigitalSignature[parties.length]; | |||
| for (int i = 0; i < parties.length; i++) { | |||
| PubKey pubKey = parties[i].getPubKey(); | |||
| @@ -298,78 +281,57 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| return allPermitted; | |||
| } | |||
| public CryptoSetting createDefaultCryptoSetting() { | |||
| CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
| for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
| supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
| } | |||
| CryptoConfig defCryptoSetting = new CryptoConfig(); | |||
| defCryptoSetting.setSupportedProviders(supportedProviders); | |||
| defCryptoSetting.setAutoVerifyHash(true); | |||
| defCryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); | |||
| return defCryptoSetting; | |||
| } | |||
| public LedgerInitProposal prepareLocalPermission(int currentId, PrivKey privKey, LedgerInitProperties ledgerProps, | |||
| ConsensusSettings consensusProps) { | |||
| CryptoSetting defCryptoSetting = createDefaultCryptoSetting(); | |||
| return prepareLocalPermission(currentId, privKey, ledgerProps, consensusProps, defCryptoSetting); | |||
| } | |||
| public LedgerInitProposal prepareLocalPermission(int currentId, PrivKey privKey, LedgerInitProperties ledgerProps, | |||
| ConsensusSettings csSettings, CryptoSetting cryptoSetting) { | |||
| // public CryptoSetting createDefaultCryptoSetting() { | |||
| // CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
| // for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
| // supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
| // } | |||
| // CryptoConfig defCryptoSetting = new CryptoConfig(); | |||
| // defCryptoSetting.setSupportedProviders(supportedProviders); | |||
| // defCryptoSetting.setAutoVerifyHash(true); | |||
| // defCryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); | |||
| // | |||
| // return defCryptoSetting; | |||
| // } | |||
| // | |||
| public LedgerInitProposal prepareLocalPermission(int currentId, PrivKey privKey, | |||
| LedgerInitProperties ledgerInitProps) { | |||
| LedgerInitConfiguration ledgerInitConfiguration = LedgerInitConfiguration.create(ledgerInitProps); | |||
| return prepareLocalPermission(currentId, privKey, ledgerInitConfiguration); | |||
| } | |||
| public LedgerInitProposal prepareLocalPermission(int currentId, PrivKey privKey, | |||
| LedgerInitConfiguration ledgerInitConfig) { | |||
| // 创建初始化配置; | |||
| LedgerInitData initSetting = new LedgerInitData(); | |||
| initSetting.setLedgerSeed(ledgerProps.getLedgerSeed()); | |||
| initSetting.setCryptoSetting(cryptoSetting); | |||
| List<ConsensusParticipantConfig> partiList = ledgerProps.getConsensusParticipants(); | |||
| ConsensusParticipantConfig[] parties = new ConsensusParticipantConfig[partiList.size()]; | |||
| parties = partiList.toArray(parties); | |||
| ConsensusParticipantConfig[] orderedParties = sortAndVerify(parties); | |||
| initSetting.setConsensusParticipants(orderedParties); | |||
| initSetting.setCreatedTime(ledgerProps.getCreatedTime()); | |||
| // 创建默认的共识配置; | |||
| try { | |||
| // ConsensusConfig csConfig = new ConsensusConfig(); | |||
| byte[] csSettingBytes = consensusProvider.getSettingsFactory().getConsensusSettingsEncoder() | |||
| .encode(csSettings); | |||
| initSetting.setConsensusProvider(consensusProvider.getName()); | |||
| initSetting.setConsensusSettings(new Bytes(csSettingBytes)); | |||
| } catch (Exception e) { | |||
| throw new LedgerInitException("Create default consensus config failed! --" + e.getMessage(), e); | |||
| } | |||
| if (currentId < 0 || currentId >= orderedParties.length) { | |||
| ParticipantProperties[] participants = ledgerInitConfig.getParticipants(); | |||
| if (currentId < 0 || currentId >= participants.length) { | |||
| throw new LedgerInitException("Your id is out of bound of participant list!"); | |||
| } | |||
| this.currentId = currentId; | |||
| this.ledgerInitSetting = initSetting; | |||
| // 校验当前的公钥、私钥是否匹配; | |||
| byte[] testBytes = BytesUtils.toBytes(currentId); | |||
| SignatureDigest testSign = SIGN_FUNC.sign(privKey, testBytes); | |||
| PubKey myPubKey = orderedParties[currentId].getPubKey(); | |||
| PubKey myPubKey = participants[currentId].getPubKey(); | |||
| if (!SIGN_FUNC.verify(testSign, myPubKey, testBytes)) { | |||
| throw new LedgerInitException("Your pub-key specified in the init-settings isn't match your priv-key!"); | |||
| } | |||
| this.initializerAddresses = new NetworkAddress[orderedParties.length]; | |||
| this.initializerAddresses = new NetworkAddress[participants.length]; | |||
| // 记录每个参与方的账本初始化服务地址; | |||
| for (int i = 0; i < orderedParties.length; i++) { | |||
| initializerAddresses[i] = orderedParties[i].getInitializerAddress(); | |||
| for (int i = 0; i < participants.length; i++) { | |||
| initializerAddresses[i] = participants[i].getInitializerAddress(); | |||
| } | |||
| // 初始化账本; | |||
| this.initializer = LedgerInitializer.create(ledgerInitSetting); | |||
| this.initializer = LedgerInitializer.create(ledgerInitConfig.getLedgerSettings(), | |||
| ledgerInitConfig.getSecuritySettings()); | |||
| // 对初始交易签名,生成当前参与者的账本初始化许可; | |||
| SignatureDigest permissionSign = initializer.signTransaction(privKey); | |||
| LedgerInitProposalData permission = new LedgerInitProposalData(currentId, permissionSign); | |||
| this.currentId = currentId; | |||
| this.permissions = new LedgerInitProposal[initSetting.getConsensusParticipants().length]; | |||
| this.permissions = new LedgerInitProposal[ledgerInitConfig.getParticipantCount()]; | |||
| this.permissions[currentId] = permission; | |||
| this.localPermission = permission; | |||
| @@ -397,7 +359,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| private boolean startRequestPermissions(int currentId, PrivKey privKey) { | |||
| SignatureDigest reqAuthSign = signPermissionRequest(currentId, privKey); | |||
| ParticipantNode[] participants = ledgerInitSetting.getConsensusParticipants(); | |||
| ParticipantNode[] participants = ledgerInitConfig.getParticipants(); | |||
| // 异步请求结果列表;不包括已经获得许可的参与方; | |||
| InvocationResult<?>[] results = new InvocationResult<?>[participants.length]; | |||
| @@ -457,7 +419,8 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| continue; | |||
| } | |||
| if (!SignatureUtils.verifySignature(initializer.getTransactionContent(), permission.getTransactionSignature(), pubKey)) { | |||
| if (!SignatureUtils.verifySignature(initializer.getTransactionContent(), | |||
| permission.getTransactionSignature(), pubKey)) { | |||
| prompter.error("Invalid permission from participant! --[Id=%s][name=%s]", participants[i].getAddress(), | |||
| participants[i].getName()); | |||
| allPermitted = false; | |||
| @@ -477,7 +440,8 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| } | |||
| public SignatureDigest signPermissionRequest(int requesterId, PrivKey privKey) { | |||
| byte[] reqAuthBytes = BytesUtils.concat(BytesUtils.toBytes(requesterId), ledgerInitSetting.getLedgerSeed()); | |||
| byte[] reqAuthBytes = BytesUtils.concat(BytesUtils.toBytes(requesterId), | |||
| ledgerInitConfig.getLedgerSettings().getLedgerSeed()); | |||
| SignatureDigest reqAuthSign = SIGN_FUNC.sign(privKey, reqAuthBytes); | |||
| return reqAuthSign; | |||
| } | |||
| @@ -523,7 +487,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| throw new LedgerInitException("There is a id conflict!"); | |||
| } | |||
| int retry = 0; | |||
| while (currentId == -1 || ledgerInitSetting == null || localPermission == null) { | |||
| while (currentId == -1 || ledgerInitConfig == null || localPermission == null) { | |||
| // 本地尚未完成初始化; | |||
| if (retry < 30) { | |||
| try { | |||
| @@ -537,11 +501,12 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| retry++; | |||
| } | |||
| ParticipantNode[] participants = ledgerInitSetting.getConsensusParticipants(); | |||
| ParticipantNode[] participants = ledgerInitConfig.getParticipants(); | |||
| if (requesterId < 0 || requesterId >= participants.length) { | |||
| throw new LedgerInitException("The id of requester is out of the bound of participant list!"); | |||
| } | |||
| byte[] requestCodeBytes = BytesUtils.concat(BytesUtils.toBytes(requesterId), ledgerInitSetting.getLedgerSeed()); | |||
| byte[] requestCodeBytes = BytesUtils.concat(BytesUtils.toBytes(requesterId), | |||
| ledgerInitConfig.getLedgerSettings().getLedgerSeed()); | |||
| PubKey requesterPubKey = participants[requesterId].getPubKey(); | |||
| if (!SIGN_FUNC.verify(signature, requesterPubKey, requestCodeBytes)) { | |||
| throw new LedgerInitException("The requester signature is invalid!"); | |||
| @@ -680,8 +645,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| } | |||
| // 检查签名; | |||
| PubKey targetPubKey = ledgerInitSetting.getConsensusParticipants()[targetDecision.getParticipantId()] | |||
| .getPubKey(); | |||
| PubKey targetPubKey = ledgerInitConfig.getParticipant(targetDecision.getParticipantId()).getPubKey(); | |||
| byte[] deciBytes = getDecisionBytes(targetDecision.getParticipantId(), targetDecision.getLedgerHash()); | |||
| if ((!SIGN_FUNC.verify(targetDecision.getSignature(), targetPubKey, deciBytes)) | |||
| && resultHandle.getValue() == null) { | |||
| @@ -733,28 +697,6 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| } | |||
| } | |||
| /** | |||
| * 对参与者列表按照 id 进行升序排列,并校验id是否从 1 开始且没有跳跃; | |||
| * | |||
| * @param parties | |||
| * @return | |||
| */ | |||
| private ConsensusParticipantConfig[] sortAndVerify(ConsensusParticipantConfig[] parties) { | |||
| Arrays.sort(parties, new Comparator<ConsensusParticipantConfig>() { | |||
| @Override | |||
| public int compare(ConsensusParticipantConfig o1, ConsensusParticipantConfig o2) { | |||
| return o1.getId() - o2.getId(); | |||
| } | |||
| }); | |||
| for (int i = 0; i < parties.length; i++) { | |||
| if (parties[i].getId() != i) { | |||
| throw new LedgerInitException( | |||
| "The ids of participants are not match their positions in the participant-list!"); | |||
| } | |||
| } | |||
| return parties; | |||
| } | |||
| private static class DecisionResultHandle extends InvocationResult<LedgerInitDecision> { | |||
| private final int PARTICIPANT_ID; | |||
| @@ -24,7 +24,7 @@ import com.jd.blockchain.ledger.CryptoSetting; | |||
| import com.jd.blockchain.ledger.DigitalSignature; | |||
| import com.jd.blockchain.ledger.LedgerInitException; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ConsensusParticipantConfig; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ParticipantProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitSetting; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| @@ -40,6 +40,7 @@ import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitDecisionData; | |||
| import com.jd.blockchain.transaction.DigitalSignatureBlob; | |||
| @@ -74,7 +75,7 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon | |||
| private volatile int currentId = -1; | |||
| private volatile LedgerInitSetting ledgerInitSetting; | |||
| private volatile LedgerInitConfiguration ledgerInitConfig; | |||
| // private volatile LedgerInitPermission[] permissions; | |||
| // private volatile LedgerInitPermission permission; | |||
| @@ -130,25 +131,22 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon | |||
| @Override | |||
| public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
| return initialize(currentId, privKey, ledgerInitProps, dbConnConfig, prompter, createDefaultCryptoSetting()); | |||
| LedgerInitConfiguration ledgerInitConfig = LedgerInitConfiguration.create(ledgerInitProps); | |||
| return initialize(currentId, privKey, ledgerInitConfig, dbConnConfig, prompter); | |||
| } | |||
| @Override | |||
| public synchronized HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, CryptoSetting cryptoSetting) { | |||
| if (this.ledgerInitSetting != null) { | |||
| public synchronized HashDigest initialize(int currentId, PrivKey privKey, LedgerInitConfiguration ledgerInitProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
| if (this.ledgerInitConfig != null) { | |||
| throw new IllegalStateException("ledger init process has already started."); | |||
| } | |||
| setPrompter(prompter); | |||
| ConsensusProvider csProvider = ConsensusProviders.getProvider(ledgerInitProps.getConsensusProvider()); | |||
| setConsensusProvider(csProvider); | |||
| prompter.info("Init settings and sign permision..."); | |||
| prepareLocalProposal(currentId, privKey, ledgerInitProps, null, cryptoSetting); | |||
| prepareLocalProposal(currentId, privKey, ledgerInitProps); | |||
| try { | |||
| // 连接数据库; | |||
| @@ -180,7 +178,7 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon | |||
| // 生成签名决定; | |||
| this.localDecision = makeDecision(currentId, initializer.getLedgerHash(), privKey); | |||
| this.decisions = new DecisionResultHandle[this.ledgerInitSetting.getConsensusParticipants().length]; | |||
| this.decisions = new DecisionResultHandle[this.ledgerInitConfig.getParticipantCount()]; | |||
| for (int i = 0; i < decisions.length; i++) { | |||
| // 参与者的 id 是依次递增的; | |||
| this.decisions[i] = new DecisionResultHandle(i); | |||
| @@ -191,7 +189,7 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon | |||
| } | |||
| private DigitalSignature getNodeSignatures() { | |||
| ParticipantNode parti = this.ledgerInitSetting.getConsensusParticipants()[currentId]; | |||
| ParticipantNode parti = this.ledgerInitConfig.getParticipant(currentId); | |||
| PubKey pubKey = parti.getPubKey(); | |||
| SignatureDigest signDigest = this.localPermission.getTransactionSignature(); | |||
| DigitalSignatureBlob digitalSignature = new DigitalSignatureBlob(pubKey, signDigest); | |||
| @@ -230,44 +228,24 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon | |||
| return defCryptoSetting; | |||
| } | |||
| public LedgerInitProposal prepareLocalProposal(int currentId, PrivKey privKey, LedgerInitProperties ledgerProps, | |||
| ConsensusSettings csSettings, CryptoSetting cryptoSetting) { | |||
| // 创建初始化配置; | |||
| LedgerInitData initSetting = new LedgerInitData(); | |||
| initSetting.setLedgerSeed(ledgerProps.getLedgerSeed()); | |||
| initSetting.setCryptoSetting(cryptoSetting); | |||
| List<ConsensusParticipantConfig> partiList = ledgerProps.getConsensusParticipants(); | |||
| ConsensusParticipantConfig[] parties = partiList.toArray(new ConsensusParticipantConfig[partiList.size()]); | |||
| ConsensusParticipantConfig[] orderedParties = sortAndVerify(parties); | |||
| initSetting.setConsensusParticipants(orderedParties); | |||
| // 创建默认的共识配置; | |||
| try { | |||
| byte[] csSettingBytes = new byte[1024]; | |||
| new Random().nextBytes(csSettingBytes); | |||
| initSetting.setConsensusProvider(consensusProvider.getName()); | |||
| initSetting.setConsensusSettings(new Bytes(csSettingBytes)); | |||
| } catch (Exception e) { | |||
| throw new LedgerInitException("Create default consensus config failed! --" + e.getMessage(), e); | |||
| } | |||
| public LedgerInitProposal prepareLocalProposal(int currentId, PrivKey privKey, | |||
| LedgerInitConfiguration ledgerInitConfig) { | |||
| if (currentId < 0 || currentId >= orderedParties.length) { | |||
| if (currentId < 0 || currentId >= ledgerInitConfig.getParticipantCount()) { | |||
| throw new LedgerInitException("Your id is out of bound of participant list!"); | |||
| } | |||
| this.currentId = currentId; | |||
| this.ledgerInitSetting = initSetting; | |||
| // 校验当前的公钥、私钥是否匹配; | |||
| byte[] testBytes = BytesUtils.toBytes(currentId); | |||
| SignatureDigest testSign = SIGN_FUNC.sign(privKey, testBytes); | |||
| PubKey myPubKey = orderedParties[currentId].getPubKey(); | |||
| PubKey myPubKey = ledgerInitConfig.getParticipant(currentId).getPubKey(); | |||
| if (!SIGN_FUNC.verify(testSign, myPubKey, testBytes)) { | |||
| throw new LedgerInitException("Your pub-key specified in the init-settings isn't match your priv-key!"); | |||
| } | |||
| // 初始化; | |||
| this.initializer = LedgerInitializer.create(ledgerInitSetting); | |||
| this.initializer = LedgerInitializer.create(ledgerInitConfig.getLedgerSettings(), | |||
| ledgerInitConfig.getSecuritySettings()); | |||
| // 对初始交易签名,生成当前参与者的账本初始化许可; | |||
| SignatureDigest permissionSign = SignatureUtils.sign(initializer.getTransactionContent(), privKey); | |||
| @@ -337,7 +315,7 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon | |||
| * @param parties | |||
| * @return | |||
| */ | |||
| private ConsensusParticipantConfig[] sortAndVerify(ConsensusParticipantConfig[] parties) { | |||
| private ParticipantProperties[] sortAndVerify(ParticipantProperties[] parties) { | |||
| Arrays.sort(parties, (o1, o2) -> o1.getId() - o2.getId()); | |||
| for (int i = 0; i < parties.length; i++) { | |||
| if (parties[i].getId() != i) { | |||
| @@ -76,6 +76,7 @@ import com.jd.blockchain.service.TransactionBatchResultHandle; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.transaction.BlockchainQueryService; | |||
| import com.jd.blockchain.transaction.TxBuilder; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| @@ -185,8 +186,11 @@ public class MockerNodeContext implements BlockchainQueryService { | |||
| MockerLedgerInitializer mockLedgerInitializer = new MockerLedgerInitializer(dbConnFactory, ledgerManager); | |||
| ledgerHash = mockLedgerInitializer.initialize(0, defaultKeypair.getPrivKey(), ledgerInitProperties, | |||
| dbConnectionConfig, new PresetAnswerPrompter("N"), cryptoConfig()); | |||
| LedgerInitConfiguration initConfig = LedgerInitConfiguration.create(ledgerInitProperties); | |||
| initConfig.getLedgerSettings().setCryptoSetting(cryptoConfig()); | |||
| ledgerHash = mockLedgerInitializer.initialize(0, defaultKeypair.getPrivKey(), initConfig, dbConnectionConfig, | |||
| new PresetAnswerPrompter("N")); | |||
| ledgerRepository = registerLedger(ledgerHash, dbConnectionConfig); | |||
| @@ -251,6 +251,14 @@ public abstract class PropertiesUtils { | |||
| String value = getRequiredProperty(props, key); | |||
| return Boolean.parseBoolean(value); | |||
| } | |||
| public static boolean getBooleanOptional(Properties props, String key, boolean defaultValue) { | |||
| String value = getProperty(props, key, false); | |||
| if (value == null) { | |||
| return defaultValue; | |||
| } | |||
| return Boolean.parseBoolean(value); | |||
| } | |||
| /** | |||
| * 返回指定的属性; <br> | |||
| @@ -267,6 +275,14 @@ public abstract class PropertiesUtils { | |||
| public static String getOptionalProperty(Properties props, String key) { | |||
| return getProperty(props, key, false); | |||
| } | |||
| public static String getOptionalProperty(Properties props, String key, String defaultValue) { | |||
| String value = getProperty(props, key, false); | |||
| if (value == null) { | |||
| return defaultValue; | |||
| } | |||
| return value; | |||
| } | |||
| /** | |||
| * 返回指定的属性; <br> | |||
| @@ -72,4 +72,8 @@ public class StringUtils { | |||
| } | |||
| return tokens.toArray(new String[tokens.size()]); | |||
| } | |||
| public static String trim(String str) { | |||
| return str == null ? "" : str.trim(); | |||
| } | |||
| } | |||