| @@ -596,28 +596,31 @@ JD区块链的核心对象包括: | |||
| // 合约地址 | |||
| String contractAddressBase58 = ""; | |||
| // Event | |||
| String event = ""; | |||
| // args(注意参数的格式) | |||
| byte[] args = "20##30##abc".getBytes(); | |||
| // 提交合约执行代码 | |||
| txTemp.contractEvents().send(contractAddressBase58, event, args); | |||
| // TX 准备就绪; | |||
| PreparedTransaction prepTx = txTemp.prepare(); | |||
| // 生成私钥并使用私钥进行签名; | |||
| CryptoKeyPair keyPair = getSponsorKey(); | |||
| prepTx.sign(keyPair); | |||
| // 提交交易; | |||
| TransactionResponse transactionResponse = prepTx.commit(); | |||
| assertTrue(transactionResponse.isSuccess()); | |||
| // 使用接口方式调用合约 | |||
| TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class); | |||
| // 使用decode方式调用合约内部方法(create方法) | |||
| // 返回GenericValueHolder可通过get方法获取结果,但get方法需要在commit调用后执行 | |||
| GenericValueHolder<String> result = ContractReturnValue.decode(transferContract.create(address, account, money)); | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| TransactionResponse transactionResponse = ptx.commit(); | |||
| String cotractExecResult = result.get(); | |||
| // TransactionResponse也提供了可供查询结果的接口 | |||
| OperationResult[] operationResults = transactionResponse.getOperationResults(); | |||
| // 通过OperationResult获取结果 | |||
| for (int i = 0; i < operationResults.length; i++) { | |||
| OperationResult opResult = operationResults[i]; | |||
| System.out.printf("Operation[%s].result = %s \r\n", | |||
| opResult.getIndex(), BytesValueEncoding.decode(opResult.getResult())); | |||
| } | |||
| ``` | |||
| @@ -1,35 +1,35 @@ | |||
| package com.jd.blockchain.consensus.bftsmart; | |||
| public class BftsmartCommitBlockConfig implements BftsmartCommitBlockSettings { | |||
| private int txSizePerBlock; | |||
| private long maxDelayMilliSecondsPerBlock; | |||
| public BftsmartCommitBlockConfig() { | |||
| } | |||
| public BftsmartCommitBlockConfig(int txSizePerBlock, long maxDelayMilliSecondsPerBlock) { | |||
| this.txSizePerBlock = txSizePerBlock; | |||
| this.maxDelayMilliSecondsPerBlock = maxDelayMilliSecondsPerBlock; | |||
| } | |||
| @Override | |||
| public int getTxSizePerBlock() { | |||
| return txSizePerBlock; | |||
| } | |||
| public void setTxSizePerBlock(int txSizePerBlock) { | |||
| this.txSizePerBlock = txSizePerBlock; | |||
| } | |||
| @Override | |||
| public long getMaxDelayMilliSecondsPerBlock() { | |||
| return maxDelayMilliSecondsPerBlock; | |||
| } | |||
| public void setMaxDelayMilliSecondsPerBlock(long maxDelayMilliSecondsPerBlock) { | |||
| this.maxDelayMilliSecondsPerBlock = maxDelayMilliSecondsPerBlock; | |||
| } | |||
| } | |||
| //package com.jd.blockchain.consensus.bftsmart; | |||
| // | |||
| //public class BftsmartCommitBlockConfig implements BftsmartCommitBlockSettings { | |||
| // | |||
| // private int txSizePerBlock; | |||
| // | |||
| // private long maxDelayMilliSecondsPerBlock; | |||
| // | |||
| // | |||
| // public BftsmartCommitBlockConfig() { | |||
| // | |||
| // } | |||
| // | |||
| // public BftsmartCommitBlockConfig(int txSizePerBlock, long maxDelayMilliSecondsPerBlock) { | |||
| // this.txSizePerBlock = txSizePerBlock; | |||
| // this.maxDelayMilliSecondsPerBlock = maxDelayMilliSecondsPerBlock; | |||
| // } | |||
| // @Override | |||
| // public int getTxSizePerBlock() { | |||
| // return txSizePerBlock; | |||
| // } | |||
| // | |||
| // public void setTxSizePerBlock(int txSizePerBlock) { | |||
| // this.txSizePerBlock = txSizePerBlock; | |||
| // } | |||
| // | |||
| // @Override | |||
| // public long getMaxDelayMilliSecondsPerBlock() { | |||
| // return maxDelayMilliSecondsPerBlock; | |||
| // } | |||
| // | |||
| // public void setMaxDelayMilliSecondsPerBlock(long maxDelayMilliSecondsPerBlock) { | |||
| // this.maxDelayMilliSecondsPerBlock = maxDelayMilliSecondsPerBlock; | |||
| // } | |||
| //} | |||
| @@ -1,17 +1,17 @@ | |||
| package com.jd.blockchain.consensus.bftsmart; | |||
| import com.jd.blockchain.binaryproto.DataContract; | |||
| import com.jd.blockchain.binaryproto.DataField; | |||
| import com.jd.blockchain.binaryproto.PrimitiveType; | |||
| import com.jd.blockchain.consts.DataCodes; | |||
| @DataContract(code = DataCodes.CONSENSUS_BFTSMART_BLOCK_SETTINGS) | |||
| public interface BftsmartCommitBlockSettings { | |||
| @DataField(order = 0, primitiveType = PrimitiveType.INT32) | |||
| int getTxSizePerBlock(); | |||
| @DataField(order = 1, primitiveType = PrimitiveType.INT64) | |||
| long getMaxDelayMilliSecondsPerBlock(); | |||
| } | |||
| //package com.jd.blockchain.consensus.bftsmart; | |||
| // | |||
| //import com.jd.blockchain.binaryproto.DataContract; | |||
| //import com.jd.blockchain.binaryproto.DataField; | |||
| //import com.jd.blockchain.binaryproto.PrimitiveType; | |||
| //import com.jd.blockchain.consts.DataCodes; | |||
| // | |||
| // | |||
| //@DataContract(code = DataCodes.CONSENSUS_BFTSMART_BLOCK_SETTINGS) | |||
| //public interface BftsmartCommitBlockSettings { | |||
| // | |||
| // @DataField(order = 0, primitiveType = PrimitiveType.INT32) | |||
| // int getTxSizePerBlock(); | |||
| // | |||
| // @DataField(order = 1, primitiveType = PrimitiveType.INT64) | |||
| // long getMaxDelayMilliSecondsPerBlock(); | |||
| //} | |||
| @@ -9,7 +9,7 @@ public class BftsmartConsensusConfig implements BftsmartConsensusSettings { | |||
| private BftsmartNodeSettings[] nodes; | |||
| private BftsmartCommitBlockSettings commitBlockSettings; | |||
| // private BftsmartCommitBlockSettings commitBlockSettings; | |||
| static { | |||
| DataContractRegistry.register(BftsmartConsensusSettings.class); | |||
| @@ -24,9 +24,11 @@ public class BftsmartConsensusConfig implements BftsmartConsensusSettings { | |||
| * @param bftsmartSystemConfigs | |||
| * bftsmart系统配置; | |||
| */ | |||
| public BftsmartConsensusConfig(BftsmartNodeSettings[] nodes, BftsmartCommitBlockSettings commitBlockSettings, Property[] bftsmartSystemConfigs) { | |||
| public BftsmartConsensusConfig(BftsmartNodeSettings[] nodes, | |||
| // BftsmartCommitBlockSettings commitBlockSettings, | |||
| Property[] bftsmartSystemConfigs) { | |||
| this.nodes = nodes; | |||
| this.commitBlockSettings = commitBlockSettings; | |||
| // this.commitBlockSettings = commitBlockSettings; | |||
| this.bftsmartSystemConfig = bftsmartSystemConfigs; | |||
| } | |||
| @@ -40,13 +42,13 @@ public class BftsmartConsensusConfig implements BftsmartConsensusSettings { | |||
| return bftsmartSystemConfig; | |||
| } | |||
| @Override | |||
| public BftsmartCommitBlockSettings getCommitBlockSettings() { | |||
| return commitBlockSettings; | |||
| } | |||
| public void setCommitBlockSettings(BftsmartCommitBlockSettings commitBlockSettings) { | |||
| this.commitBlockSettings = commitBlockSettings; | |||
| } | |||
| // @Override | |||
| // public BftsmartCommitBlockSettings getCommitBlockSettings() { | |||
| // return commitBlockSettings; | |||
| // } | |||
| // | |||
| // | |||
| // public void setCommitBlockSettings(BftsmartCommitBlockSettings commitBlockSettings) { | |||
| // this.commitBlockSettings = commitBlockSettings; | |||
| // } | |||
| } | |||
| @@ -14,7 +14,7 @@ public interface BftsmartConsensusSettings extends ConsensusSettings { | |||
| @DataField(order = 1, primitiveType = PrimitiveType.BYTES, list=true) | |||
| Property[] getSystemConfigs(); | |||
| @DataField(order = 2, refContract = true) | |||
| BftsmartCommitBlockSettings getCommitBlockSettings(); | |||
| // @DataField(order = 2, refContract = true) | |||
| // BftsmartCommitBlockSettings getCommitBlockSettings(); | |||
| } | |||
| @@ -4,6 +4,7 @@ import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
| import com.jd.blockchain.utils.PropertiesUtils; | |||
| import com.jd.blockchain.utils.codec.Base58Utils; | |||
| @@ -24,6 +25,8 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| private static final String CONFIG_TEMPLATE_FILE = "bftsmart.config"; | |||
| private static final String CONFIG_LEDGER_INIT = "ledger.init"; | |||
| /** | |||
| * 参数键:节点数量; | |||
| */ | |||
| @@ -61,6 +64,8 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| */ | |||
| public static final String CONSENSUS_SECURE_PATTERN = "system.server.%s.network.secure"; | |||
| private static Properties CONFIG_TEMPLATE; | |||
| static { | |||
| ClassPathResource configResource = new ClassPathResource(CONFIG_TEMPLATE_FILE); | |||
| @@ -74,31 +79,31 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| } | |||
| //解析得到结块的相关配置信息 | |||
| public BftsmartCommitBlockConfig createBlockConfig(Properties resolvingProps) { | |||
| BftsmartCommitBlockConfig blockConfig = new BftsmartCommitBlockConfig(); | |||
| String txSizeString = PropertiesUtils.getRequiredProperty(resolvingProps, BFTSMART_BLOCK_TXSIZE_KEY); | |||
| resolvingProps.remove(BFTSMART_BLOCK_TXSIZE_KEY); | |||
| if (txSizeString == null || txSizeString.length() == 0) { | |||
| blockConfig.setTxSizePerBlock(DEFAULT_TXSIZE); | |||
| } | |||
| else { | |||
| blockConfig.setTxSizePerBlock(Integer.parseInt(txSizeString)); | |||
| } | |||
| String maxDelayString = PropertiesUtils.getRequiredProperty(resolvingProps, BFTSMART_BLOCK_MAXDELAY_KEY); | |||
| resolvingProps.remove(BFTSMART_BLOCK_MAXDELAY_KEY); | |||
| if (maxDelayString == null || maxDelayString.length() == 0) { | |||
| blockConfig.setMaxDelayMilliSecondsPerBlock(DEFAULT_MAXDELAY); | |||
| } | |||
| else { | |||
| blockConfig.setMaxDelayMilliSecondsPerBlock(Long.parseLong(maxDelayString)); | |||
| } | |||
| return blockConfig; | |||
| } | |||
| // public BftsmartCommitBlockConfig createBlockConfig(Properties resolvingProps) { | |||
| // BftsmartCommitBlockConfig blockConfig = new BftsmartCommitBlockConfig(); | |||
| // | |||
| // String txSizeString = PropertiesUtils.getRequiredProperty(resolvingProps, BFTSMART_BLOCK_TXSIZE_KEY); | |||
| // resolvingProps.remove(BFTSMART_BLOCK_TXSIZE_KEY); | |||
| // | |||
| // if (txSizeString == null || txSizeString.length() == 0) { | |||
| // blockConfig.setTxSizePerBlock(DEFAULT_TXSIZE); | |||
| // } | |||
| // else { | |||
| // blockConfig.setTxSizePerBlock(Integer.parseInt(txSizeString)); | |||
| // } | |||
| // | |||
| // String maxDelayString = PropertiesUtils.getRequiredProperty(resolvingProps, BFTSMART_BLOCK_MAXDELAY_KEY); | |||
| // resolvingProps.remove(BFTSMART_BLOCK_MAXDELAY_KEY); | |||
| // | |||
| // if (maxDelayString == null || maxDelayString.length() == 0) { | |||
| // blockConfig.setMaxDelayMilliSecondsPerBlock(DEFAULT_MAXDELAY); | |||
| // } | |||
| // else { | |||
| // blockConfig.setMaxDelayMilliSecondsPerBlock(Long.parseLong(maxDelayString)); | |||
| // } | |||
| // | |||
| // return blockConfig; | |||
| // } | |||
| @Override | |||
| public Properties createPropertiesTemplate() { | |||
| @@ -106,7 +111,7 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| } | |||
| @Override | |||
| public BftsmartConsensusSettings createSettings(Properties props) { | |||
| public BftsmartConsensusSettings createSettings(Properties props, ParticipantNode[] participantNodes) { | |||
| Properties resolvingProps = PropertiesUtils.cloneFrom(props); | |||
| int serversNum = PropertiesUtils.getInt(resolvingProps, SERVER_NUM_KEY); | |||
| if (serversNum < 0) { | |||
| @@ -115,18 +120,26 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| if (serversNum < 4) { | |||
| throw new IllegalArgumentException(String.format("Property[%s] is less than 4!", SERVER_NUM_KEY)); | |||
| } | |||
| if (participantNodes == null) { | |||
| throw new IllegalArgumentException("ParticipantNodes is Empty !!!"); | |||
| } | |||
| if (serversNum != participantNodes.length) { | |||
| throw new IllegalArgumentException(String.format("Property[%s] which is [%s] unequal " + | |||
| "ParticipantNodes's length which is [%s] !", SERVER_NUM_KEY, serversNum, participantNodes.length)); | |||
| } | |||
| BftsmartCommitBlockConfig blockConfig = createBlockConfig(resolvingProps); | |||
| // BftsmartCommitBlockConfig blockConfig = createBlockConfig(resolvingProps); | |||
| BftsmartNodeSettings[] nodesSettings = new BftsmartNodeSettings[serversNum]; | |||
| for (int i = 0; i < serversNum; i++) { | |||
| int id = i; | |||
| String keyOfPubkey = keyOfNode(PUBKEY_PATTERN, id); | |||
| String base58PubKey = PropertiesUtils.getRequiredProperty(resolvingProps, keyOfPubkey); | |||
| // String keyOfPubkey = keyOfNode(PUBKEY_PATTERN, id); | |||
| // String base58PubKey = PropertiesUtils.getRequiredProperty(resolvingProps, keyOfPubkey); | |||
| // PubKey pubKey = new PubKey(Base58Utils.decode(base58PubKey)); | |||
| PubKey pubKey = KeyGenCommand.decodePubKey(base58PubKey); | |||
| resolvingProps.remove(keyOfPubkey); | |||
| // PubKey pubKey = KeyGenCommand.decodePubKey(base58PubKey); | |||
| PubKey pubKey = participantNodes[i].getPubKey(); | |||
| // resolvingProps.remove(keyOfPubkey); | |||
| String keyOfHost = keyOfNode(CONSENSUS_HOST_PATTERN, id); | |||
| String networkAddressHost = PropertiesUtils.getRequiredProperty(resolvingProps, keyOfHost); | |||
| @@ -145,7 +158,8 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| nodesSettings[i] = nodeConfig; | |||
| } | |||
| BftsmartConsensusConfig config = new BftsmartConsensusConfig(nodesSettings, blockConfig, | |||
| BftsmartConsensusConfig config = new BftsmartConsensusConfig(nodesSettings, | |||
| // blockConfig, | |||
| PropertiesUtils.getOrderedValues(resolvingProps)); | |||
| return config; | |||
| } | |||
| @@ -160,8 +174,8 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| if (serversNum > 0) { | |||
| for (int i = 0; i < serversNum; i++) { | |||
| int id = i; | |||
| String keyOfPubkey = keyOfNode(PUBKEY_PATTERN, id); | |||
| props.remove(keyOfPubkey); | |||
| // String keyOfPubkey = keyOfNode(PUBKEY_PATTERN, id); | |||
| // props.remove(keyOfPubkey); | |||
| String keyOfHost = keyOfNode(CONSENSUS_HOST_PATTERN, id); | |||
| props.remove(keyOfHost); | |||
| @@ -180,22 +194,22 @@ public class BftsmartConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| props.setProperty(SERVER_NUM_KEY, serversNum + ""); | |||
| //获得结块相关的属性信息 | |||
| BftsmartCommitBlockSettings blockSettings = bftsmartSettings.getCommitBlockSettings(); | |||
| if (blockSettings == null) { | |||
| props.setProperty(BFTSMART_BLOCK_TXSIZE_KEY, DEFAULT_TXSIZE + ""); | |||
| props.setProperty(BFTSMART_BLOCK_MAXDELAY_KEY, DEFAULT_MAXDELAY + ""); | |||
| } else { | |||
| int txSize = blockSettings.getTxSizePerBlock(); | |||
| long maxDelay = blockSettings.getMaxDelayMilliSecondsPerBlock(); | |||
| props.setProperty(BFTSMART_BLOCK_TXSIZE_KEY, txSize + ""); | |||
| props.setProperty(BFTSMART_BLOCK_MAXDELAY_KEY, maxDelay + ""); | |||
| } | |||
| // BftsmartCommitBlockSettings blockSettings = bftsmartSettings.getCommitBlockSettings(); | |||
| // if (blockSettings == null) { | |||
| // props.setProperty(BFTSMART_BLOCK_TXSIZE_KEY, DEFAULT_TXSIZE + ""); | |||
| // props.setProperty(BFTSMART_BLOCK_MAXDELAY_KEY, DEFAULT_MAXDELAY + ""); | |||
| // } else { | |||
| // int txSize = blockSettings.getTxSizePerBlock(); | |||
| // long maxDelay = blockSettings.getMaxDelayMilliSecondsPerBlock(); | |||
| // props.setProperty(BFTSMART_BLOCK_TXSIZE_KEY, txSize + ""); | |||
| // props.setProperty(BFTSMART_BLOCK_MAXDELAY_KEY, maxDelay + ""); | |||
| // } | |||
| for (int i = 0; i < serversNum; i++) { | |||
| BftsmartNodeSettings ns = nodesSettings[i]; | |||
| int id = i; | |||
| String keyOfPubkey = keyOfNode(PUBKEY_PATTERN, id); | |||
| props.setProperty(keyOfPubkey, ns.getPubKey().toBase58()); | |||
| // String keyOfPubkey = keyOfNode(PUBKEY_PATTERN, id); | |||
| // props.setProperty(keyOfPubkey, ns.getPubKey().toBase58()); | |||
| String keyOfHost = keyOfNode(CONSENSUS_HOST_PATTERN, id); | |||
| props.setProperty(keyOfHost, ns.getNetworkAddress() == null ? "" : ns.getNetworkAddress().getHost()); | |||
| @@ -34,26 +34,28 @@ public class BftsmartConsensusManageService implements ConsensusManageService { | |||
| @Override | |||
| public BftsmartClientIncomingSettings authClientIncoming(ClientIdentification authId) { | |||
| if (verify(authId)) { | |||
| BftsmartClientIncomingSettings clientIncomingSettings = new BftsmartClientIncomingConfig(); | |||
| BftsmartClientIncomingConfig clientIncomingSettings = new BftsmartClientIncomingConfig(); | |||
| ((BftsmartClientIncomingConfig) clientIncomingSettings) | |||
| clientIncomingSettings | |||
| .setTopology(BinarySerializeUtils.serialize(nodeServer.getTopology())); | |||
| ((BftsmartClientIncomingConfig) clientIncomingSettings) | |||
| clientIncomingSettings | |||
| .setTomConfig(BinarySerializeUtils.serialize(nodeServer.getTomConfig())); | |||
| ((BftsmartClientIncomingConfig) clientIncomingSettings) | |||
| clientIncomingSettings | |||
| .setConsensusSettings(nodeServer.getConsensusSetting()); | |||
| ((BftsmartClientIncomingConfig) clientIncomingSettings).setPubKey(authId.getPubKey()); | |||
| clientIncomingSettings.setPubKey(authId.getPubKey()); | |||
| // compute gateway id | |||
| authLock.lock(); | |||
| try { | |||
| authLock.lock(); | |||
| ((BftsmartClientIncomingConfig) clientIncomingSettings).setClientId(clientId++); | |||
| clientIncomingSettings.setClientId(clientId++); | |||
| clientId += CLIENT_SIZE_PER_GATEWAY; | |||
| } finally { | |||
| authLock.unlock(); | |||
| } | |||
| return clientIncomingSettings; | |||
| } | |||
| return null; | |||
| @@ -107,7 +107,7 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer | |||
| setting = ((BftsmartServerSettings) serverSettings).getConsensusSettings(); | |||
| List<HostsConfig.Config> configList = new ArrayList<HostsConfig.Config>(); | |||
| List<HostsConfig.Config> configList = new ArrayList<>(); | |||
| NodeSettings[] nodeSettingsArray = setting.getNodes(); | |||
| for (NodeSettings nodeSettings : nodeSettingsArray) { | |||
| @@ -1,10 +1,7 @@ | |||
| package com.jd.blockchain.consensus.bftsmart.service; | |||
| import com.jd.blockchain.consensus.NodeSettings; | |||
| import com.jd.blockchain.consensus.bftsmart.BftsmartCommitBlockSettings; | |||
| import com.jd.blockchain.consensus.bftsmart.BftsmartConsensusSettings; | |||
| import com.jd.blockchain.consensus.bftsmart.BftsmartNodeSettings; | |||
| import com.jd.blockchain.consensus.service.ServerSettings; | |||
| public class BftsmartServerSettingConfig implements BftsmartServerSettings { | |||
| private NodeSettings replicaSettings; | |||
| @@ -1,6 +1,5 @@ | |||
| package com.jd.blockchain.consensus.bftsmart.service; | |||
| import com.jd.blockchain.consensus.bftsmart.BftsmartCommitBlockSettings; | |||
| import com.jd.blockchain.consensus.bftsmart.BftsmartConsensusSettings; | |||
| import com.jd.blockchain.consensus.service.ServerSettings; | |||
| @@ -26,7 +26,7 @@ import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.ExecutorService; | |||
| import java.util.concurrent.Executors; | |||
| public class proxyClientTest { | |||
| public class ProxyClientTest { | |||
| int number = 1500000; | |||
| @@ -69,13 +69,14 @@ public class proxyClientTest { | |||
| nodesSettings[i] = (BftsmartNodeSettings) node; | |||
| } | |||
| BftsmartConsensusConfig consensusConfig = new BftsmartConsensusConfig(nodesSettings, null, | |||
| BftsmartConsensusConfig consensusConfig = new BftsmartConsensusConfig(nodesSettings, | |||
| // null, | |||
| PropertiesUtils.getOrderedValues(bftsmartConf)); | |||
| for (int j = 0; j < nodeNum; j++) { | |||
| ServerSettings serverSettings = new BftsmartServerSettingConfig(); | |||
| ((BftsmartServerSettingConfig) serverSettings).setReplicaSettings(nodesSettings[j]); | |||
| ((BftsmartServerSettingConfig) serverSettings).setConsensusSettings(consensusConfig); | |||
| BftsmartServerSettingConfig serverSettings = new BftsmartServerSettingConfig(); | |||
| serverSettings.setReplicaSettings(nodesSettings[j]); | |||
| serverSettings.setConsensusSettings(consensusConfig); | |||
| BftsmartNodeServer server = new BftsmartNodeServer(serverSettings, null, null); | |||
| nodeServers[j] = server; | |||
| nodeStartPools.execute(() -> { | |||
| @@ -25,5 +25,10 @@ | |||
| <artifactId>utils-common</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>ledger-model</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| </dependencies> | |||
| </project> | |||
| @@ -1,5 +1,7 @@ | |||
| package com.jd.blockchain.consensus; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import java.util.Properties; | |||
| public interface ConsensusSettingsBuilder { | |||
| @@ -9,13 +11,11 @@ public interface ConsensusSettingsBuilder { | |||
| * | |||
| * @param props | |||
| * 属性表; | |||
| * @param keyPrefix | |||
| * 属性的key 的前缀;<br> | |||
| * 在解析过程中,以具体协议实现的标准参数的key 加入此前缀后从属性表中检索参数值;<br> | |||
| * 如果指定为 null 或者空白,则忽略此参数; | |||
| * @param participantNodes | |||
| * 参与方列表;<br> | |||
| * @return | |||
| */ | |||
| ConsensusSettings createSettings(Properties props); | |||
| ConsensusSettings createSettings(Properties props, ParticipantNode[] participantNodes); | |||
| Properties createPropertiesTemplate(); | |||
| @@ -21,6 +21,7 @@ import com.jd.blockchain.consensus.mq.settings.MsgQueueNetworkSettings; | |||
| import com.jd.blockchain.consensus.mq.settings.MsgQueueNodeSettings; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.PropertiesUtils; | |||
| @@ -97,7 +98,7 @@ public class MsgQueueConsensusSettingsBuilder implements ConsensusSettingsBuilde | |||
| } | |||
| @Override | |||
| public MsgQueueConsensusSettings createSettings(Properties props) { | |||
| public MsgQueueConsensusSettings createSettings(Properties props, ParticipantNode[] participantNodes) { | |||
| MsgQueueNetworkConfig networkConfig = new MsgQueueNetworkConfig(); | |||
| Properties resolvingProps = PropertiesUtils.cloneFrom(props); | |||
| @@ -68,7 +68,7 @@ public class JavaContractCode extends AbstractContractCode { | |||
| @Override | |||
| public BytesValue processEvent(ContractEventContext eventContext) { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("Start processing event[%s] of contract[%s]...", eventContext.getEvent(), address.toString()); | |||
| LOGGER.debug("Start processing event{} of contract{}...", eventContext.getEvent(), address.toString()); | |||
| } | |||
| try { | |||
| return codeModule.call(new ContractExecution(eventContext)); | |||
| @@ -78,7 +78,7 @@ public class JavaContractCode extends AbstractContractCode { | |||
| throw ex; | |||
| } finally { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("End processing event[%s] of contract[%s]. ", eventContext.getEvent(), address.toString()); | |||
| LOGGER.debug("End processing event{} of contract{}. ", eventContext.getEvent(), address.toString()); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| #网关的HTTP服务地址; | |||
| #网关的HTTP服务地址,建议直接使用0.0.0.0; | |||
| http.host=0.0.0.0 | |||
| #网关的HTTP服务端口; | |||
| http.port=8081 | |||
| @@ -18,6 +18,7 @@ peer.providers=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| #数据检索服务对应URL,格式:http://{ip}:{port},例如:http://127.0.0.1:10001 | |||
| #若该值不配置或配置不正确,则浏览器模糊查询部分无法正常显示 | |||
| #数据检索服务模块(Argus)需单独部署,若不部署其他功能仍可正常使用 | |||
| data.retrieval.url=http://127.0.0.1:10001 | |||
| #默认公钥的内容(Base58编码数据); | |||
| @@ -13,22 +13,10 @@ | |||
| # See the License for the specific language governing permissions and | |||
| # limitations under the License. | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: transaction count ###### | |||
| ############################################ | |||
| system.block.txsize=15 | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: delay time ###### | |||
| ############################################ | |||
| system.block.maxdelay=500 | |||
| ############################################ | |||
| ###### #Consensus Participant0 ###### | |||
| ############################################ | |||
| system.server.0.pubkey= | |||
| system.server.0.network.host=127.0.0.1 | |||
| system.server.0.network.port=16000 | |||
| system.server.0.network.secure=false | |||
| @@ -37,7 +25,6 @@ system.server.0.network.secure=false | |||
| ###### #Consensus Participant1 ###### | |||
| ############################################ | |||
| system.server.1.pubkey= | |||
| system.server.1.network.host=127.0.0.1 | |||
| system.server.1.network.port=16010 | |||
| system.server.1.network.secure=false | |||
| @@ -46,7 +33,6 @@ system.server.1.network.secure=false | |||
| ###### #Consensus Participant2 ###### | |||
| ############################################ | |||
| system.server.2.pubkey= | |||
| system.server.2.network.host=127.0.0.1 | |||
| system.server.2.network.port=16020 | |||
| system.server.2.network.secure=false | |||
| @@ -55,7 +41,6 @@ system.server.2.network.secure=false | |||
| ###### #Consensus Participant3 ###### | |||
| ############################################ | |||
| system.server.3.pubkey= | |||
| system.server.3.network.host=127.0.0.1 | |||
| system.server.3.network.port=16030 | |||
| system.server.3.network.secure=false | |||
| @@ -1,16 +1,17 @@ | |||
| #账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
| ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| ledger.name= | |||
| #声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区 | |||
| created-time=2019-08-01 14:26:58.069+0800 | |||
| #共识服务提供者;必须; | |||
| consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| #共识服务的参数配置;必须; | |||
| consensus.conf=classpath:bftsmart.config | |||
| #共识服务的参数配置;推荐使用绝对路径;必须; | |||
| consensus.conf=bftsmart.config | |||
| #密码服务提供者列表,以英文逗点“,”分隔;必须; | |||
| crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ | |||
| @@ -21,36 +22,24 @@ com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
| cons_parti.count=4 | |||
| #第0个参与方的名称; | |||
| cons_parti.0.name=jd.com | |||
| cons_parti.0.name= | |||
| #第0个参与方的公钥文件路径; | |||
| cons_parti.0.pubkey-path=keys/jd-com.pub | |||
| cons_parti.0.pubkey-path= | |||
| #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
| #第0个参与方的共识服务的主机地址; | |||
| cons_parti.0.consensus.host=127.0.0.1 | |||
| #第0个参与方的共识服务的端口; | |||
| cons_parti.0.consensus.port=8900 | |||
| #第0个参与方的共识服务是否开启安全连接; | |||
| cons_parti.0.consensus.secure=true | |||
| cons_parti.0.pubkey= | |||
| #第0个参与方的账本初始服务的主机; | |||
| cons_parti.0.initializer.host=127.0.0.1 | |||
| #第0个参与方的账本初始服务的端口; | |||
| cons_parti.0.initializer.port=8800 | |||
| #第0个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.0.initializer.secure=true | |||
| cons_parti.0.initializer.secure=false | |||
| #第1个参与方的名称; | |||
| cons_parti.1.name=at.com | |||
| cons_parti.1.name= | |||
| #第1个参与方的公钥文件路径; | |||
| cons_parti.1.pubkey-path=keys/at-com.pub | |||
| cons_parti.1.pubkey-path= | |||
| #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
| #第1个参与方的共识服务的主机地址; | |||
| cons_parti.1.consensus.host=127.0.0.1 | |||
| #第1个参与方的共识服务的端口; | |||
| cons_parti.1.consensus.port=8910 | |||
| #第1个参与方的共识服务是否开启安全连接; | |||
| cons_parti.1.consensus.secure=false | |||
| cons_parti.1.pubkey= | |||
| #第1个参与方的账本初始服务的主机; | |||
| cons_parti.1.initializer.host=127.0.0.1 | |||
| #第1个参与方的账本初始服务的端口; | |||
| @@ -59,36 +48,24 @@ cons_parti.1.initializer.port=8810 | |||
| cons_parti.1.initializer.secure=false | |||
| #第2个参与方的名称; | |||
| cons_parti.2.name=bt.com | |||
| cons_parti.2.name= | |||
| #第2个参与方的公钥文件路径; | |||
| cons_parti.2.pubkey-path=classpath:keys/parti2.pub | |||
| cons_parti.2.pubkey-path= | |||
| #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.2.pubkey= | |||
| #第2个参与方的共识服务的主机地址; | |||
| cons_parti.2.consensus.host=127.0.0.1 | |||
| #第2个参与方的共识服务的端口; | |||
| cons_parti.2.consensus.port=8920 | |||
| #第2个参与方的共识服务是否开启安全连接; | |||
| cons_parti.2.consensus.secure=false | |||
| #第2个参与方的账本初始服务的主机; | |||
| cons_parti.2.initializer.host=127.0.0.1 | |||
| #第2个参与方的账本初始服务的端口; | |||
| cons_parti.2.initializer.port=8820 | |||
| #第2个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.2.initializer.secure=true | |||
| cons_parti.2.initializer.secure=false | |||
| #第3个参与方的名称; | |||
| cons_parti.3.name=xt.com | |||
| cons_parti.3.name= | |||
| #第3个参与方的公钥文件路径; | |||
| cons_parti.3.pubkey-path=keys/xt-com.pub | |||
| cons_parti.3.pubkey-path= | |||
| #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
| #第3个参与方的共识服务的主机地址; | |||
| cons_parti.3.consensus.host=127.0.0.1 | |||
| #第3个参与方的共识服务的端口; | |||
| cons_parti.3.consensus.port=8930 | |||
| #第3个参与方的共识服务是否开启安全连接; | |||
| cons_parti.3.consensus.secure=false | |||
| cons_parti.3.pubkey= | |||
| #第3个参与方的账本初始服务的主机; | |||
| cons_parti.3.initializer.host=127.0.0.1 | |||
| #第3个参与方的账本初始服务的端口; | |||
| @@ -1,4 +1,4 @@ | |||
| #当前参与方的 id | |||
| #当前参与方的 id,与ledger.init文件中cons_parti.id一致,默认从0开始 | |||
| local.parti.id=0 | |||
| #当前参与方的公钥 | |||
| @@ -20,5 +20,4 @@ ledger.binding.out=../ | |||
| ledger.db.uri= | |||
| #账本数据库的连接口令 | |||
| ledger.db.pwd= | |||
| ledger.db.pwd= | |||
| @@ -1,66 +0,0 @@ | |||
| #账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
| ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| #ledger.name= | |||
| #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
| cons_parti.count=4 | |||
| #第0个参与方的名称 | |||
| cons_parti.0.name=xx-0.com | |||
| #第0个参与方的公钥文件路径 | |||
| cons_parti.0.pubkey-path= | |||
| #第0个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
| cons_parti.0.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
| #第0个参与方的账本初始服务的主机 | |||
| cons_parti.0.initializer.host=127.0.0.1 | |||
| #第0个参与方的账本初始服务的端口 | |||
| cons_parti.0.initializer.port=17000 | |||
| #第0个参与方的账本初始服务是否开启安全连接 | |||
| cons_parti.0.initializer.secure=false | |||
| #第1个参与方的名称 | |||
| cons_parti.1.name=xx-1.com | |||
| #第1个参与方的公钥文件路径 | |||
| cons_parti.1.pubkey-path= | |||
| #第1个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
| cons_parti.1.pubkey=endPsK36sC5JdPCDPDAXUwZtS3sxEmqEhFcC4whayAsTTh8Z6eoZ | |||
| #第1个参与方的账本初始服务的主机 | |||
| cons_parti.1.initializer.host=127.0.0.1 | |||
| #第1个参与方的账本初始服务的端口 | |||
| cons_parti.1.initializer.port=17010 | |||
| #第1个参与方的账本初始服务是否开启安全连接 | |||
| cons_parti.1.initializer.secure=false | |||
| #第2个参与方的名称 | |||
| cons_parti.2.name=xx-2.com | |||
| #第2个参与方的公钥文件路径 | |||
| cons_parti.2.pubkey-path= | |||
| #第2个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
| cons_parti.2.pubkey=endPsK36jEG281HMHeh6oSqzqLkT95DTnCM6REDURjdb2c67uR3R | |||
| #第2个参与方的账本初始服务的主机 | |||
| cons_parti.2.initializer.host=127.0.0.1 | |||
| #第2个参与方的账本初始服务的端口 | |||
| cons_parti.2.initializer.port=17020 | |||
| #第2个参与方的账本初始服务是否开启安全连接 | |||
| cons_parti.2.initializer.secure=false | |||
| #第3个参与方的名称 | |||
| cons_parti.3.name=xx-3.com | |||
| #第3个参与方的公钥文件路径 | |||
| cons_parti.3.pubkey-path= | |||
| #第3个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
| cons_parti.3.pubkey=endPsK36nse1dck4uF19zPvAMijCV336Y3zWdgb4rQG8QoRj5ktR | |||
| #第3个参与方的账本初始服务的主机 | |||
| cons_parti.3.initializer.host=127.0.0.1 | |||
| #第3个参与方的账本初始服务的端口 | |||
| cons_parti.3.initializer.port=17030 | |||
| #第3个参与方的账本初始服务是否开启安全连接 | |||
| cons_parti.3.initializer.secure=false | |||
| @@ -0,0 +1,74 @@ | |||
| #账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
| ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| ledger.name= | |||
| #声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区 | |||
| created-time=2019-08-01 14:26:58.069+0800 | |||
| #共识服务提供者;必须; | |||
| consensus.service-provider=com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider | |||
| #共识服务的参数配置;必须; | |||
| consensus.conf=mq.config | |||
| #密码服务提供者列表,以英文逗点“,”分隔;必须; | |||
| crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ | |||
| com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
| #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
| cons_parti.count=4 | |||
| #第0个参与方的名称; | |||
| cons_parti.0.name=jd.com | |||
| #第0个参与方的公钥文件路径; | |||
| cons_parti.0.pubkey-path=keys/jd-com.pub | |||
| #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
| #第0个参与方的账本初始服务的主机; | |||
| cons_parti.0.initializer.host=127.0.0.1 | |||
| #第0个参与方的账本初始服务的端口; | |||
| cons_parti.0.initializer.port=8800 | |||
| #第0个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.0.initializer.secure=false | |||
| #第1个参与方的名称; | |||
| cons_parti.1.name=at.com | |||
| #第1个参与方的公钥文件路径; | |||
| cons_parti.1.pubkey-path=keys/at-com.pub | |||
| #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
| #第1个参与方的账本初始服务的主机; | |||
| cons_parti.1.initializer.host=127.0.0.1 | |||
| #第1个参与方的账本初始服务的端口; | |||
| cons_parti.1.initializer.port=8810 | |||
| #第1个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.1.initializer.secure=false | |||
| #第2个参与方的名称; | |||
| cons_parti.2.name=bt.com | |||
| #第2个参与方的公钥文件路径; | |||
| cons_parti.2.pubkey-path=classpath:keys/parti2.pub | |||
| #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.2.pubkey= | |||
| #第2个参与方的账本初始服务的主机; | |||
| cons_parti.2.initializer.host=127.0.0.1 | |||
| #第2个参与方的账本初始服务的端口; | |||
| cons_parti.2.initializer.port=8820 | |||
| #第2个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.2.initializer.secure=false | |||
| #第3个参与方的名称; | |||
| cons_parti.3.name=xt.com | |||
| #第3个参与方的公钥文件路径; | |||
| cons_parti.3.pubkey-path=keys/xt-com.pub | |||
| #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
| #第3个参与方的账本初始服务的主机; | |||
| cons_parti.3.initializer.host=127.0.0.1 | |||
| #第3个参与方的账本初始服务的端口; | |||
| cons_parti.3.initializer.port=8830 | |||
| #第3个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.3.initializer.secure=false | |||
| @@ -2,31 +2,22 @@ | |||
| local.parti.id=0 | |||
| #当前参与方的公钥 | |||
| local.parti.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
| local.parti.pubkey= | |||
| #当前参与方的私钥(密文编码) | |||
| local.parti.privkey=177gjsj5PHeCpbAtJE7qnbmhuZMHAEKuMsd45zHkv8F8AWBvTBbff8yRKdCyT3kwrmAjSnY | |||
| local.parti.privkey= | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入 | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| local.parti.pwd= | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录 | |||
| #推荐使用绝对路径,相对路径以当前文件(local.conf)所在目录为基准 | |||
| ledger.binding.out=../ | |||
| #账本数据库的连接字符 | |||
| #rocksdb数据库连接格式:rocksdb://{path} | |||
| #redis数据库连接格式:redis://{ip}:{prot}/{db} | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #rocksdb数据库连接格式:rocksdb://{path},例如:rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #redis数据库连接格式:redis://{ip}:{prot}/{db},例如:redis://127.0.0.1:6379/0 | |||
| ledger.db.uri= | |||
| #账本数据库的连接口令 | |||
| ledger.db.pwd= | |||
| #共识配置文件路径 | |||
| #推荐使用绝对路径,相对路径以当前文件(local.conf)所在目录为基准 | |||
| consensus.conf=mq.config | |||
| #共识Providers配置 | |||
| #BftSmart共识Provider:com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| #简单消息共识Provider:com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider | |||
| consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| ledger.db.pwd= | |||
| @@ -5,5 +5,5 @@ boot_file=$(ls ../libs | grep tools-initializer-booter-) | |||
| if [ ! -n "$boot_file" ]; then | |||
| echo "tools-initializer-booter is null" | |||
| else | |||
| java -jar $HOME/libs/$boot_file -l $HOME/config/init/local.conf -i $HOME/config/init/ledger-init.conf $* | |||
| java -jar $HOME/libs/$boot_file -l $HOME/config/init/local.conf -i $HOME/config/init/ledger.init $* | |||
| fi | |||
| @@ -52,6 +52,7 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.perf.LedgerInitializeWebTest; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class IntegrationTest { | |||
| // 合约测试使用的初始化数据; | |||
| @@ -435,7 +436,9 @@ public class IntegrationTest { | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = LedgerInitializeWebTest.loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -188,7 +188,9 @@ public class ConsensusTest { | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = Utils.loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -186,7 +186,9 @@ public class GlobalPerformanceTest { | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = Utils.loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -75,7 +75,9 @@ public class LedgerInitializeWebTest { | |||
| Properties props = loadConsensusSetting(); | |||
| // ConsensusProperties csProps = new ConsensusProperties(props); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -240,7 +242,9 @@ public class LedgerInitializeWebTest { | |||
| Properties props = loadConsensusSetting(); | |||
| // ConsensusProperties csProps = new ConsensusProperties(props); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -495,7 +495,9 @@ public class LedgerPerformanceTest { | |||
| LedgerInitProperties initSetting = loadInitSetting(); | |||
| Properties props = loadConsensusSetting(config); | |||
| ConsensusProvider csProvider = getConsensusProvider(provider); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| DBSetting dbsetting0; | |||
| DBSetting dbsetting1; | |||
| @@ -9,6 +9,8 @@ import java.util.concurrent.ConcurrentHashMap; | |||
| import com.jd.blockchain.crypto.*; | |||
| import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
| import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| @@ -72,6 +74,14 @@ 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])); | |||
| } | |||
| return participantNodes; | |||
| } | |||
| public static class NodeContext { | |||
| private LedgerManager ledgerManager = new LedgerManager(); | |||
| @@ -215,4 +225,46 @@ public class Utils { | |||
| } | |||
| private static class PartNode implements ParticipantNode { | |||
| private int id; | |||
| private String address; | |||
| private String name; | |||
| private PubKey pubKey; | |||
| public PartNode(int id, PubKey pubKey) { | |||
| this(id, id + "", pubKey); | |||
| } | |||
| public PartNode(int id, String name, PubKey pubKey) { | |||
| this.id = id; | |||
| this.name = name; | |||
| this.pubKey = pubKey; | |||
| this.address = pubKey.toBase58(); | |||
| } | |||
| @Override | |||
| public int getId() { | |||
| return id; | |||
| } | |||
| @Override | |||
| public String getAddress() { | |||
| return address; | |||
| } | |||
| @Override | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| @Override | |||
| public PubKey getPubKey() { | |||
| return pubKey; | |||
| } | |||
| } | |||
| } | |||
| @@ -25,6 +25,7 @@ import java.util.Random; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.atomic.AtomicLong; | |||
| import com.jd.blockchain.ledger.*; | |||
| import org.apache.commons.io.FileUtils; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| @@ -33,17 +34,6 @@ import com.jd.blockchain.contract.ReadContract; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.KVDataEntry; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.OperationResult; | |||
| import com.jd.blockchain.ledger.PreparedTransaction; | |||
| import com.jd.blockchain.ledger.TransactionResponse; | |||
| import com.jd.blockchain.ledger.TransactionState; | |||
| import com.jd.blockchain.ledger.TransactionTemplate; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.ledger.core.LedgerRepository; | |||
| import com.jd.blockchain.ledger.core.impl.LedgerManager; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| @@ -609,6 +599,12 @@ public class IntegrationBase { | |||
| System.out.printf("readContract1.result = %s \r\n", result1.get()); | |||
| System.out.printf("readContract3.result = %s \r\n", result3.get()); | |||
| for (int i = 0; i < operationResults.length; i++) { | |||
| OperationResult opResult = operationResults[i]; | |||
| System.out.printf("Operation[%s].result = %s \r\n", opResult.getIndex(), BytesValueEncoding.decode(opResult.getResult())); | |||
| } | |||
| // // 打印结果 | |||
| // for (OperationResult or : operationResults) { | |||
| @@ -29,6 +29,7 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class IntegrationBaseTest { | |||
| @@ -122,7 +123,9 @@ public class IntegrationBaseTest { | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = LedgerInitializeWeb4SingleStepsTest.loadConsensusSetting(configPath); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(providerName); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -42,6 +42,7 @@ import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.contract.AssetContract; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| /** | |||
| * 测试合约,提交后不立即进行验证,因为此时可能还没有完成正式结块; | |||
| @@ -160,7 +161,9 @@ public class IntegrationTest2 { | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = LedgerInitializeWeb4SingleStepsTest.loadConsensusSetting(config.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -46,6 +46,7 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class IntegrationTestDataAccount { | |||
| @@ -257,7 +258,9 @@ public class IntegrationTestDataAccount { | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = LedgerInitializeWeb4SingleStepsTest.loadConsensusSetting(config.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -27,6 +27,7 @@ import org.springframework.core.io.ClassPathResource; | |||
| import test.com.jd.blockchain.intgr.IntegrationBase; | |||
| import test.com.jd.blockchain.intgr.LedgerInitConsensusConfig; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| @@ -70,7 +71,9 @@ public class LedgerInitializeWeb4Nodes { | |||
| LedgerInitProperties initSetting = loadInitSetting_2(); | |||
| Properties props = loadConsensusSetting(config.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -50,6 +50,7 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.LedgerInitConsensusConfig; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class LedgerInitializeWeb4SingleStepsTest { | |||
| @@ -77,7 +78,9 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
| // 加载共识配置; | |||
| Properties props = loadConsensusSetting(consensusConfig.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(consensusConfig.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| @@ -45,6 +45,7 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest.NodeContext; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class LedgerBlockGeneratingTest { | |||
| @@ -128,7 +129,9 @@ public class LedgerBlockGeneratingTest { | |||
| LedgerInitProperties initSetting = loadInitSetting(); | |||
| Properties props = loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| @@ -14,58 +14,36 @@ | |||
| # limitations under the License. | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: transaction count ###### | |||
| ############################################ | |||
| system.block.txsize=15 | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: delay time ###### | |||
| ############################################ | |||
| system.block.maxdelay=500 | |||
| ############################################ | |||
| ###### Consensus Participant0 ###### | |||
| ############################################ | |||
| system.server.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
| system.server.0.network.host=127.0.0.1 | |||
| system.server.0.network.port=8910 | |||
| system.server.0.network.secure=false | |||
| ############################################ | |||
| ###### #Consensus Participant1 ###### | |||
| ############################################ | |||
| system.server.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
| system.server.1.network.host=127.0.0.1 | |||
| system.server.1.network.port=8920 | |||
| system.server.1.network.secure=false | |||
| ############################################ | |||
| ###### #Consensus Participant2 ###### | |||
| ############################################ | |||
| system.server.2.pubkey=3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x | |||
| system.server.2.network.host=127.0.0.1 | |||
| system.server.2.network.port=8930 | |||
| system.server.2.network.secure=false | |||
| ############################################ | |||
| ###### Consensus Participant3 ###### | |||
| ############################################ | |||
| system.server.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
| system.server.3.network.host=127.0.0.1 | |||
| system.server.3.network.port=8940 | |||
| system.server.3.network.secure=false | |||
| ############################################ | |||
| @@ -174,5 +152,4 @@ system.ttp.id = 7002 | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -5,7 +5,6 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| ledger.name= | |||
| #共识服务提供者;必须; | |||
| consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| @@ -95,6 +95,14 @@ public class LedgerInitProperties { | |||
| return consensusParticipants; | |||
| } | |||
| public ParticipantNode[] getConsensusParticipantNodes() { | |||
| if (consensusParticipants.isEmpty()) { | |||
| return null; | |||
| } | |||
| ParticipantNode[] participantNodes = new ParticipantNode[consensusParticipants.size()]; | |||
| return consensusParticipants.toArray(participantNodes); | |||
| } | |||
| public String[] getCryptoProviders() { | |||
| return cryptoProviders.clone(); | |||
| } | |||
| @@ -106,7 +114,7 @@ public class LedgerInitProperties { | |||
| /** | |||
| * 返回参与者; | |||
| * | |||
| * @param address 从 1 开始; 小于等于 {@link #getConsensusParticipantCount()}; | |||
| * @param id 从 1 开始; 小于等于 {@link #getConsensusParticipantCount()}; | |||
| * @return | |||
| */ | |||
| public ConsensusParticipantConfig getConsensusParticipant(int id) { | |||
| @@ -133,7 +141,8 @@ public class LedgerInitProperties { | |||
| public static LedgerInitProperties resolve(String initSettingFile) { | |||
| Properties props = FileUtils.readProperties(initSettingFile, "UTF-8"); | |||
| return resolve(props); | |||
| File realFile = new File(initSettingFile); | |||
| return resolve(realFile.getParentFile().getPath(), props); | |||
| } | |||
| public static LedgerInitProperties resolve(InputStream in) { | |||
| @@ -142,6 +151,10 @@ public class LedgerInitProperties { | |||
| } | |||
| public static LedgerInitProperties resolve(Properties props) { | |||
| return resolve(null, props); | |||
| } | |||
| public static LedgerInitProperties resolve(String dir, Properties props) { | |||
| String hexLedgerSeed = PropertiesUtils.getRequiredProperty(props, LEDGER_SEED).replace("-", ""); | |||
| byte[] ledgerSeed = HexUtils.decode(hexLedgerSeed); | |||
| LedgerInitProperties initProps = new LedgerInitProperties(ledgerSeed); | |||
| @@ -158,7 +171,7 @@ public class LedgerInitProperties { | |||
| initProps.consensusProvider = PropertiesUtils.getRequiredProperty(props, CONSENSUS_SERVICE_PROVIDER); | |||
| String consensusConfigFilePath = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONFIG); | |||
| try { | |||
| File consensusConfigFile = ResourceUtils.getFile(consensusConfigFilePath); | |||
| File consensusConfigFile = FileUtils.getFile(dir, consensusConfigFilePath); | |||
| initProps.consensusConfig = FileUtils.readProperties(consensusConfigFile); | |||
| } catch (FileNotFoundException e) { | |||
| throw new IllegalArgumentException( | |||
| @@ -181,8 +181,9 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| Properties csProps = ledgerInitProps.getConsensusConfig(); | |||
| ConsensusProvider csProvider = ConsensusProviders.getProvider(ledgerInitProps.getConsensusProvider()); | |||
| ConsensusSettings csSettings = csProvider.getSettingsFactory().getConsensusSettingsBuilder() | |||
| .createSettings(csProps); | |||
| ConsensusSettings csSettings = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(csProps, ledgerInitProps.getConsensusParticipantNodes()); | |||
| setConsensusProvider(csProvider); | |||
| prompter.info("Init settings and sign permision..."); | |||
| @@ -335,7 +336,9 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
| initSetting.setCryptoSetting(cryptoSetting); | |||
| List<ConsensusParticipantConfig> partiList = ledgerProps.getConsensusParticipants(); | |||
| ConsensusParticipantConfig[] parties = partiList.toArray(new ConsensusParticipantConfig[partiList.size()]); | |||
| ConsensusParticipantConfig[] parties = new ConsensusParticipantConfig[partiList.size()]; | |||
| parties = partiList.toArray(parties); | |||
| // ConsensusParticipantConfig[] parties = partiList.toArray(new ConsensusParticipantConfig[partiList.size()]); | |||
| ConsensusParticipantConfig[] orderedParties = sortAndVerify(parties); | |||
| initSetting.setConsensusParticipants(orderedParties); | |||
| initSetting.setCreatedTime(ledgerProps.getCreatedTime()); | |||
| @@ -16,6 +16,7 @@ import java.io.Reader; | |||
| import java.util.ArrayList; | |||
| import java.util.Properties; | |||
| import com.jd.blockchain.utils.PathUtils; | |||
| import org.springframework.util.ResourceUtils; | |||
| /** | |||
| @@ -482,4 +483,26 @@ public class FileUtils { | |||
| } | |||
| return path.delete(); | |||
| } | |||
| /** | |||
| * 获取指定路径和位置的文件信息 | |||
| * | |||
| * @param dir | |||
| * 指定路径,不要以"/"结尾 | |||
| * @param resourceLocation | |||
| * 文件位置信息,可支持绝对路径、相对路径(相对dir)、classpath:前缀 | |||
| * @return | |||
| * | |||
| * @throws FileNotFoundException | |||
| */ | |||
| public static File getFile(String dir, String resourceLocation) throws FileNotFoundException { | |||
| if (resourceLocation.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) { | |||
| return ResourceUtils.getFile(resourceLocation); | |||
| } | |||
| if (resourceLocation.startsWith(PathUtils.PATH_SEPERATOR)) { | |||
| return new File(resourceLocation); | |||
| } | |||
| String totalPath = PathUtils.concatPaths(dir, resourceLocation); | |||
| return new File(totalPath); | |||
| } | |||
| } | |||