use of bftsmart.consensus.messages.ConsensusMessage in project aware by bergerch.
the class CSTState method getCertifiedDecision.
/**
* Retrieves the certified decision for the last consensus present in this object
* @param controller
* @return The certified decision for the last consensus present in this object
*/
@Override
public CertifiedDecision getCertifiedDecision(ServerViewController controller) {
CommandsInfo ci = getMessageBatch(getLastCID());
if (ci != null && ci.msgCtx[0].getProof() != null) {
// do I have a proof for the consensus?
Set<ConsensusMessage> proof = ci.msgCtx[0].getProof();
LinkedList<TOMMessage> requests = new LinkedList<>();
// Recreate all TOMMessages ordered in the consensus
for (int i = 0; i < ci.commands.length; i++) {
requests.add(ci.msgCtx[i].recreateTOMMessage(ci.commands[i]));
}
// Serialize the TOMMessages to re-create the proposed value
BatchBuilder bb = new BatchBuilder(0);
byte[] value = bb.makeBatch(requests, ci.msgCtx[0].getNumOfNonces(), ci.msgCtx[0].getSeed(), ci.msgCtx[0].getTimestamp(), controller.getStaticConf().getUseSignatures() == 1);
// Assemble and return the certified decision
return new CertifiedDecision(pid, getLastCID(), value, proof);
} else
// there was no proof for the consensus
return null;
}
use of bftsmart.consensus.messages.ConsensusMessage in project aware by bergerch.
the class StateManager method proofIsConsistent.
// check if the consensus messages are consistent without checking the mac/signatures
// if it is consistent, it returns the respective consensus ID; otherwise, returns -1
private int proofIsConsistent(Set<ConsensusMessage> proof) {
int id = -1;
byte[] value = null;
for (ConsensusMessage cm : proof) {
if (id == -1)
id = cm.getNumber();
if (value == null)
value = cm.getValue();
if (id != cm.getNumber() || !Arrays.equals(value, cm.getValue())) {
// they are not consistent, so the proof is invalid
return -1;
}
}
// if the values are still these, this means the proof is empty, thus is invalid
if (id == -1 || value == null)
return -1;
return id;
}
use of bftsmart.consensus.messages.ConsensusMessage in project aware by bergerch.
the class Acceptor method computeWrite.
/**
* Computes WRITE values according to Byzantine consensus specification
* values received).
*
* @param cid Consensus ID of the received message
* @param epoch Epoch of the receives message
* @param value Value sent in the message
*/
private void computeWrite(int cid, Epoch epoch, byte[] value) {
int writeAccepted = epoch.countWrite(value);
logger.debug("I have " + writeAccepted + " WRITEs for " + cid + "," + epoch.getTimestamp());
if (writeAccepted > controller.getQuorum() && Arrays.equals(value, epoch.propValueHash)) {
if (!epoch.isAcceptSent()) {
logger.debug("Sending WRITE for " + cid);
/**
** LEADER CHANGE CODE! *****
*/
logger.debug("Setting consensus " + cid + " QuorumWrite tiemstamp to " + epoch.getConsensus().getEts() + " and value " + Arrays.toString(value));
epoch.getConsensus().setQuorumWrites(value);
if (epoch.getConsensus().getDecision().firstMessageProposed != null) {
epoch.getConsensus().getDecision().firstMessageProposed.acceptSentTime = System.nanoTime();
}
ConsensusMessage cm = epoch.fetchAccept();
int[] targets = this.controller.getCurrentViewAcceptors();
epoch.acceptSent();
if (Arrays.equals(cm.getValue(), value)) {
// make sure the ACCEPT message generated upon receiving the PROPOSE message
// still matches the value that ended up being written...
logger.debug("Speculative ACCEPT message for consensus {} matches the written value, sending it to the other replicas", cid);
communication.getServersConn().send(targets, cm, true);
} else {
// ... and if not, create the ACCEPT message again (with the correct value), and send it
ConsensusMessage correctAccept = factory.createAccept(cid, epoch.getTimestamp(), value);
proofExecutor.submit(() -> {
// Create a cryptographic proof for this ACCEPT message
logger.debug("Creating cryptographic proof for the correct ACCEPT message from consensus " + cid);
insertProof(correctAccept, epoch.deserializedPropValue);
communication.getServersConn().send(targets, correctAccept, true);
});
}
}
} else if (!epoch.isAcceptCreated()) {
// start creating the ACCEPT message and its respective proof ASAP, to increase performance.
// since this is done after a PROPOSE message is received, this is done speculatively, hence
// the value must be verified before sending the ACCEPT message to the other replicas
ConsensusMessage cm = factory.createAccept(cid, epoch.getTimestamp(), value);
epoch.acceptCreated();
proofExecutor.submit(() -> {
// Create a cryptographic proof for this ACCEPT message
logger.debug("Creating cryptographic proof for speculative ACCEPT message from consensus " + cid);
insertProof(cm, epoch.deserializedPropValue);
epoch.setAcceptMsg(cm);
});
}
}
use of bftsmart.consensus.messages.ConsensusMessage in project aware by bergerch.
the class ExecutionManager method processOutOfContextPropose.
public void processOutOfContextPropose(Consensus consensus) {
outOfContextLock.lock();
/**
***** BEGIN OUTOFCONTEXT CRITICAL SECTION ******
*/
ConsensusMessage prop = outOfContextProposes.remove(consensus.getId());
if (prop != null) {
logger.debug("[Consensus " + consensus.getId() + "] Processing out of context propose");
acceptor.processMessage(prop);
}
/**
***** END OUTOFCONTEXT CRITICAL SECTION ******
*/
outOfContextLock.unlock();
}
use of bftsmart.consensus.messages.ConsensusMessage in project aware by bergerch.
the class Synchronizer method processSTOPDATA.
// Processes STOPDATA messages that were not process upon reception, because they were
// ahead of the replica's expected regency
private void processSTOPDATA(LCMessage msg, int regency) {
// TODO: It is necessary to verify the proof of the last decided consensus and the signature of the state of the current consensus!
CertifiedDecision lastData = null;
SignedObject signedCollect = null;
int last = -1;
byte[] lastValue = null;
Set<ConsensusMessage> proof = null;
ByteArrayInputStream bis;
ObjectInputStream ois;
try {
// deserialize the content of the message
bis = new ByteArrayInputStream(msg.getPayload());
ois = new ObjectInputStream(bis);
if (ois.readBoolean()) {
// content of the last decided cid
last = ois.readInt();
lastValue = (byte[]) ois.readObject();
proof = (Set<ConsensusMessage>) ois.readObject();
// TODO: Proof is missing!
}
lastData = new CertifiedDecision(msg.getSender(), last, lastValue, proof);
lcManager.addLastCID(regency, lastData);
signedCollect = (SignedObject) ois.readObject();
ois.close();
bis.close();
lcManager.addCollect(regency, signedCollect);
int bizantineQuorum = (controller.getCurrentViewN() + controller.getCurrentViewF()) / 2;
int cftQuorum = (controller.getCurrentViewN()) / 2;
// Did I already got messages from a Byzantine/Crash quorum,
// related to the last cid as well as for the current?
boolean conditionBFT = (controller.getStaticConf().isBFT() && lcManager.getLastCIDsSize(regency) > bizantineQuorum && lcManager.getCollectsSize(regency) > bizantineQuorum);
boolean conditionCFT = (lcManager.getLastCIDsSize(regency) > cftQuorum && lcManager.getCollectsSize(regency) > cftQuorum);
if (conditionBFT || conditionCFT) {
catch_up(regency);
}
} catch (IOException | ClassNotFoundException ex) {
logger.error("Could not deserialize STOPDATA message", ex);
}
}
Aggregations