@@ -17,6 +17,7 @@ public interface LedgerInitSetting { | |||
/** | |||
* 账本的种子; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
@@ -37,9 +38,8 @@ public interface LedgerInitSetting { | |||
*/ | |||
@DataField(order = 3, refContract = true) | |||
CryptoSetting getCryptoSetting(); | |||
@DataField(order = 4, primitiveType=PrimitiveType.TEXT) | |||
@DataField(order = 4, primitiveType = PrimitiveType.TEXT) | |||
String getConsensusProvider(); | |||
/** | |||
@@ -47,7 +47,15 @@ public interface LedgerInitSetting { | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 5, primitiveType=PrimitiveType.BYTES) | |||
@DataField(order = 5, primitiveType = PrimitiveType.BYTES) | |||
Bytes getConsensusSettings(); | |||
/** | |||
* 账本创建时间; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 6, primitiveType = PrimitiveType.INT64) | |||
long getCreatedTime(); | |||
} |
@@ -11,22 +11,41 @@ import com.jd.blockchain.transaction.LedgerInitOperator; | |||
* | |||
*/ | |||
public interface TransactionBuilder extends ClientOperator, LedgerInitOperator { | |||
HashDigest getLedgerHash(); | |||
/** | |||
* 完成交易定义,并生成就绪的交易数据; <br> | |||
* 基于当前的系统时间完成交易定义,并生成就绪的交易数据; <br> | |||
* | |||
* 注:调用此方法后,不能再向当前对象加入更多的操作; | |||
* 注:调用此方法后,不能再向当前对象加入更多的操作;<br> | |||
* | |||
* @return | |||
*/ | |||
TransactionRequestBuilder prepareRequest(); | |||
/** | |||
* 生成交易内容; | |||
* | |||
* @return | |||
*/ | |||
TransactionContent prepareContent(); | |||
/** | |||
* 基于当前的系统时间完成交易定义,并生成就绪的交易数据; <br> | |||
* | |||
* 注:调用此方法后,不能再向当前对象加入更多的操作; | |||
* | |||
* @param time 交易时间戳; | |||
* @return | |||
*/ | |||
TransactionRequestBuilder prepareRequest(long time); | |||
/** | |||
* 生成交易内容; | |||
* | |||
* @param time 交易时间戳; | |||
* @return | |||
*/ | |||
TransactionContent prepareContent(long time); | |||
} |
@@ -33,4 +33,13 @@ public interface TransactionContentBody { | |||
@DataField(order = 2, list = true, refContract = true, genericContract = true) | |||
Operation[] getOperations(); | |||
/** | |||
* 生成交易的时间;<br> | |||
* 以毫秒为单位,表示距离 1970-1-1 00:00:00 (UTC) 的毫秒数;<br> | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 3, primitiveType = PrimitiveType.INT64) | |||
long getTime(); | |||
} |
@@ -16,6 +16,8 @@ public class LedgerInitSettingData implements LedgerInitSetting { | |||
private String consensusProvider; | |||
private Bytes consensusSettings; | |||
private long createdTime; | |||
@Override | |||
public byte[] getLedgerSeed() { | |||
@@ -62,4 +64,12 @@ public class LedgerInitSettingData implements LedgerInitSetting { | |||
this.consensusProvider = consensusProvider; | |||
} | |||
@Override | |||
public long getCreatedTime() { | |||
return createdTime; | |||
} | |||
public void setCreatedTime(long createdTime) { | |||
this.createdTime = createdTime; | |||
} | |||
} |
@@ -35,14 +35,25 @@ public class TxBuilder implements TransactionBuilder { | |||
@Override | |||
public TransactionRequestBuilder prepareRequest() { | |||
TransactionContent txContent = prepareContent(); | |||
return new TxRequestBuilder(txContent); | |||
return prepareRequest(System.currentTimeMillis()); | |||
} | |||
@Override | |||
public TransactionContent prepareContent() { | |||
return prepareContent(System.currentTimeMillis()); | |||
} | |||
@Override | |||
public TransactionRequestBuilder prepareRequest(long time) { | |||
TransactionContent txContent = prepareContent(time); | |||
return new TxRequestBuilder(txContent); | |||
} | |||
@Override | |||
public TransactionContent prepareContent(long time) { | |||
TxContentBlob txContent = new TxContentBlob(ledgerHash); | |||
txContent.addOperations(opFactory.getOperations()); | |||
txContent.setTime(time); | |||
byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); | |||
HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); | |||
@@ -30,6 +30,8 @@ public class TxContentBlob implements TransactionContent { | |||
private HashDigest hash; | |||
private HashDigest ledgerHash; | |||
private long time; | |||
public TxContentBlob(HashDigest ledgerHash) { | |||
this.ledgerHash = ledgerHash; | |||
@@ -80,6 +82,15 @@ public class TxContentBlob implements TransactionContent { | |||
addOperation(op); | |||
} | |||
} | |||
@Override | |||
public long getTime() { | |||
return time; | |||
} | |||
public void setTime(long time) { | |||
this.time = time; | |||
} | |||
public void addOperation(Operation operation) { | |||
operationList.add(operation); | |||
@@ -1,85 +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=jd.com | |||
#第0个参与方的公钥文件路径; | |||
cons_parti.0.pubkey-path=keys/jd-com.pub | |||
#第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.0.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
#第0个参与方的共识服务的主机地址; | |||
cons_parti.0.consensus.host=127.0.0.1 | |||
#第0个参与方的共识服务的端口; | |||
cons_parti.0.consensus.port=8900 | |||
#第0个参与方的共识服务是否开启安全连接; | |||
cons_parti.0.consensus.secure=true | |||
#第0个参与方的账本初始服务的主机; | |||
cons_parti.0.initializer.host=127.0.0.1 | |||
#第0个参与方的账本初始服务的端口; | |||
cons_parti.0.initializer.port=8800 | |||
#第0个参与方的账本初始服务是否开启安全连接; | |||
cons_parti.0.initializer.secure=true | |||
#第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=endPsK36sC5JdPCDPDAXUwZtS3sxEmqEhFcC4whayAsTTh8Z6eoZ | |||
#第1个参与方的共识服务的主机地址; | |||
cons_parti.1.consensus.host=127.0.0.1 | |||
#第1个参与方的共识服务的端口; | |||
cons_parti.1.consensus.port=8910 | |||
#第1个参与方的共识服务是否开启安全连接; | |||
cons_parti.1.consensus.secure=false | |||
#第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=keys/bt-com.pub | |||
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.2.pubkey=endPsK36jEG281HMHeh6oSqzqLkT95DTnCM6REDURjdb2c67uR3R | |||
#第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 | |||
#第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=endPsK36nse1dck4uF19zPvAMijCV336Y3zWdgb4rQG8QoRj5ktR | |||
#第3个参与方的共识服务的主机地址; | |||
cons_parti.3.consensus.host=127.0.0.1 | |||
#第3个参与方的共识服务的端口; | |||
cons_parti.3.consensus.port=8930 | |||
#第3个参与方的共识服务是否开启安全连接; | |||
cons_parti.3.consensus.secure=false | |||
#第3个参与方的账本初始服务的主机; | |||
cons_parti.3.initializer.host=127.0.0.1 | |||
#第3个参与方的账本初始服务的端口; | |||
cons_parti.3.initializer.port=8830 | |||
#第3个参与方的账本初始服务是否开启安全连接; | |||
cons_parti.3.initializer.secure=false |
@@ -1,8 +1,5 @@ | |||
package com.jd.blockchain.tools.initializer; | |||
import com.jd.blockchain.consensus.ConsensusProvider; | |||
import com.jd.blockchain.consensus.ConsensusSettings; | |||
import com.jd.blockchain.consensus.service.ConsensusServiceProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.PrivKey; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
@@ -3,6 +3,8 @@ package com.jd.blockchain.tools.initializer; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.InputStream; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Properties; | |||
@@ -22,6 +24,12 @@ public class LedgerInitProperties { | |||
// 账本种子; | |||
public static final String LEDGER_SEED = "ledger.seed"; | |||
// 声明的账本建立时间; | |||
public static final String CREATED_TIME = "created-time"; | |||
// 创建时间的格式; | |||
public static final String CREATED_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSZ"; | |||
// 共识参与方的个数,后续以 part.id 分别标识每一个参与方的配置; | |||
public static final String PART_COUNT = "cons_parti.count"; | |||
// 共识参与方的名称的模式; | |||
@@ -61,10 +69,16 @@ public class LedgerInitProperties { | |||
private String[] cryptoProviders; | |||
private long createdTime; | |||
public byte[] getLedgerSeed() { | |||
return ledgerSeed.clone(); | |||
} | |||
public long getCreatedTime() { | |||
return createdTime; | |||
} | |||
public Properties getConsensusConfig() { | |||
return consensusConfig; | |||
} | |||
@@ -80,11 +94,11 @@ public class LedgerInitProperties { | |||
public List<ConsensusParticipantConfig> getConsensusParticipants() { | |||
return consensusParticipants; | |||
} | |||
public String[] getCryptoProviders() { | |||
return cryptoProviders.clone(); | |||
} | |||
public void setCryptoProviders(String[] cryptoProviders) { | |||
this.cryptoProviders = cryptoProviders; | |||
} | |||
@@ -132,6 +146,14 @@ public class LedgerInitProperties { | |||
byte[] ledgerSeed = HexUtils.decode(hexLedgerSeed); | |||
LedgerInitProperties initProps = new LedgerInitProperties(ledgerSeed); | |||
// 创建时间; | |||
String strCreatedTime = PropertiesUtils.getRequiredProperty(props, CREATED_TIME); | |||
try { | |||
initProps.createdTime = new SimpleDateFormat(CREATED_TIME_FORMAT).parse(strCreatedTime).getTime(); | |||
} catch (ParseException ex) { | |||
throw new IllegalArgumentException(ex.getMessage(), ex); | |||
} | |||
// 解析共识相关的属性; | |||
initProps.consensusProvider = PropertiesUtils.getRequiredProperty(props, CONSENSUS_SERVICE_PROVIDER); | |||
String consensusConfigFilePath = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONFIG); | |||
@@ -338,6 +338,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
ConsensusParticipantConfig[] parties = partiList.toArray(new ConsensusParticipantConfig[partiList.size()]); | |||
ConsensusParticipantConfig[] orderedParties = sortAndVerify(parties); | |||
initSetting.setConsensusParticipants(orderedParties); | |||
initSetting.setCreatedTime(ledgerProps.getCreatedTime()); | |||
// 创建默认的共识配置; | |||
try { | |||
@@ -377,7 +378,8 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
BlockchainIdentity superUserId = new BlockchainIdentityData(p.getPubKey()); | |||
initTxBuilder.users().register(superUserId); | |||
} | |||
this.initTxContent = initTxBuilder.prepareContent(); | |||
// 账本初始化配置声明的创建时间来初始化交易时间戳;注:不能用本地时间,因为共识节点之间的本地时间系统不一致; | |||
this.initTxContent = initTxBuilder.prepareContent(initSetting.getCreatedTime()); | |||
// 对初始交易签名,生成当前参与者的账本初始化许可; | |||
SignatureDigest permissionSign = TxRequestBuilder.sign(initTxContent, privKey); | |||
@@ -755,7 +757,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
prompter.info("Received request of synchronizing decision! --[RemoteId=%s][CurrentId=%s]", remoteId, currentId); | |||
try { | |||
DecisionResultHandle resultHandle = this.decisions[remoteId]; | |||
if (!validateAndRecordDecision(initDecision, resultHandle)) { | |||
// 签名无效; | |||
@@ -1,9 +1,12 @@ | |||
package test.com.jd.blockchain.intgr.initializer; | |||
package test.com.jd.blockchain.tools.initializer; | |||
import static org.junit.Assert.*; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import org.junit.Test; | |||
@@ -14,12 +17,21 @@ import com.jd.blockchain.tools.initializer.LedgerInitProperties; | |||
import com.jd.blockchain.tools.initializer.LedgerInitProperties.ConsensusParticipantConfig; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.codec.HexUtils; | |||
import test.com.jd.blockchain.intgr.IntegrationBase; | |||
public class LedgerInitPropertiesTest { | |||
private static String expectedCreatedTimeStr = "2019-08-01 14:26:58.069+0800"; | |||
@Test | |||
public void test() throws IOException { | |||
public void testTimeFormat() throws ParseException { | |||
SimpleDateFormat timeFormat = new SimpleDateFormat(LedgerInitProperties.CREATED_TIME_FORMAT); | |||
Date time = timeFormat.parse(expectedCreatedTimeStr); | |||
String actualTimeStr = timeFormat.format(time); | |||
assertEquals(expectedCreatedTimeStr, actualTimeStr); | |||
} | |||
@Test | |||
public void testProperties() throws IOException, ParseException { | |||
ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger.init"); | |||
InputStream in = ledgerInitSettingResource.getInputStream(); | |||
try { | |||
@@ -30,6 +42,13 @@ public class LedgerInitPropertiesTest { | |||
String actualLedgerSeed = HexUtils.encode(initProps.getLedgerSeed()); | |||
assertEquals(expectedLedgerSeed, actualLedgerSeed); | |||
SimpleDateFormat timeFormat = new SimpleDateFormat(LedgerInitProperties.CREATED_TIME_FORMAT); | |||
long expectedTs = timeFormat.parse(expectedCreatedTimeStr).getTime(); | |||
assertEquals(expectedTs, initProps.getCreatedTime()); | |||
String createdTimeStr = timeFormat.format(new Date(initProps.getCreatedTime())); | |||
assertEquals(expectedCreatedTimeStr, createdTimeStr); | |||
assertEquals("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", | |||
initProps.getConsensusProvider()); | |||
@@ -61,7 +80,7 @@ public class LedgerInitPropertiesTest { | |||
@Test | |||
public void testPubKeyAddress() { | |||
String[] pubKeys = IntegrationBase.PUB_KEYS; | |||
String[] pubKeys = TestConsts.PUB_KEYS; | |||
int index = 0; | |||
for (String pubKeyStr : pubKeys) { | |||
System.out.println("[" + index + "][配置] = " + pubKeyStr); |
@@ -0,0 +1,37 @@ | |||
/** | |||
* Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
* FileName: test.com.jd.blockchain.intgr.perf.IntegrationBase | |||
* Author: shaozhuguang | |||
* Department: 区块链研发部 | |||
* Date: 2018/12/25 下午3:40 | |||
* Description: | |||
*/ | |||
package test.com.jd.blockchain.tools.initializer; | |||
import java.util.concurrent.atomic.AtomicLong; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.ledger.LedgerInitOperation; | |||
import com.jd.blockchain.ledger.UserRegisterOperation; | |||
public class TestConsts { | |||
static { | |||
DataContractRegistry.register(LedgerInitOperation.class); | |||
DataContractRegistry.register(UserRegisterOperation.class); | |||
} | |||
public static final String PASSWORD = "abc"; | |||
public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", | |||
"3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", | |||
"3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", | |||
"3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; | |||
public static final String[] PRIV_KEYS = { | |||
"177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", | |||
"177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", | |||
"177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", | |||
"177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; | |||
} |
@@ -0,0 +1,144 @@ | |||
# Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
# | |||
# Licensed under the Apache License, Version 2.0 (the "License"); | |||
# you may not use this file except in compliance with the License. | |||
# You may obtain a copy of the License at | |||
# | |||
# http://www.apache.org/licenses/LICENSE-2.0 | |||
# | |||
# Unless required by applicable law or agreed to in writing, software | |||
# distributed under the License is distributed on an "AS IS" BASIS, | |||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
# See the License for the specific language governing permissions and | |||
# limitations under the License. | |||
############################################ | |||
####### Communication Configurations ####### | |||
############################################ | |||
#HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
#This parameter is not currently being used being used | |||
#system.authentication.hmacAlgorithm = HmacSHA1 | |||
#Specify if the communication system should use a thread to send data (true or false) | |||
system.communication.useSenderThread = true | |||
#Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
#and benchmarks, but must not be used in production systems. | |||
system.communication.defaultkeys = true | |||
############################################ | |||
### Replication Algorithm Configurations ### | |||
############################################ | |||
#Timeout to asking for a client request | |||
system.totalordermulticast.timeout = 2000 | |||
#Maximum batch size (in number of messages) | |||
system.totalordermulticast.maxbatchsize = 400 | |||
#Number of nonces (for non-determinism actions) generated | |||
system.totalordermulticast.nonces = 10 | |||
#if verification of leader-generated timestamps are increasing | |||
#it can only be used on systems in which the network clocks | |||
#are synchronized | |||
system.totalordermulticast.verifyTimestamps = false | |||
#Quantity of messages that can be stored in the receive queue of the communication system | |||
system.communication.inQueueSize = 500000 | |||
# Quantity of messages that can be stored in the send queue of each replica | |||
system.communication.outQueueSize = 500000 | |||
#Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
system.communication.useSignatures = 0 | |||
#Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
system.communication.useMACs = 1 | |||
#Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
system.debug = 0 | |||
#Print information about the replica when it is shutdown | |||
system.shutdownhook = true | |||
############################################ | |||
###### State Transfer Configurations ####### | |||
############################################ | |||
#Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
system.totalordermulticast.state_transfer = true | |||
#Maximum ahead-of-time message not discarded | |||
system.totalordermulticast.highMark = 10000 | |||
#Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
system.totalordermulticast.revival_highMark = 10 | |||
#Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
system.totalordermulticast.timeout_highMark = 200 | |||
############################################ | |||
###### Log and Checkpoint Configurations ### | |||
############################################ | |||
system.totalordermulticast.log = true | |||
system.totalordermulticast.log_parallel = false | |||
system.totalordermulticast.log_to_disk = false | |||
system.totalordermulticast.sync_log = false | |||
#Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
system.totalordermulticast.checkpoint_period = 1000 | |||
system.totalordermulticast.global_checkpoint_period = 120000 | |||
system.totalordermulticast.checkpoint_to_disk = false | |||
system.totalordermulticast.sync_ckp = false | |||
############################################ | |||
###### Reconfiguration Configurations ###### | |||
############################################ | |||
#The ID of the trust third party (TTP) | |||
system.ttp.id = 7002 | |||
#This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
system.bft = true | |||
#Custom View Storage; | |||
#view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
#Number of servers in the group | |||
system.servers.num = 4 | |||
#Maximum number of faulty replicas | |||
system.servers.f = 1 | |||
#Replicas ID for the initial view, separated by a comma. | |||
# The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
system.initial.view = 0,1,2,3 | |||
#Configuration of all node servers; | |||
#PubKey of node server with specified ID, with base58 encoding. | |||
system.server.0.pubkey= | |||
system.server.0.network.host=127.0.0.1 | |||
system.server.0.network.port=8900 | |||
system.server.0.network.secure=false | |||
system.server.1.pubkey= | |||
system.server.1.network.host=127.0.0.1 | |||
system.server.1.network.port=8910 | |||
system.server.1.network.secure=false | |||
system.server.2.pubkey= | |||
system.server.2.network.host=127.0.0.1 | |||
system.server.2.network.port=8920 | |||
system.server.2.network.secure=false | |||
system.server.3.pubkey= | |||
system.server.3.network.host=127.0.0.1 | |||
system.server.3.network.port=8920 | |||
system.server.3.network.secure=false |
@@ -0,0 +1 @@ | |||
3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x |
@@ -5,6 +5,20 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 | |||
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
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 | |||
#密码服务提供者列表,以英文逗点“,”分隔;必须; | |||
crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ | |||
com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
cons_parti.count=4 | |||
@@ -13,7 +27,7 @@ cons_parti.0.name=jd.com | |||
#第0个参与方的公钥文件路径; | |||
cons_parti.0.pubkey-path=keys/jd-com.pub | |||
#第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.0.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
#第0个参与方的共识服务的主机地址; | |||
cons_parti.0.consensus.host=127.0.0.1 | |||
#第0个参与方的共识服务的端口; | |||
@@ -32,7 +46,7 @@ cons_parti.1.name=at.com | |||
#第1个参与方的公钥文件路径; | |||
cons_parti.1.pubkey-path=keys/at-com.pub | |||
#第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.1.pubkey=endPsK36sC5JdPCDPDAXUwZtS3sxEmqEhFcC4whayAsTTh8Z6eoZ | |||
cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
#第1个参与方的共识服务的主机地址; | |||
cons_parti.1.consensus.host=127.0.0.1 | |||
#第1个参与方的共识服务的端口; | |||
@@ -49,9 +63,9 @@ cons_parti.1.initializer.secure=false | |||
#第2个参与方的名称; | |||
cons_parti.2.name=bt.com | |||
#第2个参与方的公钥文件路径; | |||
cons_parti.2.pubkey-path=keys/bt-com.pub | |||
cons_parti.2.pubkey-path=classpath:keys/parti2.pub | |||
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.2.pubkey=endPsK36jEG281HMHeh6oSqzqLkT95DTnCM6REDURjdb2c67uR3R | |||
cons_parti.2.pubkey= | |||
#第2个参与方的共识服务的主机地址; | |||
cons_parti.2.consensus.host=127.0.0.1 | |||
#第2个参与方的共识服务的端口; | |||
@@ -70,7 +84,7 @@ cons_parti.3.name=xt.com | |||
#第3个参与方的公钥文件路径; | |||
cons_parti.3.pubkey-path=keys/xt-com.pub | |||
#第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.3.pubkey=endPsK36nse1dck4uF19zPvAMijCV336Y3zWdgb4rQG8QoRj5ktR | |||
cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
#第3个参与方的共识服务的主机地址; | |||
cons_parti.3.consensus.host=127.0.0.1 | |||
#第3个参与方的共识服务的端口; | |||