use of bftsmart.reconfiguration.views.View in project bftsmart by blockchain-jd-com.
the class LeaderConfirmationTask method generateRegencyPropose.
/**
* 根据收集的全局的执政期清单,以当前视图为基准生成新的执政期提议;
*
* @return
*/
public synchronized LeaderRegencyPropose generateRegencyPropose() {
int maxRegency = tomLayer.getSynchronizer().getLCManager().getLastReg();
for (Map.Entry<Integer, LeaderRegencyView> entry : responsedRegencies.entrySet()) {
int regency = entry.getValue().getRegency().getId();
if (regency > maxRegency) {
maxRegency = regency;
}
}
int nextRegency = maxRegency + 1;
View view = tomLayer.controller.getCurrentView();
int sender = tomLayer.controller.getStaticConf().getProcessId();
return LeaderRegencyPropose.chooseFromView(nextRegency, view, sender);
}
use of bftsmart.reconfiguration.views.View in project bftsmart by blockchain-jd-com.
the class LeaderTimeoutTask method waitStatusResposne.
/**
* 等待超时状态查询的回复;
*/
private void waitStatusResposne() {
try {
// }
if (tomLayer.getSynchronizer().getLCManager().isInProgress()) {
// 已经在选举中了,先终止当前任务;
cancelTask();
return;
}
if (!HEART_BEAT_TIMER.isHeartBeatTimeout()) {
// 已经不超时了,则终止当前任务;
cancelTask();
return;
}
// 等待应答结果
// 状态不为空的情况下进行汇总,并且是同一个Sequence
View currentView = tomLayer.controller.getCurrentView();
int quorum = tomLayer.controller.getStaticConf().isBFT() ? currentView.computeBFT_QUORUM() : currentView.computeCFT_QUORUM();
// 检查是否全局已经进入超时状态;
LeaderRegencyStatus[] timeoutStatuses = leaderStatusContext.getTimeoutStatus();
if (timeoutStatuses.length >= quorum) {
// 超时数量已经超过法定数量;
LOGGER.info("I am {}, receive more than f response for timeout, so I will start to LC !", tomLayer.controller.getStaticConf().getProcessId());
// 表示可以触发领导者切换流程
LeaderRegencyPropose regencyPropose = leaderStatusContext.generateRegencyPropose();
tomLayer.requestsTimer.run_lc_protocol(regencyPropose);
// 取消任务;
cancelTask();
return;
}
// 未达到全局超时的状态;
// 检查是否全局的法定大多数节点存在一致的执政期;
LeaderRegencyStatus[] greatestRegencyStatuses = leaderStatusContext.getGreatestRegencyStatus();
if (greatestRegencyStatuses.length >= quorum) {
// 全局大多数节点已经具备一致的执政期;当前节点跟上新的领导者;
boolean leaderConsistency = true;
int leaderId = greatestRegencyStatuses[0].getLeaderId();
for (int i = 1; i < greatestRegencyStatuses.length; i++) {
if (leaderId != greatestRegencyStatuses[i].getLeaderId()) {
// 出现相同的执政期但是领导者不同的情况;
// 此种情况先不做处理,有可能是其它节点处于不稳定状态;
// 继续等待到以后的机会;
leaderConsistency = false;
}
}
if (leaderConsistency) {
// 尝试跳跃到新的执政期;
// 如果未能跳跃到新的执政期,则继续执行超时等待任务,等待以后的机会;
LeaderRegency newRegency = greatestRegencyStatuses[0];
if (tomLayer.getSynchronizer().getLCManager().tryJumpToRegency(newRegency)) {
tomLayer.getExecManager().setNewLeader(newRegency.getLeaderId());
// 完成任务;
cancelTask();
return;
}
}
}
// 则继续重复发送超时状态请求,并继续接收其它节点的回复,不断更新本地接收到全局的执政期状态;
if (isTaskTimeout()) {
// 更新自身的状态;
setSelfStatus();
// 发送超时状态请求;
sendStatusRequest(leaderStatusContext.sequence);
// 重置任务执行超时状态;
// 控制重复发送超时状态请求的频率,只有每一次任务执行时间超时之后才重新发送;
resetTaskTimeout();
}
} catch (Exception e) {
// 处理错误;避免异常抛出后中断任务;
LOGGER.info("Handle leader status response error !!!", e);
}
}
use of bftsmart.reconfiguration.views.View in project bftsmart by blockchain-jd-com.
the class MessageHandler method processData.
@SuppressWarnings("unchecked")
public void processData(SystemMessage sm) {
if (sm instanceof ConsensusMessage) {
int myId = tomLayer.controller.getStaticConf().getProcessId();
ConsensusMessage consMsg = (ConsensusMessage) sm;
if (//
consMsg.getSender() == myId || //
(!tomLayer.controller.getStaticConf().isUseMACs()) || consMsg.authenticated) {
acceptor.deliver(consMsg);
} else if (consMsg.getType() == MessageFactory.ACCEPT && consMsg.getProof() != null) {
// We are going to verify the MAC vector at the algorithm level
HashMap<Integer, byte[]> macVector = (HashMap<Integer, byte[]>) consMsg.getProof();
byte[] recvMAC = macVector.get(myId);
ConsensusMessage cm = new ConsensusMessage(MessageFactory.ACCEPT, consMsg.getNumber(), consMsg.getEpoch(), consMsg.getSender(), consMsg.getValue());
ByteArrayOutputStream bOut = new ByteArrayOutputStream(248);
try {
new ObjectOutputStream(bOut).writeObject(cm);
} catch (IOException ex) {
throw new IllegalStateException("Error occurred while serializing ConsensusMessage[" + cm.toString() + "]! --" + ex.getMessage(), ex);
}
byte[] data = bOut.toByteArray();
// byte[] hash = tomLayer.computeHash(data);
byte[] myMAC = null;
MacMessageCodec<SystemMessage> msgCodec = tomLayer.getCommunication().getServersCommunication().getMessageCodec(consMsg.getSender());
MacKey macKey = msgCodec.getMacKey();
if (macKey != null) {
myMAC = macKey.generateMac(data);
}
if (recvMAC != null && myMAC != null && Arrays.equals(recvMAC, myMAC))
acceptor.deliver(consMsg);
else {
LOGGER.error("(MessageHandler.processData) WARNING: invalid MAC from {}", sm.getSender());
}
} else {
LOGGER.error("(MessageHandler.processData) Discarding unauthenticated message from {}", sm.getSender());
}
} else if (sm instanceof HeartBeatMessage) {
// 心跳消息
tomLayer.heartBeatTimer.receiveHeartBeatMessage((HeartBeatMessage) sm);
} else if (sm instanceof ViewMessage) {
// 视图消息
// 通过该消息可更新本地视图
ViewMessage viewMessage = (ViewMessage) sm;
int remoteId = viewMessage.getSender();
View view = viewMessage.getView();
if (view != null) {
tomLayer.viewSyncTimer.updateView(remoteId, view);
}
} else if (sm instanceof LeaderRequestMessage) {
// 获取Leader节点请求的消息
tomLayer.heartBeatTimer.receiveLeaderRequestMessage((LeaderRequestMessage) sm);
} else if (sm instanceof LeaderResponseMessage) {
// 获取Leader节点请求的消息
tomLayer.heartBeatTimer.receiveLeaderResponseMessage((LeaderResponseMessage) sm);
} else if (sm instanceof LeaderStatusResponseMessage) {
// 该处理顺序必须在前面,因为LeaderStatusResponseMessage继承自LeaderStatusRequestMessage
tomLayer.heartBeatTimer.receiveLeaderStatusResponseMessage((LeaderStatusResponseMessage) sm);
} else if (sm instanceof LeaderStatusRequestMessage) {
tomLayer.heartBeatTimer.receiveLeaderStatusRequestMessage((LeaderStatusRequestMessage) sm);
} else {
if ((!tomLayer.controller.getStaticConf().isUseMACs()) || sm.authenticated) {
/**
* This is Joao's code, related to leader change
*/
if (sm instanceof LCMessage) {
LCMessage lcMsg = (LCMessage) sm;
tomLayer.getSynchronizer().deliverTimeoutRequest(lcMsg);
/**
***********************************************************
*/
} else if (sm instanceof ForwardedMessage) {
TOMMessage request = ((ForwardedMessage) sm).getRequest();
tomLayer.requestReceived(request);
/**
* This is Joao's code, to handle state transfer
*/
} else if (sm instanceof SMMessage) {
SMMessage smsg = (SMMessage) sm;
LOGGER.debug("I am {}, receive SMMessage[{}], type = {} !", tomLayer.controller.getStaticConf().getProcessId(), smsg.getSender(), smsg.getType());
switch(smsg.getType()) {
case TOMUtil.SM_REQUEST:
tomLayer.getStateManager().SMRequestDeliver(smsg, tomLayer.controller.getStaticConf().isBFT());
break;
case TOMUtil.SM_REPLY:
tomLayer.getStateManager().SMReplyDeliver(smsg, tomLayer.controller.getStaticConf().isBFT());
break;
case TOMUtil.SM_ASK_INITIAL:
tomLayer.getStateManager().currentConsensusIdAsked(smsg.getSender(), smsg.getView().getId());
break;
case TOMUtil.SM_REPLY_INITIAL:
tomLayer.getStateManager().currentConsensusIdReceived(smsg);
break;
default:
tomLayer.getStateManager().stateTimeout();
break;
}
/**
***************************************************************
*/
} else if (sm instanceof StandardTRMessage) {
StandardTRMessage trMessage = (StandardTRMessage) sm;
LOGGER.info("I am {}, receive StandardTRMessage[{}], type = {} !", tomLayer.controller.getStaticConf().getProcessId(), trMessage.getSender(), trMessage.getType());
switch(trMessage.getType()) {
case TOMUtil.SM_TRANSACTION_REPLAY_REQUEST_INFO:
tomLayer.getStateManager().transactionReplayAsked(trMessage.sender, trMessage.getTarget(), trMessage.getStartCid(), trMessage.getEndCid());
break;
case TOMUtil.SM_TRANSACTION_REPLAY_REPLY_INFO:
tomLayer.getStateManager().transactionReplayReplyDeliver(trMessage);
break;
default:
break;
}
} else {
LOGGER.error("UNKNOWN MESSAGE TYPE: {}", sm);
}
} else {
LOGGER.error("(MessageHandler.processData) Discarding unauthenticated message from {}", sm.getSender());
}
}
}
use of bftsmart.reconfiguration.views.View in project jdchain-core by blockchain-jd-com.
the class BftsmartNodeServer method initConfig.
protected void initConfig(int id, Properties systemsConfig, HostsConfig hostConfig) {
HostsConfig outerHostConfig = BinarySerializeUtils.deserialize(BinarySerializeUtils.serialize(hostConfig));
Properties sysConfClone = (Properties) systemsConfig.clone();
int port = hostConfig.getPort(id);
boolean isSecure = hostConfig.isSecure(id);
// hostConfig.add(id, DEFAULT_BINDING_HOST, port);
// if peer-startup.sh set up the -DhostIp=xxx, then get it;
String preHostPort = System.getProperty("hostPort");
if (!StringUtils.isEmpty(preHostPort)) {
port = NumberUtils.parseNumber(preHostPort, Integer.class);
LOGGER.info("###peer-startup.sh###,set up the -DhostPort=" + port);
}
int monitorPort = RuntimeConstant.getMonitorPort();
boolean monitorSecure = RuntimeConstant.isMonitorSecure();
String preHostIp = System.getProperty("hostIp");
if (!StringUtils.isEmpty(preHostIp)) {
hostConfig.add(id, preHostIp, port, monitorPort, isSecure, monitorSecure);
LOGGER.info("###peer-startup.sh###,set up the -DhostIp=" + preHostIp);
LOGGER.info("###peer-startup.sh###,isSecure=" + isSecure);
}
// 调整视图中的本节点端口号
consensusAddresses.get(id).setMonitorPort(monitorPort);
consensusAddresses.get(id).setMonitorSecure(monitorSecure);
this.tomConfig = new TOMConfiguration(id, systemsConfig, hostConfig, outerHostConfig);
Collection<NodeNetwork> nodeNetworks = consensusAddresses.values();
NodeNetwork[] nodeNetworksArray = new NodeNetwork[nodeNetworks.size()];
// 保证处理器ID与共识端口一致性
int[] init_view = new int[consensusAddresses.size()];
int i = 0;
for (int proid : consensusAddresses.keySet()) {
init_view[i++] = proid;
}
this.latestView = new View(setting.getViewId(), init_view, tomConfig.getF(), nodeNetworks.toArray(nodeNetworksArray));
LOGGER.info("[initConfig] latestview = {}", this.latestView);
this.outerTomConfig = new TOMConfiguration(id, sysConfClone, outerHostConfig);
}
use of bftsmart.reconfiguration.views.View in project jdchain-core by blockchain-jd-com.
the class BftsmartPeerProxyFactory method create.
@Override
public AsynchServiceProxy create() throws Exception {
BftsmartTopology topology = BinarySerializeUtils.deserialize(bftsmartClientSettings.getTopology());
View view = topology.getView();
if (view == null) {
throw new IllegalStateException("No topology view in the bftsmart client settings!");
}
MemoryBasedViewStorage viewStorage = new MemoryBasedViewStorage(view);
TOMConfiguration tomConfiguration = BinarySerializeUtils.deserialize(bftsmartClientSettings.getTomConfig());
// every proxy client has unique id;
int processId = allocateId();
tomConfiguration.setProcessId(processId);
AsynchServiceProxy peerProxy = new AsynchServiceProxy(tomConfiguration, viewStorage, bftsmartClientSettings.getSSLSecurity());
if (LOGGER.isInfoEnabled()) {
// 打印view
int[] processes = view.getProcesses();
NodeNetwork[] addresses = new NodeNetwork[processes.length];
for (int i = 0; i < addresses.length; i++) {
addresses[i] = view.getAddress(processes[i]);
}
LOGGER.info("Creating pooled bftsmart client ... [PooledClientID={}] [ViewID={}] [ViewTopology={}] [Peers={}]", processId, view.getId(), Arrays.toString(processes), Arrays.toString(addresses));
}
return peerProxy;
}
Aggregations