use of bftsmart.reconfiguration.ReconfigureReply in project aware by bergerch.
the class ServiceProxy method invoke.
/**
* This method sends a request to the replicas, and returns the related reply.
* If the servers take more than invokeTimeout seconds the method returns null.
* This method is thread-safe.
*
* @param request Request to be sent
* @param reqType ORDERED_REQUEST/UNORDERED_REQUEST/UNORDERED_HASHED_REQUEST for normal requests, and RECONFIG for
* reconfiguration requests.
*
* @return The reply from the replicas related to request
*/
public byte[] invoke(byte[] request, TOMMessageType reqType) {
try {
canSendLock.lock();
// Clean all statefull data to prepare for receiving next replies
Arrays.fill(replies, null);
receivedReplies = 0;
response = null;
replyQuorum = getReplyQuorum();
// Send the request to the replicas, and get its ID
reqId = generateRequestId(reqType);
operationId = generateOperationId();
requestType = reqType;
replyServer = -1;
hashResponseController = null;
if (requestType == TOMMessageType.UNORDERED_HASHED_REQUEST) {
replyServer = getRandomlyServerId();
logger.debug("[" + this.getClass().getName() + "] replyServerId(" + replyServer + ") " + "pos(" + getViewManager().getCurrentViewPos(replyServer) + ")");
hashResponseController = new HashResponseController(getViewManager().getCurrentViewPos(replyServer), getViewManager().getCurrentViewProcesses().length);
TOMMessage sm = new TOMMessage(getProcessId(), getSession(), reqId, operationId, request, getViewManager().getCurrentViewId(), requestType);
sm.setReplyServer(replyServer);
TOMulticast(sm);
} else {
TOMulticast(request, reqId, operationId, reqType);
}
logger.debug("Sending request (" + reqType + ") with reqId=" + reqId);
logger.debug("Expected number of matching replies: " + replyQuorum);
// by the client side communication system
try {
if (reqType == TOMMessageType.UNORDERED_HASHED_REQUEST) {
if (!this.sm.tryAcquire(invokeUnorderedHashedTimeout, TimeUnit.SECONDS)) {
logger.info("######## UNORDERED HASHED REQUEST TIMOUT ########");
canSendLock.unlock();
return invoke(request, TOMMessageType.ORDERED_REQUEST);
}
} else {
if (!this.sm.tryAcquire(invokeTimeout, TimeUnit.SECONDS)) {
logger.info("###################TIMEOUT#######################");
logger.info("Reply timeout for reqId=" + reqId + ", Replies received: " + receivedReplies);
canSendLock.unlock();
return null;
}
}
} catch (InterruptedException ex) {
logger.error("Problem aquiring semaphore", ex);
}
logger.debug("Response extracted = " + response);
byte[] ret = null;
if (response == null) {
// the response can be null if n-f replies are received but there isn't
// a replyQuorum of matching replies
logger.debug("Received n-f replies and no response could be extracted.");
canSendLock.unlock();
if (reqType == TOMMessageType.UNORDERED_REQUEST || reqType == TOMMessageType.UNORDERED_HASHED_REQUEST) {
// invoke the operation again, whitout the read-only flag
logger.debug("###################RETRY#######################");
return invokeOrdered(request);
} else {
throw new RuntimeException("Received n-f replies without f+1 of them matching.");
}
} else {
// ******* EDUARDO BEGIN **************//
if (reqType == TOMMessageType.ORDERED_REQUEST) {
// Reply to a normal request!
if (response.getViewID() == getViewManager().getCurrentViewId()) {
// return the response
ret = response.getContent();
} else {
// if(response.getViewID() > getViewManager().getCurrentViewId())
// updated view received
reconfigureTo((View) TOMUtil.getObject(response.getContent()));
canSendLock.unlock();
return invoke(request, reqType);
}
} else if (reqType == TOMMessageType.UNORDERED_REQUEST || reqType == TOMMessageType.UNORDERED_HASHED_REQUEST) {
if (response.getViewID() == getViewManager().getCurrentViewId()) {
// return the response
ret = response.getContent();
} else {
canSendLock.unlock();
return invoke(request, TOMMessageType.ORDERED_REQUEST);
}
} else {
if (response.getViewID() > getViewManager().getCurrentViewId()) {
// Reply to a reconfigure request!
logger.debug("Reconfiguration request' reply received!");
Object r = TOMUtil.getObject(response.getContent());
if (r instanceof View) {
// did not executed the request because it is using an outdated view
reconfigureTo((View) r);
canSendLock.unlock();
return invoke(request, reqType);
} else if (r instanceof ReconfigureReply) {
// reconfiguration executed!
reconfigureTo(((ReconfigureReply) r).getView());
ret = response.getContent();
} else {
logger.debug("Unknown response type");
}
} else {
logger.debug("Unexpected execution flow");
}
}
}
return ret;
} finally {
// always release lock
if (canSendLock.isHeldByCurrentThread())
canSendLock.unlock();
}
}
use of bftsmart.reconfiguration.ReconfigureReply in project jdchain-core by blockchain-jd-com.
the class BftsmartConsensusManageService method addNode.
@Override
public AsyncFuture<ConsensusView> addNode(Replica replica) {
BftsmartServiceProxyPool serviceProxyPool = getServiceProxyPool();
BftsmartReplica bftsmartReplica = (BftsmartReplica) replica;
CompletableAsyncFuture<ConsensusView> asyncFuture = new CompletableAsyncFuture<>();
AsynchServiceProxy serviceProxy = null;
try {
serviceProxy = serviceProxyPool.borrowObject();
Reconfiguration reconfiguration = new Reconfiguration(serviceProxy.getProcessId(), serviceProxy);
reconfiguration.addServer(bftsmartReplica.getId(), bftsmartReplica.getNetworkAddress());
ReconfigureReply reply = reconfiguration.execute();
asyncFuture.complete(new BftsmartView(reply.getView()));
} catch (Exception e) {
asyncFuture.error(e);
} finally {
if (serviceProxy != null) {
serviceProxyPool.returnObject(serviceProxy);
}
}
return asyncFuture;
}
use of bftsmart.reconfiguration.ReconfigureReply in project jdchain-core by blockchain-jd-com.
the class ParticipantManagerService4Bft method updateView.
// 通知原有的共识网络更新共识的视图ID
private View updateView(ParticipantNode node, NetworkAddress networkAddress, SSLSecurity security, ManagementController.ParticipantUpdateType participantUpdateType, Properties systemConfig, int viewId, List<NodeSettings> origConsensusNodes) {
LOGGER.info("ManagementController start updateView operation!");
TransactionRequest reconfigRequest = null;
try {
ServiceProxy peerProxy = createPeerProxy(systemConfig, viewId, origConsensusNodes, security);
Reconfiguration reconfiguration = new Reconfiguration(peerProxy.getProcessId(), peerProxy);
if (participantUpdateType == ManagementController.ParticipantUpdateType.ACTIVE) {
// addServer的第一个参数指待加入共识的新参与方的编号
reconfiguration.addServer(node.getId(), networkAddress);
reconfigRequest = prepareReconfigTx("active");
} else if (participantUpdateType == ManagementController.ParticipantUpdateType.DEACTIVE) {
// 参数为待移除共识节点的id
reconfiguration.removeServer(node.getId());
reconfigRequest = prepareReconfigTx("deactive");
} else if (participantUpdateType == ManagementController.ParticipantUpdateType.UPDATE) {
// 共识参数修改,先移除后添加
reconfiguration.removeServer(node.getId());
reconfiguration.addServer(node.getId(), networkAddress);
reconfigRequest = prepareReconfigTx("update");
} else {
throw new IllegalArgumentException("op type error!");
}
// 把交易作为reconfig操作的扩展信息携带,目的是为了让该操作上链,便于后续跟踪;
reconfiguration.addExtendInfo(BinaryProtocol.encode(reconfigRequest, TransactionRequest.class));
// 执行更新目标共识网络的视图ID
ReconfigureReply reconfigureReply = reconfiguration.execute();
peerProxy.close();
// 返回新视图
return reconfigureReply.getView();
} catch (Exception e) {
throw new ViewUpdateException("view update fail exception!", e);
}
}
use of bftsmart.reconfiguration.ReconfigureReply in project aware by bergerch.
the class ServiceReplica method joinMsgReceived.
/**
* @deprecated
*/
public void joinMsgReceived(VMMessage msg) {
ReconfigureReply r = msg.getReply();
if (r.getView().isMember(id)) {
this.SVController.processJoinResult(r);
// initiaze the TOM layer
initTOMLayer();
cs.updateServersConnections();
this.cs.joinViewReceived();
waitTTPJoinMsgLock.lock();
canProceed.signalAll();
waitTTPJoinMsgLock.unlock();
}
}
use of bftsmart.reconfiguration.ReconfigureReply in project bftsmart by blockchain-jd-com.
the class ServiceProxy method invoke.
/**
* This method sends a request to the replicas, and returns the related reply.
* If the servers take more than invokeTimeout seconds the method returns null.
* This method is thread-safe.
*
* @param request
* Request to be sent
* @param reqType
* TOM_NORMAL_REQUESTS for service requests, and other for reconfig
* requests.
* @return The reply from the replicas related to request
*/
public byte[] invoke(byte[] request, TOMMessageType reqType) {
canSendLock.lock();
try {
// Clean all statefull data to prepare for receiving next replies
Arrays.fill(replies, null);
receivedReplies = 0;
response = null;
replyQuorum = getReplyQuorum();
// Send the request to the replicas, and get its ID
reqId = generateRequestId(reqType);
operationId = generateOperationId();
requestType = reqType;
replyServer = -1;
hashResponseController = null;
LOGGER.info("Before Sending request {} with reqId {}, operationId {}, clientId={}", reqType, reqId, operationId, getProcessId());
if (requestType == TOMMessageType.UNORDERED_HASHED_REQUEST) {
replyServer = getRandomlyServerId();
LOGGER.debug("[{}] replyServerId {} pos at {}", this.getClass().getName(), replyServer, getViewManager().getCurrentViewPos(replyServer));
hashResponseController = new HashResponseController(getViewManager().getCurrentViewPos(replyServer), getViewManager().getCurrentViewProcesses().length);
TOMMessage sm = new TOMMessage(getProcessId(), getSession(), reqId, operationId, request, null, getViewManager().getCurrentViewId(), requestType);
sm.setReplyServer(replyServer);
TOMulticast(sm);
} else {
TOMulticast(request, reqId, operationId, reqType);
}
LOGGER.info("After Sending request {} with reqId {}, operationId {}, clientId={}", reqType, reqId, operationId, getProcessId());
LOGGER.debug("Expected number of matching replies: {}", replyQuorum);
// by the client side communication system
try {
if (reqType == TOMMessageType.UNORDERED_HASHED_REQUEST) {
if (!this.sm.tryAcquire(invokeUnorderedHashedTimeout, TimeUnit.SECONDS)) {
LOGGER.debug("######## UNORDERED HASHED REQUEST TIMOUT ########");
return invoke(request, TOMMessageType.ORDERED_REQUEST);
}
} else {
if (!this.sm.tryAcquire(invokeTimeout, TimeUnit.SECONDS)) {
LOGGER.error("###################TIMEOUT#######################");
LOGGER.error("Reply timeout for reqId is {}", reqId);
LOGGER.error("Process id {} // req id {} // TIMEOUT // ", getProcessId(), reqId);
LOGGER.error("Replies received: {}", receivedReplies);
LOGGER.error("Replies quorum: {}", replyQuorum);
checkReplyNum(reqType, receivedReplies, replyQuorum);
return null;
}
}
} catch (ViewObsoleteException voe) {
throw voe;
} catch (Exception ex) {
LOGGER.error("exception", ex);
}
LOGGER.debug("Response extracted {}", response);
byte[] ret = null;
if (response == null) {
// the response can be null if n-f replies are received but there isn't
// a replyQuorum of matching replies
LOGGER.error("Received n-f replies and no response could be extracted. request.length = {}, type = {} !", request.length, reqType);
throw new RuntimeException("Received n-f replies without f+1 of them matching.");
} else {
// ******* EDUARDO BEGIN **************//
if (reqType == TOMMessageType.ORDERED_REQUEST) {
// Reply to a normal request!
if (response.getViewID() == getViewManager().getCurrentViewId()) {
// return the response
ret = response.getContent();
} else {
// if(response.getViewID() > getViewManager().getCurrentViewId())
// Request with backward viewid, still up chain by server node, but proxy client need update local view according to response view
LOGGER.warn("Service proxy view id little than service replica view id, will update local view!");
if (response.getViewContent() != null) {
reconfigureTo((View) TOMUtil.getObject(response.getViewContent()));
}
ret = response.getContent();
// LOGGER.warn("Service proxy view id little than service replica view id, will re invoke request!");
// return invoke(request, reqType);
}
} else if (reqType == TOMMessageType.UNORDERED_REQUEST || reqType == TOMMessageType.UNORDERED_HASHED_REQUEST) {
// return the response
ret = response.getContent();
if (response.getViewID() > getViewManager().getCurrentViewId()) {
Object r = TOMUtil.getObject(response.getContent());
if (r instanceof View) {
reconfigureTo((View) r);
return invoke(request, reqType);
}
}
} else {
if (response.getViewID() > getViewManager().getCurrentViewId()) {
// Reply to a reconfigure request!
LOGGER.debug("Reconfiguration request' reply received!");
Object r = TOMUtil.getObject(response.getContent());
if (r instanceof View) {
// did not executed the request because it is using an outdated view
reconfigureTo((View) r);
return invoke(request, reqType);
} else if (r instanceof ReconfigureReply) {
// reconfiguration executed!
reconfigureTo(((ReconfigureReply) r).getView());
ret = response.getContent();
} else {
LOGGER.error("Unknown response type");
}
} else {
LOGGER.error("Unexpected execution flow");
}
}
}
return ret;
} catch (Exception e) {
LOGGER.error("[ServiceProxy] invoke exception occur!", e);
throw e;
} finally {
canSendLock.unlock();
}
}
Aggregations