Search in sources :

Example 1 with LeaderRegencyPropose

use of bftsmart.tom.leaderchange.LeaderRegencyPropose in project bftsmart by blockchain-jd-com.

the class Synchronizer method processOutOfContextSTOPs.

// Processes STOP messages that were not process upon reception, because they
// were
// ahead of the replica's expected regency
private void processOutOfContextSTOPs(int regency) {
    // Logger.println("(Synchronizer.processOutOfContextSTOPs) Checking if there are out of context STOPs for regency " + regency);
    Set<LCMessage> stops = getOutOfContextLC(LCType.STOP, regency);
    if (stops.size() > 0) {
        LOGGER.info("(Synchronizer.processOutOfContextSTOPs) [{}] -> I am proc {} Processing {} out of context STOPs for regency {}", this.execManager.getTOMLayer().getRealName(), controller.getStaticConf().getProcessId(), stops.size(), regency);
    } else {
        LOGGER.info("(Synchronizer.processOutOfContextSTOPs) [{}] -> I am proc {} No out of context STOPs for regency {}", this.execManager.getTOMLayer().getRealName(), controller.getStaticConf().getProcessId(), regency);
    }
    for (LCMessage m : stops) {
        TOMMessage[] requests = deserializeTOMMessages(m.getPayload());
        // store requests that came with the STOP message
        lcManager.addRequestsFromSTOP(requests);
        // store information about the STOP message
        LeaderRegencyPropose propose = LeaderRegencyPropose.copy(m.getLeader(), m.getReg(), m.getViewId(), m.getViewProcessIds(), m.getSender());
        lcManager.addStop(propose);
    }
}
Also used : TOMMessage(bftsmart.tom.core.messages.TOMMessage) LCMessage(bftsmart.tom.leaderchange.LCMessage) LeaderRegencyPropose(bftsmart.tom.leaderchange.LeaderRegencyPropose)

Example 2 with LeaderRegencyPropose

use of bftsmart.tom.leaderchange.LeaderRegencyPropose in project bftsmart by blockchain-jd-com.

the class Synchronizer method process_LC_STOP.

private synchronized void process_LC_STOP(LCMessage msg) {
    // message STOP
    log_debug("process_LC_STOP", "begin...", msg.getType(), msg.getSender());
    // TODO: 收到 STOP 消息;
    // this message is for the next leader change?
    LeaderRegencyPropose regencyPropose = copyPropose(msg);
    final int proposedRegencyId = regencyPropose.getRegency().getId();
    if (lcManager.canPropose(proposedRegencyId)) {
        if (lcManager.isFutureAfterNextRegency(proposedRegencyId)) {
            // send STOP to out of context
            // 处于选举进程中,但是提议的执政期Id 大于当前选举中的执政期 Id,说明这是一个执政期Id超前的提议;
            // it is for a future regency
            log_debug("process_LC_STOP", "Keeping STOP message as out of context for regency[" + msg.getReg() + "]!", msg.getType(), msg.getSender());
            outOfContextLC.add(msg);
            // 解决节点处于选举中,新一轮选举的消息放入缓存没有机会处理的问题
            LeaderRegency maxRegency = getMaxRegencyFromOutofContextLC();
            // 对超出预期的,且个数满足f+1条件的最大regency进行处理
            for (int outofregency = maxRegency.getId(); outofregency > lcManager.getNextReg(); outofregency--) {
                if (maxRegencyOutOfContextSTOPs(outofregency) == lcManager.getBeginQuorum()) {
                    LOGGER.info("I am proc {}, process out of context msg for regency {}", this.controller.getStaticConf().getProcessId(), outofregency);
                    processOutOfContextSTOPs(outofregency);
                    lcManager.updateNextReg(outofregency);
                    // 生成本地的附议Stop消息
                    LeaderRegencyPropose leaderRegencyPropose = LeaderRegencyPropose.copy(maxRegency.getLeaderId(), maxRegency.getId(), this.controller.getCurrentView().getId(), this.controller.getCurrentView().getProcesses(), getCurrentId());
                    lcManager.addStop(leaderRegencyPropose);
                    try {
                        byte[] payload = makeTomMessageReplyBatch(maxRegency.getId());
                        LCMessage msgSTOP_APPEND = LCMessage.createSTOP_APPEND(this.controller.getStaticConf().getProcessId(), leaderRegencyPropose.getRegency(), controller.getCurrentView(), payload);
                        // make replica re-transmit the stop
                        requestsTimer.setSTOP(maxRegency.getId(), msgSTOP_APPEND);
                        communication.send(this.controller.getCurrentViewOtherAcceptors(), msgSTOP_APPEND);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        } else {
            // 未开始选举进程,或者已经开始选举进程并且提议的执政期等于正在选举中的执政期;
            // 等同于表达式:(!lcManager.isInProgress()) || proposedRegencyId ==
            // lcManager.getNextReg()
            log_debug("process_LC_STOP", "received regency change request.", msg.getType(), msg.getSender());
            TOMMessage[] requests = deserializeTOMMessages(msg.getPayload());
            // store requests that came with the STOP message
            lcManager.addRequestsFromSTOP(requests);
            // 当前的领导者;
            // store information about the message STOP
            lcManager.addStop(regencyPropose);
            // the replica might have received STOPs
            processOutOfContextSTOPs(msg.getReg());
            // that were out of context at the time they
            // were received, but now can be processed
            // evaluate STOP messages
            startSynchronization(regencyPropose);
        }
    } else {
        log_warn("process_LC_STOP", "Discard the outdated STOP message with regency[" + proposedRegencyId + "]!", msg.getType(), msg.getSender());
    }
}
Also used : TOMMessage(bftsmart.tom.core.messages.TOMMessage) LeaderRegencyPropose(bftsmart.tom.leaderchange.LeaderRegencyPropose) LCMessage(bftsmart.tom.leaderchange.LCMessage) LeaderRegency(bftsmart.tom.leaderchange.LeaderRegency) IOException(java.io.IOException) EOFException(java.io.EOFException)

Example 3 with LeaderRegencyPropose

use of bftsmart.tom.leaderchange.LeaderRegencyPropose in project bftsmart by blockchain-jd-com.

the class Synchronizer method startSynchronization.

// this method is called when a timeout occurs or when a STOP message is
// recevied
private synchronized void startSynchronization(LeaderRegencyPropose regencyPropose) {
    LOGGER.info("(Synchronizer.startSynchronization) [{}] -> I am proc {}, initialize synchr phase", this.execManager.getTOMLayer().getRealName(), controller.getStaticConf().getProcessId());
    // Ask to start the synchronizations phase if enough messages have been received
    // already
    final int proposedRegencyId = regencyPropose.getRegency().getId();
    // 如果此时已经处于选举进程,则不作后续处理;
    if (!lcManager.isInProgress()) {
        // 对非领导者而言,如果请求是有当前执政期的领导者节点主动触发的,并计入自己的一票;
        LeaderRegency currentRegency = lcManager.getCurrentRegency();
        if ((!tom.isLeader()) && regencyPropose.getSender() == currentRegency.getLeaderId() && regencyPropose.getRegency().getId() == currentRegency.getId() + 1) {
            // 这是来自当前执政期领导者的主动选举提议;
            // 进一步校验视图的一致性;
            // 基于当前视图预测下一个执政期(即:当前执政期Id + 1),校验预测结果与来自远程的领导者的提议是否一致;
            // 如果一致,则直接投赞成票,并主动发出 STOP_APPEND 消息;
            View currentView = controller.getCurrentView();
            LeaderRegencyPropose nextRegencyPropose = LeaderRegencyPropose.chooseFromView(currentRegency.getId() + 1, currentView, this.getCurrentId());
            if (regencyPropose.isViewEquals(currentView) && nextRegencyPropose.getRegency().getLeaderId() == regencyPropose.getRegency().getLeaderId()) {
                lcManager.addStop(nextRegencyPropose);
                // 发送 STOP_APPEND 消息;
                sendSTOP_APPEND(nextRegencyPropose);
            }
        }
        if (lcManager.isUpToBeginQuorum(proposedRegencyId)) {
            beginElection(regencyPropose);
        }
    }
    // Did the synchronization phase really started?
    // LCManager有两种状态:
    // 1: 进入“选举中”状态;
    // 2:在本次“选举周期”下并发地收到其它节点的 STOPDATA 消息,完成了本次轮选举;
    ElectionResult electionResult = lcManager.generateQuorumElectionResult(proposedRegencyId);
    if (lcManager.isInProgress(proposedRegencyId) && electionResult != null) {
        commitElection(proposedRegencyId);
    }
// End of: if (canSendStopData && lcManager.getNextReg() >
// lcManager.getLastReg());
}
Also used : LeaderRegencyPropose(bftsmart.tom.leaderchange.LeaderRegencyPropose) ElectionResult(bftsmart.tom.leaderchange.ElectionResult) LeaderRegency(bftsmart.tom.leaderchange.LeaderRegency) View(bftsmart.reconfiguration.views.View)

Example 4 with LeaderRegencyPropose

use of bftsmart.tom.leaderchange.LeaderRegencyPropose in project bftsmart by blockchain-jd-com.

the class Synchronizer method beginElection.

/**
 * 由于收到其它节点报告的 STOP 消息数量达到了满足开始选举的数量条件,调用此方法将开始一轮新的选举;
 *
 * <p>
 *
 * 1. 调用此方法时,如果当前节点尚未开启新选举,则此方法将开启新一轮选举,并向其它节点广播 STOP / STOP_APPEND 消息;<br>
 * 1.1. 如果开启选举的提议( {@link LeaderRegencyPropose} )来自当前节点,则向其它节点广播 STOP 消息; <br>
 * 1.2. 如果开启选举的提议( {@link LeaderRegencyPropose} )来自其它节点,则向其它节点广播 STOP_APPEND 消息;
 * <p>
 *
 * 2. 调用此方法时,如果当前节点已经开启新选举,则不做任何操作;
 */
private void beginElection(LeaderRegencyPropose regencyPropose) {
    if (!lcManager.tryBeginElection(regencyPropose.getRegency())) {
        return;
    }
    final boolean FROM_REMOTE = regencyPropose.getSender() != getCurrentId();
    final int PROPOSED_NEXT_REGENCY_ID = regencyPropose.getRegency().getId();
    heartBeatTimer.stopAll();
    requestsTimer.stopTimer();
    this.getLCManager().setLcTimestampStatePair(new LCTimestampStatePair(System.currentTimeMillis(), LCState.LC_SELECTING));
    // 加入当前节点的领导者执政期提议;
    // store information about message I am going to send
    lcManager.addStop(regencyPropose);
    // 对于已经收到满足f+1条件stop的情形,本身会发送stop_append, 定时器停止,不会再触发超时,此时需要把自己的投票
    LeaderRegencyPropose leaderRegencyPropose = LeaderRegencyPropose.copy(regencyPropose.getRegency().getLeaderId(), regencyPropose.getRegency().getId(), this.controller.getCurrentView().getId(), this.controller.getCurrentView().getProcesses(), getCurrentId());
    lcManager.addStop(leaderRegencyPropose);
    // Get requests that timed out and the requests received in STOP messages
    // and add those STOPed requests to the client manager
    addSTOPedRequestsToClientManager();
    try {
        // serialize conent to send in the STOP message
        byte[] payload = makeTomMessageReplyBatch(PROPOSED_NEXT_REGENCY_ID);
        if (FROM_REMOTE) {
            View currentView = this.controller.getCurrentView();
            if (!regencyPropose.isViewEquals(currentView)) {
                throw new IllegalStateException(String.format("The view of regency propose from node[%s] is not equal the the current view of node[%s]!", regencyPropose.getSender(), controller.getStaticConf().getProcessId()));
            }
            LCMessage msgSTOP_APPEND = LCMessage.createSTOP_APPEND(this.controller.getStaticConf().getProcessId(), regencyPropose.getRegency(), currentView, payload);
            // make replica re-transmit the stop
            requestsTimer.setSTOP(PROPOSED_NEXT_REGENCY_ID, msgSTOP_APPEND);
            // message
            // until a
            // new
            // regency is installed
            communication.send(this.controller.getCurrentViewOtherAcceptors(), msgSTOP_APPEND);
        } else {
            LCMessage msgSTOP = LCMessage.createSTOP(this.controller.getStaticConf().getProcessId(), regencyPropose.getRegency(), this.controller.getCurrentView(), payload);
            // TODO: ???
            // make replica re-transmit the stop message
            requestsTimer.setSTOP(PROPOSED_NEXT_REGENCY_ID, msgSTOP);
            // until a
            // new
            // regency is installed
            communication.send(this.controller.getCurrentViewOtherAcceptors(), msgSTOP);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
        java.util.logging.Logger.getLogger(TOMLayer.class.getName()).log(Level.SEVERE, null, ex);
    }
}
Also used : LeaderRegencyPropose(bftsmart.tom.leaderchange.LeaderRegencyPropose) LCMessage(bftsmart.tom.leaderchange.LCMessage) LCTimestampStatePair(bftsmart.tom.leaderchange.LCTimestampStatePair) View(bftsmart.reconfiguration.views.View) IOException(java.io.IOException) EOFException(java.io.EOFException)

Example 5 with LeaderRegencyPropose

use of bftsmart.tom.leaderchange.LeaderRegencyPropose in project bftsmart by blockchain-jd-com.

the class Synchronizer method maxRegencyOutOfContextSTOPs.

// get stops count with max regency from out of context
// 
// 
private int maxRegencyOutOfContextSTOPs(int regency) {
    Map<Integer, Map<Integer, LeaderRegencyPropose>> stops = new ConcurrentHashMap<Integer, Map<Integer, LeaderRegencyPropose>>();
    for (LCMessage m : outOfContextLC) {
        if (m.getType() == LCType.STOP && m.getReg() == regency) {
            LeaderRegencyPropose propose = LeaderRegencyPropose.copy(m.getLeader(), m.getReg(), m.getViewId(), m.getViewProcessIds(), m.getSender());
            Map<Integer, LeaderRegencyPropose> peerProposes = stops.get(regency);
            if (peerProposes == null) {
                peerProposes = new ConcurrentHashMap<Integer, LeaderRegencyPropose>();
                stops.put(regency, peerProposes);
            }
            peerProposes.put(m.getSender(), propose);
        }
    }
    return stops.get(regency) == null ? 0 : stops.get(regency).size();
}
Also used : LeaderRegencyPropose(bftsmart.tom.leaderchange.LeaderRegencyPropose) LCMessage(bftsmart.tom.leaderchange.LCMessage) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

LeaderRegencyPropose (bftsmart.tom.leaderchange.LeaderRegencyPropose)5 LCMessage (bftsmart.tom.leaderchange.LCMessage)4 View (bftsmart.reconfiguration.views.View)2 TOMMessage (bftsmart.tom.core.messages.TOMMessage)2 LeaderRegency (bftsmart.tom.leaderchange.LeaderRegency)2 EOFException (java.io.EOFException)2 IOException (java.io.IOException)2 ElectionResult (bftsmart.tom.leaderchange.ElectionResult)1 LCTimestampStatePair (bftsmart.tom.leaderchange.LCTimestampStatePair)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1