refactor: sdk for consensus algorithm

This commit is contained in:
汪旭鑫 2022-02-15 14:44:15 +08:00
parent fc7512f50f
commit e2df294d65
14 changed files with 1426 additions and 1397 deletions

View File

@ -34,6 +34,7 @@ dependencies {
implementation project(":cm") implementation project(":cm")
implementation project(":mockjava") implementation project(":mockjava")
implementation project(":front-base") implementation project(":front-base")
implementation project(":consistency-sdk")
implementation 'io.prometheus:simpleclient_httpserver:0.12.0' implementation 'io.prometheus:simpleclient_httpserver:0.12.0'
implementation 'org.knowhowlab.osgi:sigar:1.6.5_01' implementation 'org.knowhowlab.osgi:sigar:1.6.5_01'
implementation 'io.grpc:grpc-all:1.43.1' implementation 'io.grpc:grpc-all:1.43.1'

View File

@ -26,6 +26,7 @@ import org.bdware.sc.db.CMTables;
import org.bdware.sc.db.KeyValueDBUtil; import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.db.MultiIndexTimeRocksDBUtil; import org.bdware.sc.db.MultiIndexTimeRocksDBUtil;
import org.bdware.sc.util.ExceptionUtil; import org.bdware.sc.util.ExceptionUtil;
import org.bdware.sdk.consistency.ConsistencyPluginManager;
import org.bdware.server.action.FileActions; import org.bdware.server.action.FileActions;
import org.bdware.server.doip.ContractRepositoryMain; import org.bdware.server.doip.ContractRepositoryMain;
import org.bdware.server.http.CMHttpHandler; import org.bdware.server.http.CMHttpHandler;
@ -251,6 +252,7 @@ public class CMHttpServer {
* port: http & websocket port port+1: tcp port port+2: doip port port+3: prometheus * port: http & websocket port port+1: tcp port port+2: doip port port+3: prometheus
*/ */
private void start() { private void start() {
ConsistencyPluginManager.setContext(new SDKContext());
// EpollEventLoopGroup // EpollEventLoopGroup
// EpollServerSocketChannel // EpollServerSocketChannel
// ContractManager.reconnectPort = (port - 18000) * 30 + 1630; // ContractManager.reconnectPort = (port - 18000) * 30 + 1630;

View File

@ -0,0 +1,113 @@
package org.bdware.server;
import org.bdware.sc.ContractManager;
import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.units.RecoverFlag;
import org.bdware.sc.units.RequestCache;
import org.bdware.sdk.consistency.api.context.*;
import org.bdware.server.action.CMActions;
import org.bdware.server.action.SyncResult;
import org.bdware.server.action.p2p.MasterServerRecoverMechAction;
import org.bdware.server.action.p2p.MasterServerTCPAction;
import org.bdware.server.trustedmodel.ResultCollector;
import org.bdware.units.NetworkManager;
import org.zz.gmhelper.SM2KeyPair;
import java.util.Map;
public class SDKContext implements ISDKContext {
IMasterServerTCPAction masterServerTCPActionProxy = new MasterServerTCPActionProxy();
INetworkManager networkManagerProxy = new NetworkManagerProxy();
ICMActions cmActionsProxy = new CMActionsProxy();
IMasterServerRecoverMechAction masterServerRecoverMechActionProxy = new MasterServerRecoverMechActionProxy();
IGlobalConf globalConfProxy = new GlobalProxy();
@Override
public IMasterServerTCPAction getMasterServerTCPAction() {
return masterServerTCPActionProxy;
}
@Override
public INetworkManager getNetworkManager() {
return networkManagerProxy;
}
@Override
public ICMActions getCMActions() {
return cmActionsProxy;
}
@Override
public IMasterServerRecoverMechAction getMasterServerRecoverMechAction() {
return masterServerRecoverMechActionProxy;
}
@Override
public IGlobalConf getGlobalConf() {
return globalConfProxy;
}
public static class MasterServerTCPActionProxy implements IMasterServerTCPAction {
@Override
public SyncResult getSync() {
return MasterServerTCPAction.sync;
}
@Override
public Map<String, RequestCache> getReqCache() {
return MasterServerTCPAction.requestCache;
}
}
public static class NetworkManagerProxy implements INetworkManager {
@Override
public void sendToAgent(String pubkey, String content) {
NetworkManager.instance.sendToAgent(pubkey, content);
}
@Override
public boolean hasAgentConnection(String pubkey) {
return NetworkManager.instance.hasAgentConnection(pubkey);
}
@Override
public ResultCallback createResultCallback(String requestID, ResultCallback rc, int count) {
return new ResultCollector(requestID, rc, count);
}
}
public static class CMActionsProxy implements ICMActions {
@Override
public ContractManager getManager() {
return CMActions.manager;
}
}
public static class MasterServerRecoverMechActionProxy implements IMasterServerRecoverMechAction {
@Override
public Map<String, Map<String, RecoverFlag>> getRecoverStatusMap() {
return MasterServerRecoverMechAction.recoverStatus;
}
@Override
public void restartContractFromCommonMode(String nodeID, String contractID) {
MasterServerRecoverMechAction.restartContractFromCommonMode(nodeID, contractID);
}
}
public static class GlobalProxy implements IGlobalConf {
@Override
public String getNodeID() {
return GlobalConf.getNodeID();
}
@Override
public SM2KeyPair getKeyPair() {
return GlobalConf.instance.keyPair;
}
}
}

View File

@ -19,8 +19,6 @@ import org.bdware.server.GlobalConf;
import org.bdware.server.action.Action; import org.bdware.server.action.Action;
import org.bdware.server.action.CMActions; import org.bdware.server.action.CMActions;
import org.bdware.server.action.RequestToMaster; import org.bdware.server.action.RequestToMaster;
import org.bdware.server.executor.consistency.PBFTExecutor;
import org.bdware.server.executor.consistency.RequestAllExecutor;
import org.bdware.server.tcp.TCPClientFrameHandler; import org.bdware.server.tcp.TCPClientFrameHandler;
import org.bdware.server.trustedmodel.AgentManager; import org.bdware.server.trustedmodel.AgentManager;
import org.bdware.server.trustedmodel.ContractUnitStatus; import org.bdware.server.trustedmodel.ContractUnitStatus;
@ -344,20 +342,9 @@ public class MasterClientRecoverMechAction {
ContractMeta meta = CMActions.manager.statusRecorder.getContractMeta(cei.getContractID()); ContractMeta meta = CMActions.manager.statusRecorder.getContractMeta(cei.getContractID());
meta.setContractExecutor( meta.setContractExecutor(
MasterClientTCPAction.createContractExecutor(meta.contract, contractID, cei.getMasterNode(), cei.getMembers())); MasterClientTCPAction.createContractExecutor(meta.contract, contractID, cei.getMasterNode(), cei.getMembers()));
switch (meta.contract.getType()) { Map<String, Object> args = new HashMap<>();
case RequestAllResponseFirst: args.put("ceiLastExeSeq", cei.getLastExeSeq());
case RequestAllResponseHalf: meta.contractExecutor.onRecover(args);
case RequestAllResponseAll:
((RequestAllExecutor) meta.contractExecutor).setSeq(cei.getLastExeSeq() + 1);
break;
case PBFT:
((PBFTExecutor) meta.contractExecutor).setSeq(cei.getLastExeSeq() + 1);
break;
case Sharding:
break;
default:
break;
}
// 认为contractID不会重 // 认为contractID不会重
if (client != null if (client != null
&& client.isProcessAlive() && client.isProcessAlive()
@ -619,20 +606,9 @@ public class MasterClientRecoverMechAction {
} }
CMActions.manager.multiContractRecorder.updateValue(cei); CMActions.manager.multiContractRecorder.updateValue(cei);
ContractMeta meta = CMActions.manager.statusRecorder.getContractMeta(contractID); ContractMeta meta = CMActions.manager.statusRecorder.getContractMeta(contractID);
switch (meta.contract.getType()) { Map<String, Object> args = new HashMap<>();
case RequestAllResponseFirst: args.put("ceiLastExeSeq", cei.getLastExeSeq());
case RequestAllResponseHalf: meta.contractExecutor.onRecover(args);
case RequestAllResponseAll:
((RequestAllExecutor) meta.contractExecutor).setSeq(cei.getLastExeSeq() + 1);
break;
case PBFT:
((PBFTExecutor) meta.contractExecutor).setSeq(cei.getLastExeSeq() + 1);
break;
case Sharding:
break;
default:
break;
}
boolean flag = checkAndRestart(cei); // if need,restart the contract process boolean flag = checkAndRestart(cei); // if need,restart the contract process
if (!flag) { if (!flag) {

View File

@ -15,18 +15,12 @@ import org.bdware.sc.db.KeyValueDBUtil;
import org.bdware.sc.units.MultiContractMeta; import org.bdware.sc.units.MultiContractMeta;
import org.bdware.sc.units.PubKeyNode; import org.bdware.sc.units.PubKeyNode;
import org.bdware.sc.util.JsonUtil; import org.bdware.sc.util.JsonUtil;
import org.bdware.sdk.consistency.ConsistencyPluginManager;
import org.bdware.server.GlobalConf; import org.bdware.server.GlobalConf;
import org.bdware.server.action.*; import org.bdware.server.action.*;
import org.bdware.server.executor.consistency.PBFTExecutor;
import org.bdware.server.executor.consistency.RequestAllExecutor;
import org.bdware.server.executor.unconsistency.MultiPointCooperationExecutor;
import org.bdware.server.executor.unconsistency.RequestOnceExecutor;
import org.bdware.server.executor.unconsistency.ResponseOnceExecutor;
import org.bdware.server.tcp.PubkeyResultCallback; import org.bdware.server.tcp.PubkeyResultCallback;
import org.bdware.server.trustedmodel.ContractExecutor; import org.bdware.server.trustedmodel.ContractExecutor;
import org.bdware.server.trustedmodel.KillUnitContractInfo; import org.bdware.server.trustedmodel.KillUnitContractInfo;
import org.bdware.server.trustedmodel.SelfAdaptiveShardingExecutor;
import org.bdware.server.trustedmodel.SingleNodeExecutor;
import org.bdware.units.NetworkManager; import org.bdware.units.NetworkManager;
import org.bdware.units.function.ExecutionManager; import org.bdware.units.function.ExecutionManager;
import org.zz.gmhelper.SM2KeyPair; import org.zz.gmhelper.SM2KeyPair;
@ -85,46 +79,12 @@ public class MasterClientTCPAction {
} }
public static ContractExecutor createContractExecutor(Contract contract, String contractID, String masterPubkey, String[] members) { public static ContractExecutor createContractExecutor(Contract contract, String contractID, String masterPubkey, String[] members) {
ContractExecutor executor = null; Map<String, Object> args = new HashMap<>();
int nodeSize = contract.getNumOfCopies(); args.put("contractID", contractID);
switch (contract.getType()) { args.put("nodeSize", contract.getNumOfCopies());
case Sole: args.put("masterPubkey", masterPubkey);
LOGGER.info("Sole contract is not supported in multi-point mode"); args.put("members", members);
return SingleNodeExecutor.instance; return ConsistencyPluginManager.getInstance().createContractExecutor(contract.getType(), args);
case RequestOnce:
executor = new RequestOnceExecutor(contractID);
break;
case ResponseOnce:
executor = new ResponseOnceExecutor(contractID);
break;
case RequestAllResponseFirst:
executor =
new RequestAllExecutor(
ContractExecType.RequestAllResponseFirst, 1, contractID);
break;
case RequestAllResponseHalf:
executor =
new RequestAllExecutor(
ContractExecType.RequestAllResponseHalf,
nodeSize / 2 + 1,
contractID);
break;
case RequestAllResponseAll:
executor =
new RequestAllExecutor(
ContractExecType.RequestAllResponseAll, nodeSize, contractID);
break;
case Sharding:
executor = new MultiPointCooperationExecutor(ContractExecType.Sharding, nodeSize, contractID);
break;
case SelfAdaptiveSharding:
executor = new SelfAdaptiveShardingExecutor(contractID);
break;
case PBFT:
executor = new PBFTExecutor(nodeSize, contractID, masterPubkey, members);
break;
}
return executor;
} }
public static void dealRequests(String contractID) { public static void dealRequests(String contractID) {
@ -460,8 +420,8 @@ public class MasterClientTCPAction {
if (jo.has("contractID") && jo.has("data")) { if (jo.has("contractID") && jo.has("data")) {
String contractID = jo.get("contractID").getAsString(); String contractID = jo.get("contractID").getAsString();
ContractMeta meta = CMActions.manager.statusRecorder.getContractMeta(contractID); ContractMeta meta = CMActions.manager.statusRecorder.getContractMeta(contractID);
if (null != meta && meta.contractExecutor instanceof SelfAdaptiveShardingExecutor) { if (null != meta && meta.contractExecutor != null) {
((SelfAdaptiveShardingExecutor) meta.contractExecutor).execute(jo.get("data").getAsString()); meta.contractExecutor.onDeliverBlock(jo.get("data").getAsString());
} }
} }
} }

View File

@ -16,8 +16,6 @@ import org.bdware.sc.util.JsonUtil;
import org.bdware.server.GlobalConf; import org.bdware.server.GlobalConf;
import org.bdware.server.action.Action; import org.bdware.server.action.Action;
import org.bdware.server.action.CMActions; import org.bdware.server.action.CMActions;
import org.bdware.server.executor.consistency.PBFTExecutor;
import org.bdware.server.executor.consistency.RequestAllExecutor;
import org.bdware.server.trustedmodel.ContractUnitStatus; import org.bdware.server.trustedmodel.ContractUnitStatus;
import org.bdware.units.NetworkManager; import org.bdware.units.NetworkManager;
import org.zz.gmhelper.SM2KeyPair; import org.zz.gmhelper.SM2KeyPair;
@ -296,20 +294,9 @@ public class MasterServerRecoverMechAction {
meta.setContractExecutor( meta.setContractExecutor(
MasterClientTCPAction.createContractExecutor(meta.contract, contractID, cei.getMasterNode(), cei.getMembers())); MasterClientTCPAction.createContractExecutor(meta.contract, contractID, cei.getMasterNode(), cei.getMembers()));
switch (meta.contract.getType()) { Map<String, Object> args = new HashMap<>();
case RequestAllResponseFirst: args.put("ceiLastExeSeq", cei.getLastExeSeq());
case RequestAllResponseHalf: meta.contractExecutor.onRecover(args);
case RequestAllResponseAll:
((RequestAllExecutor) meta.contractExecutor).setSeq(cei.getLastExeSeq() + 1);
break;
case PBFT:
((PBFTExecutor) meta.contractExecutor).setSeq(cei.getLastExeSeq() + 1);
break;
case Sharding:
break;
default:
break;
}
CMActions.manager.multiContractRecorder.updateValue(cei); CMActions.manager.multiContractRecorder.updateValue(cei);
LOGGER.info("[master recover] contractID2Members put 合约 " + contractID); LOGGER.info("[master recover] contractID2Members put 合约 " + contractID);
LOGGER.info("新master恢复 MultiPointContractInfo 完成!"); LOGGER.info("新master恢复 MultiPointContractInfo 完成!");

View File

@ -14,6 +14,7 @@ import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.units.MultiContractMeta; import org.bdware.sc.units.MultiContractMeta;
import org.bdware.sc.units.RequestCache; import org.bdware.sc.units.RequestCache;
import org.bdware.sc.util.JsonUtil; import org.bdware.sc.util.JsonUtil;
import org.bdware.sdk.consistency.api.NotifiableResultMerger;
import org.bdware.server.CongestionControl; import org.bdware.server.CongestionControl;
import org.bdware.server.action.Action; import org.bdware.server.action.Action;
import org.bdware.server.action.CMActions; import org.bdware.server.action.CMActions;
@ -68,9 +69,9 @@ public class MasterServerTCPAction {
ResultCallback cb = sync.waitObj.get(requestID); ResultCallback cb = sync.waitObj.get(requestID);
if (cb instanceof ResultCollector) { if (cb instanceof ResultCollector) {
ResultCollector rc = (ResultCollector) cb; ResultCollector rc = (ResultCollector) cb;
if (rc.getCommitter() instanceof RequestAllExecutor.ResultMerger) { if (rc.getCommitter() instanceof NotifiableResultMerger) {
RequestAllExecutor.ResultMerger merger = NotifiableResultMerger merger =
(RequestAllExecutor.ResultMerger) rc.getCommitter(); (NotifiableResultMerger) rc.getCommitter();
if (merger.getContractID().equals(contractID)) { if (merger.getContractID().equals(contractID)) {
LOGGER.info("node " + nodeID + " offline! in the cluster of contract " + contractID); LOGGER.info("node " + nodeID + " offline! in the cluster of contract " + contractID);
LOGGER.debug("nodeID=" + nodeID + " contractID=" + contractID + LOGGER.debug("nodeID=" + nodeID + " contractID=" + contractID +

View File

@ -1,375 +1,375 @@
package org.bdware.server.executor.consistency; //package org.bdware.server.executor.consistency;
//
import com.google.gson.JsonObject; //import com.google.gson.JsonObject;
import com.google.gson.JsonParser; //import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive; //import com.google.gson.JsonPrimitive;
import org.apache.logging.log4j.LogManager; //import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; //import org.apache.logging.log4j.Logger;
import org.bdware.sc.ComponedContractResult; //import org.bdware.sc.ComponedContractResult;
import org.bdware.sc.ContractResult; //import org.bdware.sc.ContractResult;
import org.bdware.sc.bean.ContractRequest; //import org.bdware.sc.bean.ContractRequest;
import org.bdware.sc.conn.Node; //import org.bdware.sc.conn.Node;
import org.bdware.sc.conn.OnHashCallback; //import org.bdware.sc.conn.OnHashCallback;
import org.bdware.sc.conn.ResultCallback; //import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.consistency.Committer; //import org.bdware.sc.consistency.Committer;
import org.bdware.sc.consistency.pbft.PBFTAlgorithm; //import org.bdware.sc.consistency.pbft.PBFTAlgorithm;
import org.bdware.sc.consistency.pbft.PBFTMember; //import org.bdware.sc.consistency.pbft.PBFTMember;
import org.bdware.sc.consistency.pbft.PBFTMessage; //import org.bdware.sc.consistency.pbft.PBFTMessage;
import org.bdware.sc.consistency.pbft.PBFTType; //import org.bdware.sc.consistency.pbft.PBFTType;
import org.bdware.sc.units.*; //import org.bdware.sc.units.*;
import org.bdware.sc.util.JsonUtil; //import org.bdware.sc.util.JsonUtil;
import org.bdware.server.GlobalConf; //import org.bdware.server.GlobalConf;
import org.bdware.server.action.CMActions; //import org.bdware.server.action.CMActions;
import org.bdware.server.action.p2p.MasterServerRecoverMechAction; //import org.bdware.server.action.p2p.MasterServerRecoverMechAction;
import org.bdware.server.action.p2p.MasterServerTCPAction; //import org.bdware.server.action.p2p.MasterServerTCPAction;
import org.bdware.server.trustedmodel.ContractCluster; //import org.bdware.server.trustedmodel.ContractCluster;
import org.bdware.server.trustedmodel.ContractExecutor; //import org.bdware.server.trustedmodel.ContractExecutor;
import org.bdware.server.trustedmodel.MultiReqSeq; //import org.bdware.server.trustedmodel.MultiReqSeq;
import org.bdware.server.trustedmodel.ResultCollector; //import org.bdware.server.trustedmodel.ResultCollector;
import org.bdware.units.NetworkManager; //import org.bdware.units.NetworkManager;
import org.zz.gmhelper.SM2KeyPair; //import org.zz.gmhelper.SM2KeyPair;
//
import java.util.*; //import java.util.*;
import java.util.concurrent.ConcurrentHashMap; //import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger; //import java.util.concurrent.atomic.AtomicInteger;
//
//TODO 追赶差下的调用 ////TODO 追赶差下的调用
public class PBFTExecutor implements ContractExecutor { //public class PBFTExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(PBFTExecutor.class); // private static final Logger LOGGER = LogManager.getLogger(PBFTExecutor.class);
final Object lock = new Object(); // final Object lock = new Object();
private final List<PubKeyNode> members; // private final List<PubKeyNode> members;
int resultCount; // int resultCount;
//
AtomicInteger request_index = new AtomicInteger(0); // AtomicInteger request_index = new AtomicInteger(0);
// key为requestIDvalue为其seq // // key为requestIDvalue为其seq
Map<String, MultiReqSeq> seqMap = new ConcurrentHashMap<>(); // Map<String, MultiReqSeq> seqMap = new ConcurrentHashMap<>();
Map<String, ResultCache> resultCache = new ConcurrentHashMap<>(); // Map<String, ResultCache> resultCache = new ConcurrentHashMap<>();
// MultiPointContractInfo info; // // MultiPointContractInfo info;
String contractID; // String contractID;
PBFTAlgorithm pbft; // PBFTAlgorithm pbft;
ContractCluster contractCluster; // ContractCluster contractCluster;
boolean isMaster; // boolean isMaster;
//
public PBFTExecutor( // public PBFTExecutor(
int c, String con_id, final String masterPubkey, String[] members) { // int c, String con_id, final String masterPubkey, String[] members) {
resultCount = c; // resultCount = c;
contractID = con_id; // contractID = con_id;
this.members = new ArrayList<>(); // this.members = new ArrayList<>();
isMaster = GlobalConf.getNodeID().equals(masterPubkey); // isMaster = GlobalConf.getNodeID().equals(masterPubkey);
pbft = new PBFTAlgorithm(isMaster); // pbft = new PBFTAlgorithm(isMaster);
int count = 0; // int count = 0;
for (String mem : members) { // for (String mem : members) {
PubKeyNode pubkeyNode = new PubKeyNode(); // PubKeyNode pubkeyNode = new PubKeyNode();
pubkeyNode.pubkey = mem; // pubkeyNode.pubkey = mem;
PBFTMember pbftMember = new PBFTMember(); // PBFTMember pbftMember = new PBFTMember();
pbftMember.isMaster = mem.equals(masterPubkey); // pbftMember.isMaster = mem.equals(masterPubkey);
pbft.addMember(pubkeyNode, pbftMember); // pbft.addMember(pubkeyNode, pbftMember);
this.members.add(pubkeyNode); // this.members.add(pubkeyNode);
if (GlobalConf.getNodeID().equals(mem)) { // if (GlobalConf.getNodeID().equals(mem)) {
pbft.setSendID(count); // pbft.setSendID(count);
} // }
count++; // count++;
} // }
contractCluster = new ContractCluster(contractID, this.members); // contractCluster = new ContractCluster(contractID, this.members);
pbft.setConnection(contractCluster); // pbft.setConnection(contractCluster);
final MultiContractMeta cei = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID); // final MultiContractMeta cei = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID);
pbft.setCommitter(new Committer() { // pbft.setCommitter(new Committer() {
@Override // @Override
public void onCommit(ContractRequest data) { // public void onCommit(ContractRequest data) {
ResultCallback ret = null; // ResultCallback ret = null;
final long startTime = System.currentTimeMillis(); // final long startTime = System.currentTimeMillis();
ret = new ResultCallback() { // ret = new ResultCallback() {
@Override // @Override
public void onResult(String str) { // public void onResult(String str) {
Map<String, String> ret = new HashMap<>(); // Map<String, String> ret = new HashMap<>();
ret.put("action", "receiveTrustfullyResult"); // ret.put("action", "receiveTrustfullyResult");
SM2KeyPair keyPair = GlobalConf.instance.keyPair; // SM2KeyPair keyPair = GlobalConf.instance.keyPair;
ret.put("nodeID", keyPair.getPublicKeyStr()); // ret.put("nodeID", keyPair.getPublicKeyStr());
ret.put("responseID", data.getRequestID()); // ret.put("responseID", data.getRequestID());
ret.put("executeTime", (System.currentTimeMillis() - startTime) + ""); // ret.put("executeTime", (System.currentTimeMillis() - startTime) + "");
ret.put("data", str); // ret.put("data", str);
cei.setLastExeSeq(data.seq); // cei.setLastExeSeq(data.seq);
NetworkManager.instance.sendToAgent(masterPubkey, JsonUtil.toJson(ret)); // NetworkManager.instance.sendToAgent(masterPubkey, JsonUtil.toJson(ret));
} // }
}; // };
CMActions.manager.executeLocallyAsync(data, ret, null); // CMActions.manager.executeLocallyAsync(data, ret, null);
} // }
}); // });
} // }
//
public void onSyncMessage(Node node, byte[] data) { // public void onSyncMessage(Node node, byte[] data) {
//
pbft.onMessage(node, data); // pbft.onMessage(node, data);
} // }
//
public void setSeq(int seq) { // public void setSeq(int seq) {
request_index = new AtomicInteger(seq); // request_index = new AtomicInteger(seq);
pbft.setAtomSeq(request_index.get()); // pbft.setAtomSeq(request_index.get());
} // }
//
public ResultCallback createResultCallback( // public ResultCallback createResultCallback(
final String requestID, // final String requestID,
final ResultCallback originalCb, // final ResultCallback originalCb,
final int count, // final int count,
final int request_seq, // final int request_seq,
final String contractID) { // final String contractID) {
ComponedContractResult componedContractResult = new ComponedContractResult(count); // ComponedContractResult componedContractResult = new ComponedContractResult(count);
// TODO 加对应的超时 // // TODO 加对应的超时
return new ResultCollector( // return new ResultCollector(
requestID, new ResultMerger(originalCb, count, request_seq, contractID), count); // requestID, new ResultMerger(originalCb, count, request_seq, contractID), count);
} // }
//
public void sendRequest(String id, ContractRequest req, ResultCallback collector) { // public void sendRequest(String id, ContractRequest req, ResultCallback collector) {
// Map<String, Object> reqStr = new HashMap<>(); //// Map<String, Object> reqStr = new HashMap<>();
// reqStr.put("uniReqID", id); //// reqStr.put("uniReqID", id);
// reqStr.put("data", req); //// reqStr.put("data", req);
// reqStr.put("action", "executeContractLocally"); //// reqStr.put("action", "executeContractLocally");
ContractRequest cr2 = ContractRequest.parse(req.toByte()); // ContractRequest cr2 = ContractRequest.parse(req.toByte());
cr2.setRequestID(id); // cr2.setRequestID(id);
PBFTMessage request = new PBFTMessage(); // PBFTMessage request = new PBFTMessage();
request.setOrder(req.seq); // request.setOrder(req.seq);
request.setType(PBFTType.Request); // request.setType(PBFTType.Request);
request.setContent(cr2.toByte()); // request.setContent(cr2.toByte());
for (PubKeyNode node : members) { // for (PubKeyNode node : members) {
if (!NetworkManager.instance.hasAgentConnection(node.pubkey)) { // if (!NetworkManager.instance.hasAgentConnection(node.pubkey)) {
LOGGER.warn("cmNode " + node.pubkey.substring(0, 5) + " is null"); // LOGGER.warn("cmNode " + node.pubkey.substring(0, 5) + " is null");
collector.onResult(
"{\"status\":\"Error\",\"result\":\"node offline\","
+ "\"nodeID\":\""
+ node
+ "\","
+ "\"action\":\"onExecuteContractTrustfully\"}");
// } else if (MasterServerRecoverMechAction.recoverStatus.get(node).get(contractID)
// != RecoverFlag.Fine) {
// collector.onResult( // collector.onResult(
// "{\"status\":\"Error\",\"result\":\"node recovering\"," // "{\"status\":\"Error\",\"result\":\"node offline\","
// + "\"nodeID\":\"" // + "\"nodeID\":\""
// + node // + node
// + "\"," // + "\","
// + "\"action\":\"onExecuteContractTrustfully\"}"); // + "\"action\":\"onExecuteContractTrustfully\"}");
//// } else if (MasterServerRecoverMechAction.recoverStatus.get(node).get(contractID)
//// != RecoverFlag.Fine) {
//// collector.onResult(
//// "{\"status\":\"Error\",\"result\":\"node recovering\","
//// + "\"nodeID\":\""
//// + node
//// + "\","
//// + "\"action\":\"onExecuteContractTrustfully\"}");
//// contractCluster.sendMessage(node, request.getBytes());
// } else {
// contractCluster.sendMessage(node, request.getBytes()); // contractCluster.sendMessage(node, request.getBytes());
} else { // }
contractCluster.sendMessage(node, request.getBytes()); // }
} // // master负责缓存请求
} // if (!MasterServerTCPAction.requestCache.containsKey(contractID)) {
// master负责缓存请求 // MasterServerTCPAction.requestCache.put(contractID, new RequestCache());
if (!MasterServerTCPAction.requestCache.containsKey(contractID)) { // }
MasterServerTCPAction.requestCache.put(contractID, new RequestCache()); // // TODO 多调多统一个seq的有多个请求这个需要改
} // String[] nodes =
// TODO 多调多统一个seq的有多个请求这个需要改 // CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID).getMembers();
String[] nodes = // LOGGER.info("cluster size=" + nodes.length + " contract " + req.getContractID());
CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID).getMembers(); // LOGGER.debug("contract " + req.getContractID() + " cluster: " + JsonUtil.toJson(nodes));
LOGGER.info("cluster size=" + nodes.length + " contract " + req.getContractID()); //
LOGGER.debug("contract " + req.getContractID() + " cluster: " + JsonUtil.toJson(nodes)); // }
//
} //
// public boolean checkCurNodeNumValid() {
// return true;
public boolean checkCurNodeNumValid() { // }
return true; //
} // @Override
// public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) {
@Override // LOGGER.debug(JsonUtil.toJson(req));
public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) { // MultiContractMeta meta = CMActions.manager.multiContractRecorder.getMultiContractMeta(req.getContractID());
LOGGER.debug(JsonUtil.toJson(req)); // if (meta == null || !meta.isMaster()) {
MultiContractMeta meta = CMActions.manager.multiContractRecorder.getMultiContractMeta(req.getContractID()); // CMActions.manager.executeContractOnOtherNodes(req, rc);
if (meta == null || !meta.isMaster()) { // return;
CMActions.manager.executeContractOnOtherNodes(req, rc); // }
return; // req.setContractID(CMActions.manager.getContractIDByName(req.getContractID()));
} //
req.setContractID(CMActions.manager.getContractIDByName(req.getContractID())); // // 三个相同requestID进来的时候会有冲突
// // 仅在此处有冲突么
// 三个相同requestID进来的时候会有冲突 // // 这里是从MasterServer->MasterClient请求的是"executeContractLocally"
// 仅在此处有冲突么 //
// 这里是从MasterServer->MasterClient请求的是"executeContractLocally" // // 如果是多点合约的请求A1A2A3的序号应该一致不能分配一个新的seq根据requestID判断是否不需要重新分配一个序号
// //TODO seqMap memory leak
// 如果是多点合约的请求A1A2A3的序号应该一致不能分配一个新的seq根据requestID判断是否不需要重新分配一个序号 // //TODO
//TODO seqMap memory leak // //TODO
//TODO // if (null != requestID && requestID.endsWith("_mul")) {
//TODO // synchronized (lock) {
if (null != requestID && requestID.endsWith("_mul")) { // if (seqMap.containsKey(requestID)) {
synchronized (lock) { // req.seq = seqMap.get(requestID).seq;
if (seqMap.containsKey(requestID)) { // } else {
req.seq = seqMap.get(requestID).seq; // req.seq = request_index.getAndIncrement();
} else { // seqMap.put(requestID, new MultiReqSeq(req.seq));
req.seq = request_index.getAndIncrement(); // }
seqMap.put(requestID, new MultiReqSeq(req.seq)); // }
} // } else {
} // req.seq = request_index.getAndIncrement();
} else { // }
req.seq = request_index.getAndIncrement(); // req.needSeq = true;
} // String id =
req.needSeq = true; // System.currentTimeMillis() + "_" + (int) (Math.random() * 1000000) + "_" + req.seq;
String id = // LOGGER.info("execute receive requestID=" + requestID + " msgID=" + id);
System.currentTimeMillis() + "_" + (int) (Math.random() * 1000000) + "_" + req.seq; //
LOGGER.info("execute receive requestID=" + requestID + " msgID=" + id); // if (checkCurNodeNumValid()) {
// LOGGER.debug("checkCurNodeNumValid=true");
if (checkCurNodeNumValid()) { // ResultCallback collector =
LOGGER.debug("checkCurNodeNumValid=true"); // createResultCallback(id, rc, resultCount, req.seq, req.getContractID());
ResultCallback collector = // MasterServerTCPAction.sync.sleep(id, collector);
createResultCallback(id, rc, resultCount, req.seq, req.getContractID()); // LOGGER.info("requestID=" + requestID + " master broadcasts request " + req.seq);
MasterServerTCPAction.sync.sleep(id, collector); // sendRequest(id, req, collector);
LOGGER.info("requestID=" + requestID + " master broadcasts request " + req.seq); // } else {
sendRequest(id, req, collector); // LOGGER.debug("invalidNodeNumOnResult");
} else { // request_index.getAndDecrement();
LOGGER.debug("invalidNodeNumOnResult"); // ContractResult finalResult =
request_index.getAndDecrement(); // new ContractResult(
ContractResult finalResult = // ContractResult.Status.Error,
new ContractResult( // new JsonPrimitive("node number unavailable, request refused."));
ContractResult.Status.Error, // rc.onResult(JsonUtil.toJson(finalResult));
new JsonPrimitive("node number unavailable, request refused.")); // }
rc.onResult(JsonUtil.toJson(finalResult)); //
} // // }
//
// } // /* // 三个相同requestID进来的时候会有冲突
// // 仅在此处有冲突么
/* // 三个相同requestID进来的时候会有冲突 // // 这里是从MasterServer->MasterClient请求的是"executeContractLocally"
// 仅在此处有冲突么 // req.seq = request_index.getAndIncrement();
// 这里是从MasterServer->MasterClient请求的是"executeContractLocally" // req.needSeq = true;
req.seq = request_index.getAndIncrement(); // ResultCallback collector = createResultCallback(id, rc, resultCount, req.getContractID());
req.needSeq = true; // MasterServerTCPAction.sync.sleep(id, collector);
ResultCallback collector = createResultCallback(id, rc, resultCount, req.getContractID()); // sendRequest(id, req, collector);*/
MasterServerTCPAction.sync.sleep(id, collector); // }
sendRequest(id, req, collector);*/ //
} // // 清理缓存的多点合约请求序号
// public void clearCache() {
// 清理缓存的多点合约请求序号 // final long time = System.currentTimeMillis() - 30000L;
public void clearCache() { // seqMap.entrySet()
final long time = System.currentTimeMillis() - 30000L; // .removeIf(
seqMap.entrySet() // entry -> {
.removeIf( // MultiReqSeq cache = entry.getValue();
entry -> { // if (null == cache) {
MultiReqSeq cache = entry.getValue(); // return true;
if (null == cache) { // }
return true; // return cache.startTime < time;
} // });
return cache.startTime < time; // }
}); //
} // public static class ResultMerger extends ResultCallback {
// ComponedContractResult componedContractResult;
public static class ResultMerger extends ResultCallback { // AtomicInteger order;
ComponedContractResult componedContractResult; // String contractID;
AtomicInteger order; // int count;
String contractID; // int request_seq;
int count; // ResultCallback originalCallback;
int request_seq; // Set<String> nodeIDs = new HashSet<>(); // 已收到返回结果的节点
ResultCallback originalCallback; //
Set<String> nodeIDs = new HashSet<>(); // 已收到返回结果的节点 // ResultMerger(
// final ResultCallback originalCb,
ResultMerger( // final int count,
final ResultCallback originalCb, // final int request_seq,
final int count, // final String contractID) {
final int request_seq, // originalCallback = originalCb;
final String contractID) { // this.count = count;
originalCallback = originalCb; // this.request_seq = request_seq;
this.count = count; // this.contractID = contractID;
this.request_seq = request_seq; // componedContractResult = new ComponedContractResult(count);
this.contractID = contractID; // order = new AtomicInteger(0);
componedContractResult = new ComponedContractResult(count); // }
order = new AtomicInteger(0); //
} // public String getContractID() {
// return contractID;
public String getContractID() { // }
return contractID; //
} // public String getInfo() {
// return "contractID="
public String getInfo() { // + contractID
return "contractID=" // + " 收到第 "
+ contractID // + order
+ " 收到第 " // + " 个节点回复 : "
+ order // + " order="
+ " 个节点回复 : " // + order
+ " order=" // + " count="
+ order // + count
+ " count=" // + " ";
+ count // }
+ " "; //
} // @Override
// public void onResult(String str) {
@Override // // TODO 必须在这里聚合
public void onResult(String str) { // // str的data是个ContractResult
// TODO 必须在这里聚合 // // 在这儿也是返回个ContractResult
// str的data是个ContractResult // try {
// 在这儿也是返回个ContractResult // LOGGER.debug("a result of contract" + contractID + ": " + str);
try { // JsonObject obj = JsonParser.parseString(str).getAsJsonObject();
LOGGER.debug("a result of contract" + contractID + ": " + str); // if (obj.has("nodeID")) {
JsonObject obj = JsonParser.parseString(str).getAsJsonObject(); // String id = obj.get("nodeID").getAsString();
if (obj.has("nodeID")) { // if (nodeIDs.contains(id)) {
String id = obj.get("nodeID").getAsString(); // LOGGER.debug(
if (nodeIDs.contains(id)) { // "ignored result because the result of node "
LOGGER.debug( // + id.substring(0, 5)
"ignored result because the result of node " // + " has been received");
+ id.substring(0, 5) // return;
+ " has been received"); // }
return; // nodeIDs.add(id);
} // }
nodeIDs.add(id); //
} // LOGGER.debug(
// String.format(
LOGGER.debug( // "contractID=%s received=%s order=%d count=%d",
String.format( // contractID, str, order.get(), count));
"contractID=%s received=%s order=%d count=%d", // componedContractResult.add(obj);
contractID, str, order.get(), count)); // // 收集到所有结果
componedContractResult.add(obj); // if (order.incrementAndGet() == count) {
// 收集到所有结果 // ContractResult finalResult = componedContractResult.figureFinalResult();
if (order.incrementAndGet() == count) { // finalResult.needSeq = true;
ContractResult finalResult = componedContractResult.figureFinalResult(); // finalResult.seq = request_seq;
finalResult.needSeq = true; //
finalResult.seq = request_seq; // // if (null == finalResult) {
// // finalResult =
// if (null == finalResult) { // // new ContractResult(
// finalResult = // // ContractResult.Status.Exception,
// new ContractResult( // // new JsonPrimitive(
// ContractResult.Status.Exception, // // "no nore than half of the
// new JsonPrimitive( // // consistent result"));
// "no nore than half of the // // originalCallback.onResult(new
// consistent result")); // // Gson().toJson(finalResult));
// originalCallback.onResult(new // // } else {
// Gson().toJson(finalResult)); // originalCallback.onResult(JsonUtil.toJson(finalResult));
// } else { // // }
originalCallback.onResult(JsonUtil.toJson(finalResult)); // LOGGER.debug(
// } // String.format(
LOGGER.debug( // "%d results are the same: %s",
String.format( // finalResult.size, finalResult.result));
"%d results are the same: %s", //
finalResult.size, finalResult.result)); // // 集群中事务序号+1
// CMActions.manager.multiContractRecorder
// 集群中事务序号+1 // .getMultiContractMeta(contractID)
CMActions.manager.multiContractRecorder // .nextSeqAtMaster();
.getMultiContractMeta(contractID) //
.nextSeqAtMaster(); // // recover其中无状态合约CP出错无需恢复
// Set<String> nodesID = componedContractResult.getProblemNodes();
// recover其中无状态合约CP出错无需恢复 // if (null == nodesID || nodesID.isEmpty()) {
Set<String> nodesID = componedContractResult.getProblemNodes(); // return;
if (null == nodesID || nodesID.isEmpty()) { // }
return; // for (String nodeID : nodesID) {
} // LOGGER.warn("node fails! " + nodeID);
for (String nodeID : nodesID) { // if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID)
LOGGER.warn("node fails! " + nodeID); // == RecoverFlag.Fine) {
if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID) // MasterServerRecoverMechAction.recoverStatus
== RecoverFlag.Fine) { // .get(nodeID)
MasterServerRecoverMechAction.recoverStatus // .put(contractID, RecoverFlag.ToRecover);
.get(nodeID) // }
.put(contractID, RecoverFlag.ToRecover); // }
} // for (String nodeID : nodesID) {
} // if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID)
for (String nodeID : nodesID) { // == RecoverFlag.ToRecover) {
if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID) // LOGGER.warn("node in recover " + nodeID);
== RecoverFlag.ToRecover) { //
LOGGER.warn("node in recover " + nodeID); // // 因为该节点结果有误所以即时是stableMode也认为trans记录不可信
// // 直接通过load别的节点来恢复
// 因为该节点结果有误所以即时是stableMode也认为trans记录不可信 // MasterServerRecoverMechAction.restartContractFromCommonMode(
// 直接通过load别的节点来恢复 // nodeID, contractID);
MasterServerRecoverMechAction.restartContractFromCommonMode( // }
nodeID, contractID); // }
} // }
} // // clearCache();
} // } catch (Exception e) {
// clearCache(); // e.printStackTrace();
} catch (Exception e) { // LOGGER.warn("result exception!");
e.printStackTrace(); // }
LOGGER.warn("result exception!"); // }
} // }
} //}
}
}

View File

@ -1,400 +1,400 @@
package org.bdware.server.executor.unconsistency; //package org.bdware.server.executor.unconsistency;
//
import com.google.gson.JsonObject; //import com.google.gson.JsonObject;
import com.google.gson.JsonParser; //import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive; //import com.google.gson.JsonPrimitive;
import org.apache.logging.log4j.LogManager; //import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; //import org.apache.logging.log4j.Logger;
import org.bdware.sc.ComponedContractResult; //import org.bdware.sc.ComponedContractResult;
import org.bdware.sc.ContractMeta; //import org.bdware.sc.ContractMeta;
import org.bdware.sc.ContractResult; //import org.bdware.sc.ContractResult;
import org.bdware.sc.bean.*; //import org.bdware.sc.bean.*;
import org.bdware.sc.conn.OnHashCallback; //import org.bdware.sc.conn.OnHashCallback;
import org.bdware.sc.conn.ResultCallback; //import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.units.MultiContractMeta; //import org.bdware.sc.units.MultiContractMeta;
import org.bdware.sc.units.RecoverFlag; //import org.bdware.sc.units.RecoverFlag;
import org.bdware.sc.units.RequestCache; //import org.bdware.sc.units.RequestCache;
import org.bdware.sc.units.ResultCache; //import org.bdware.sc.units.ResultCache;
import org.bdware.sc.util.JsonUtil; //import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.CMActions; //import org.bdware.server.action.CMActions;
import org.bdware.server.action.p2p.MasterServerRecoverMechAction; //import org.bdware.server.action.p2p.MasterServerRecoverMechAction;
import org.bdware.server.action.p2p.MasterServerTCPAction; //import org.bdware.server.action.p2p.MasterServerTCPAction;
import org.bdware.server.trustedmodel.ContractExecutor; //import org.bdware.server.trustedmodel.ContractExecutor;
import org.bdware.server.trustedmodel.MultiReqSeq; //import org.bdware.server.trustedmodel.MultiReqSeq;
import org.bdware.server.trustedmodel.ResultCollector; //import org.bdware.server.trustedmodel.ResultCollector;
import org.bdware.units.NetworkManager; //import org.bdware.units.NetworkManager;
//
import java.math.BigInteger; //import java.math.BigInteger;
import java.util.HashMap; //import java.util.HashMap;
import java.util.HashSet; //import java.util.HashSet;
import java.util.Map; //import java.util.Map;
import java.util.Set; //import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; //import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger; //import java.util.concurrent.atomic.AtomicInteger;
//
// 改为MultiPointCooperationExecutor //// 改为MultiPointCooperationExecutor
public class MultiPointCooperationExecutor implements ContractExecutor { //public class MultiPointCooperationExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(MultiPointCooperationExecutor.class); // private static final Logger LOGGER = LogManager.getLogger(MultiPointCooperationExecutor.class);
final Object lock = new Object(); // final Object lock = new Object();
int resultCount; // int resultCount;
AtomicInteger request_index = new AtomicInteger(0); // AtomicInteger request_index = new AtomicInteger(0);
ContractExecType type; // ContractExecType type;
// key为requestIDvalue为其seq // // key为requestIDvalue为其seq
Map<String, MultiReqSeq> seqMap = new ConcurrentHashMap<>(); // Map<String, MultiReqSeq> seqMap = new ConcurrentHashMap<>();
Map<String, ResultCache> resultCache = new ConcurrentHashMap<>(); // Map<String, ResultCache> resultCache = new ConcurrentHashMap<>();
// MultiPointContractInfo info; // // MultiPointContractInfo info;
MultiContractMeta multiMeta; // MultiContractMeta multiMeta;
String contractID; // String contractID;
//
public MultiPointCooperationExecutor(ContractExecType t, int c, String con_id) { // public MultiPointCooperationExecutor(ContractExecType t, int c, String con_id) {
LOGGER.info("-- sharding executor---"); // LOGGER.info("-- sharding executor---");
type = t; // type = t;
resultCount = c; // resultCount = c;
contractID = con_id; // contractID = con_id;
multiMeta = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID); // multiMeta = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID);
} // }
//
public void setSeq(int seq) { // public void setSeq(int seq) {
request_index = new AtomicInteger(seq); // request_index = new AtomicInteger(seq);
} // }
//
public ResultCallback createResultCallback( // public ResultCallback createResultCallback(
final String requestID, // final String requestID,
final ResultCallback originalCb, // final ResultCallback originalCb,
final int count, // final int count,
final int request_seq, // final int request_seq,
final String contractID, JoinInfo joinInfo) { // final String contractID, JoinInfo joinInfo) {
// TODO 加对应的超时 // // TODO 加对应的超时
return new ResultCollector( // return new ResultCollector(
requestID, // requestID,
new MultiPointCooperationExecutor.ResultMerger(originalCb, count, request_seq, contractID, joinInfo), // new MultiPointCooperationExecutor.ResultMerger(originalCb, count, request_seq, contractID, joinInfo),
count); // 把count改成了1设置成获得1个响应就行 // count); // 把count改成了1设置成获得1个响应就行
} // }
//
public void sendRequest(String id, ContractRequest req, String[] nodes) { // public void sendRequest(String id, ContractRequest req, String[] nodes) {
Map<String, Object> reqStr = new HashMap<>(); // Map<String, Object> reqStr = new HashMap<>();
reqStr.put("uniReqID", id); // reqStr.put("uniReqID", id);
reqStr.put("data", req); // reqStr.put("data", req);
req.needSeq = false; // req.needSeq = false;
reqStr.put("action", "executeContractLocally"); // reqStr.put("action", "executeContractLocally");
String sendStr = JsonUtil.toJson(reqStr); // String sendStr = JsonUtil.toJson(reqStr);
// master负责缓存请求 // // master负责缓存请求
if (!MasterServerTCPAction.requestCache.containsKey(contractID)) { // if (!MasterServerTCPAction.requestCache.containsKey(contractID)) {
MasterServerTCPAction.requestCache.put(contractID, new RequestCache()); // MasterServerTCPAction.requestCache.put(contractID, new RequestCache());
} // }
// TODO 多调多统一个seq的有多个请求这个需要改 // // TODO 多调多统一个seq的有多个请求这个需要改
MasterServerTCPAction.requestCache.get(contractID).put(req.seq, sendStr); // MasterServerTCPAction.requestCache.get(contractID).put(req.seq, sendStr);
LOGGER.debug(JsonUtil.toJson(req)); // LOGGER.debug(JsonUtil.toJson(req));
LOGGER.info("node size = " + nodes.length); // LOGGER.info("node size = " + nodes.length);
LOGGER.debug("nodes:" + JsonUtil.toJson(nodes)); // LOGGER.debug("nodes:" + JsonUtil.toJson(nodes));
for (String node : nodes) { // for (String node : nodes) {
LOGGER.info( // LOGGER.info(
"[sendRequests] get cmNode " // "[sendRequests] get cmNode "
+ node.substring(0, 5) // + node.substring(0, 5)
+ " not null " // + " not null "
+ "RequestAllExecutor 发送请求给 " // + "RequestAllExecutor 发送请求给 "
+ node.substring(0, 5)); // + node.substring(0, 5));
NetworkManager.instance.sendToAgent(node, sendStr); // NetworkManager.instance.sendToAgent(node, sendStr);
} // }
} // }
//
private String[] getAccordingToRouteInfo(RouteInfo routeInfo, ContractRequest req, String[] members) { // private String[] getAccordingToRouteInfo(RouteInfo routeInfo, ContractRequest req, String[] members) {
try { // try {
int val; // int val;
switch (routeInfo.useDefault) { // switch (routeInfo.useDefault) {
case byRequester: // case byRequester:
val = // val =
new BigInteger(req.getRequester(), 16) // new BigInteger(req.getRequester(), 16)
.mod(new BigInteger("" + members.length)) // .mod(new BigInteger("" + members.length))
.intValue(); // .intValue();
while (val < 0) { // while (val < 0) {
val = val + members.length; // val = val + members.length;
} // }
return new String[]{members[val]}; // return new String[]{members[val]};
case byArgHash: // case byArgHash:
val = req.getArg().hashCode(); // val = req.getArg().hashCode();
val = val % members.length; // val = val % members.length;
while (val < 0) { // while (val < 0) {
val += members.length; // val += members.length;
} // }
return new String[]{members[val]}; // return new String[]{members[val]};
case byTarget: // case byTarget:
JsonObject jo = req.getArg().getAsJsonObject(); // JsonObject jo = req.getArg().getAsJsonObject();
val = // val =
new BigInteger(jo.get("target").getAsString(), 16) // new BigInteger(jo.get("target").getAsString(), 16)
.mod(new BigInteger("" + members.length)) // .mod(new BigInteger("" + members.length))
.intValue(); // .intValue();
while (val < 0) { // while (val < 0) {
val = val + members.length; // val = val + members.length;
} // }
return new String[]{members[val]}; // return new String[]{members[val]};
default: // default:
return members; // return members;
} // }
} catch (Exception e) { // } catch (Exception e) {
return members; // return members;
} // }
} // }
//
public boolean checkCurNodeNumValid() { // public boolean checkCurNodeNumValid() {
LOGGER.info("checkCurNodeNumValid"); // LOGGER.info("checkCurNodeNumValid");
String[] nodes = multiMeta.getMembers(); // String[] nodes = multiMeta.getMembers();
// List<String> nodes = info.members; // // List<String> nodes = info.members;
int validNode = 0; // int validNode = 0;
for (String node : nodes) { // for (String node : nodes) {
if (NetworkManager.instance.hasAgentConnection(node) // if (NetworkManager.instance.hasAgentConnection(node)
&& MasterServerRecoverMechAction.recoverStatus.get(node).get(contractID) // && MasterServerRecoverMechAction.recoverStatus.get(node).get(contractID)
== RecoverFlag.Fine) { // == RecoverFlag.Fine) {
validNode++; // validNode++;
} // }
} // }
int c = resultCount; // int c = resultCount;
if (type == ContractExecType.Sharding) c = (int) Math.ceil((double) c / 2); // if (type == ContractExecType.Sharding) c = (int) Math.ceil((double) c / 2);
LOGGER.info("c=" + c + " validNode=" + validNode); // LOGGER.info("c=" + c + " validNode=" + validNode);
return validNode >= c; // return validNode >= c;
} // }
//
@Override // @Override
public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) { // public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) {
LOGGER.info("[MultiPointCooperationExecutor] execute " + JsonUtil.toJson(req)); // LOGGER.info("[MultiPointCooperationExecutor] execute " + JsonUtil.toJson(req));
// 获得action 函数名 // // 获得action 函数名
LOGGER.info("action is : " + req.getAction()); // LOGGER.info("action is : " + req.getAction());
req.setContractID(CMActions.manager.getContractIDByName(req.getContractID())); // req.setContractID(CMActions.manager.getContractIDByName(req.getContractID()));
if (requestID != null && requestID.endsWith("_mul")) { // if (requestID != null && requestID.endsWith("_mul")) {
synchronized (lock) { // synchronized (lock) {
if (seqMap.containsKey(requestID)) { // if (seqMap.containsKey(requestID)) {
req.seq = seqMap.get(requestID).seq; // req.seq = seqMap.get(requestID).seq;
} else { // } else {
req.seq = request_index.getAndIncrement(); // req.seq = request_index.getAndIncrement();
seqMap.put(requestID, new MultiReqSeq(req.seq)); // seqMap.put(requestID, new MultiReqSeq(req.seq));
} // }
} // }
} else { // } else {
req.seq = request_index.getAndIncrement(); // req.seq = request_index.getAndIncrement();
} // }
req.needSeq = true; // req.needSeq = true;
String id = // String id =
System.currentTimeMillis() + "_" + (int) (Math.random() * 1000000) + "_" + req.seq; // System.currentTimeMillis() + "_" + (int) (Math.random() * 1000000) + "_" + req.seq;
LOGGER.info("execute receive requestID= " + requestID + " msgID=" + id); // LOGGER.info("execute receive requestID= " + requestID + " msgID=" + id);
if (checkCurNodeNumValid()) { // 校验成功 current node num 合法 // if (checkCurNodeNumValid()) { // 校验成功 current node num 合法
LOGGER.info("checkCurNodeNumValid true"); // LOGGER.info("checkCurNodeNumValid true");
ContractMeta meta = // ContractMeta meta =
CMActions.manager.statusRecorder.getContractMeta(req.getContractID()); // CMActions.manager.statusRecorder.getContractMeta(req.getContractID());
FunctionDesp fun = meta.getExportedFunction(req.getAction()); // FunctionDesp fun = meta.getExportedFunction(req.getAction());
ResultCallback collector; // ResultCallback collector;
// TODO @fanbo 下面的count 1要改应该是根据route的规则来 // // TODO @fanbo 下面的count 1要改应该是根据route的规则来
//Count 根据join规则来 // //Count 根据join规则来
//nodes 根据route规则来 // //nodes 根据route规则来
JoinInfo joinInfo = fun.joinInfo; // JoinInfo joinInfo = fun.joinInfo;
RouteInfo routeInfo = fun.routeInfo; // RouteInfo routeInfo = fun.routeInfo;
int count = getJoinCount(joinInfo, contractID); // int count = getJoinCount(joinInfo, contractID);
LOGGER.info("requestID=" + requestID + " join Count: " + count); // LOGGER.info("requestID=" + requestID + " join Count: " + count);
//
String[] members = multiMeta.getMembers(); // String[] members = multiMeta.getMembers();
String[] nodes = getAccordingToRouteInfo(routeInfo, req, members); // String[] nodes = getAccordingToRouteInfo(routeInfo, req, members);
if (nodes.length < count) { // if (nodes.length < count) {
count = nodes.length; // count = nodes.length;
} // }
collector = // collector =
createResultCallback(id, rc, count, req.seq, req.getContractID(), joinInfo); // 初始化结果收集器 // createResultCallback(id, rc, count, req.seq, req.getContractID(), joinInfo); // 初始化结果收集器
MasterServerTCPAction.sync.sleep(id, collector); // MasterServerTCPAction.sync.sleep(id, collector);
LOGGER.info("requestID=" + requestID + " master broadcasts request " + req.seq); // LOGGER.info("requestID=" + requestID + " master broadcasts request " + req.seq);
sendRequest(id, req, nodes); // 发送请求 // sendRequest(id, req, nodes); // 发送请求
} else { // } else {
LOGGER.info("invalidNodeNumOnResult"); // LOGGER.info("invalidNodeNumOnResult");
request_index.getAndDecrement(); // request_index.getAndDecrement();
ContractResult finalResult = // ContractResult finalResult =
new ContractResult( // new ContractResult(
ContractResult.Status.Error, // ContractResult.Status.Error,
new JsonPrimitive("node number unavailbale,request refused.")); // new JsonPrimitive("node number unavailbale,request refused."));
rc.onResult(JsonUtil.toJson(finalResult)); // rc.onResult(JsonUtil.toJson(finalResult));
} // }
} // }
//
private int getJoinCount(JoinInfo joinInfo, String contractID) { // private int getJoinCount(JoinInfo joinInfo, String contractID) {
if (joinInfo == null) return resultCount; // if (joinInfo == null) return resultCount;
if (joinInfo.joinCount.isJsonPrimitive() && joinInfo.joinCount.getAsJsonPrimitive().isNumber()) { // if (joinInfo.joinCount.isJsonPrimitive() && joinInfo.joinCount.getAsJsonPrimitive().isNumber()) {
return joinInfo.joinCount.getAsJsonPrimitive().getAsInt(); // return joinInfo.joinCount.getAsJsonPrimitive().getAsInt();
} // }
try { // try {
ContractRequest cr = new ContractRequest(); // ContractRequest cr = new ContractRequest();
cr.setContractID(contractID); // cr.setContractID(contractID);
cr.setAction(joinInfo.joinCount.getAsString()); // cr.setAction(joinInfo.joinCount.getAsString());
//TODO Arg需要好好设计一下 // //TODO Arg需要好好设计一下
//TODO 又好用又简单的那种设计 // //TODO 又好用又简单的那种设计
//TODO // //TODO
cr.setArg(""); // cr.setArg("");
String result = CMActions.manager.executeLocally(cr, null); // String result = CMActions.manager.executeLocally(cr, null);
return JsonUtil.parseString(result).getAsJsonObject().get("result").getAsInt(); // return JsonUtil.parseString(result).getAsJsonObject().get("result").getAsInt();
} catch (Exception e) { // } catch (Exception e) {
e.printStackTrace(); // e.printStackTrace();
return 1; // return 1;
} // }
} // }
//
// 清理缓存的多点合约请求序号 // // 清理缓存的多点合约请求序号
public void clearCache() { // public void clearCache() {
final long time = System.currentTimeMillis() - 30000L; // final long time = System.currentTimeMillis() - 30000L;
seqMap.entrySet() // seqMap.entrySet()
.removeIf( // .removeIf(
entry -> { // entry -> {
MultiReqSeq cache = entry.getValue(); // MultiReqSeq cache = entry.getValue();
if (null == cache) { // if (null == cache) {
return true; // return true;
} // }
return cache.startTime < time; // return cache.startTime < time;
}); // });
} // }
//
public static class ResultMerger extends ResultCallback { // public static class ResultMerger extends ResultCallback {
ComponedContractResult componedContractResult; // ComponedContractResult componedContractResult;
AtomicInteger order; // AtomicInteger order;
String contractID; // String contractID;
int count; // 记录有多少个节点 // int count; // 记录有多少个节点
int request_seq; // int request_seq;
ResultCallback originalCallback; // ResultCallback originalCallback;
Set<String> nodeIDs = new HashSet<>(); // 已收到返回结果的节点 // Set<String> nodeIDs = new HashSet<>(); // 已收到返回结果的节点
JoinInfo joinInfo; // JoinInfo joinInfo;
//
ResultMerger( // ResultMerger(
final ResultCallback originalCb, // final ResultCallback originalCb,
final int count, // final int count,
final int request_seq, // final int request_seq,
final String contractID, // final String contractID,
final JoinInfo joinInfo) { // final JoinInfo joinInfo) {
originalCallback = originalCb; // originalCallback = originalCb;
this.count = count; // this.count = count;
this.request_seq = request_seq; // this.request_seq = request_seq;
this.contractID = contractID; // this.contractID = contractID;
componedContractResult = new ComponedContractResult(count); // componedContractResult = new ComponedContractResult(count);
order = new AtomicInteger(0); // order = new AtomicInteger(0);
this.joinInfo = joinInfo; // this.joinInfo = joinInfo;
} // }
//
public String getInfo() { // public String getInfo() {
return "contractID=" // return "contractID="
+ contractID // + contractID
+ " 收到第 " // + " 收到第 "
+ order // + order
+ " 个节点回复 : " // + " 个节点回复 : "
+ " order=" // + " order="
+ order // + order
+ " count=" // + " count="
+ count // + count
+ " "; // + " ";
} // }
//
@Override // @Override
public void onResult(String str) { // public void onResult(String str) {
// TODO 必须在这里聚合 // // TODO 必须在这里聚合
// str的data是个ContractResult // // str的data是个ContractResult
// 在这儿也是返回个ContractResult // // 在这儿也是返回个ContractResult
try { // try {
LOGGER.info(str); // LOGGER.info(str);
JsonObject obj = JsonParser.parseString(str).getAsJsonObject(); // JsonObject obj = JsonParser.parseString(str).getAsJsonObject();
String id = obj.get("nodeID").getAsString(); // String id = obj.get("nodeID").getAsString();
if (nodeIDs.contains(id)) { // if (nodeIDs.contains(id)) {
LOGGER.info("已经收到节点 " + id.substring(0, 5) + " 的结果,该结果被忽略"); // LOGGER.info("已经收到节点 " + id.substring(0, 5) + " 的结果,该结果被忽略");
return; // return;
} // }
nodeIDs.add(id); // nodeIDs.add(id);
LOGGER.info( // LOGGER.info(
"contractID=" // "contractID="
+ contractID // + contractID
+ " 收到第 " // + " 收到第 "
+ order // + order
+ " 个节点回复 : " // + " 个节点回复 : "
+ str // + str
+ " order=" // + " order="
+ order // + order
+ " count=" // + " count="
+ count); // + count);
componedContractResult.add(obj); // componedContractResult.add(obj);
// 收集到所有结果 // // 收集到所有结果
if (order.incrementAndGet() == count) { // if (order.incrementAndGet() == count) {
ContractResult finalResult = componedContractResult.mergeFinalResult(); // ContractResult finalResult = componedContractResult.mergeFinalResult();
//
finalResult.needSeq = true; // finalResult.needSeq = true;
finalResult.seq = request_seq; // finalResult.seq = request_seq;
//
// if (null == finalResult) { // // if (null == finalResult) {
// finalResult = // // finalResult =
// new ContractResult( // // new ContractResult(
// ContractResult.Status.Exception, // // ContractResult.Status.Exception,
// new JsonPrimitive( // // new JsonPrimitive(
// "no nore than half of the // // "no nore than half of the
// consistent result")); // // consistent result"));
// originalCallback.onResult(new // // originalCallback.onResult(new
// Gson().toJson(finalResult)); // // Gson().toJson(finalResult));
// } else { // // } else {
if (joinInfo != null) { // if (joinInfo != null) {
handleJoinInfo(finalResult, joinInfo); // handleJoinInfo(finalResult, joinInfo);
} // }
originalCallback.onResult(JsonUtil.toJson(finalResult)); // originalCallback.onResult(JsonUtil.toJson(finalResult));
// } // // }
LOGGER.info( // LOGGER.info(
"本次执行最终结果为 " + finalResult.size + "个节点合并的,结果为 " + finalResult.result); // "本次执行最终结果为 " + finalResult.size + "个节点合并的,结果为 " + finalResult.result);
//
// 集群中事务序号+1 // // 集群中事务序号+1
// MasterServerTCPAction.contractID2Members.get(contractID).nextSeq(); // // MasterServerTCPAction.contractID2Members.get(contractID).nextSeq();
CMActions.manager // CMActions.manager
.multiContractRecorder // .multiContractRecorder
.getMultiContractMeta(contractID) // .getMultiContractMeta(contractID)
.nextSeqAtMaster(); // .nextSeqAtMaster();
// recover其中无状态合约CP出错无需恢复 // // recover其中无状态合约CP出错无需恢复
Set<String> nodesID = componedContractResult.getProblemNodes(); // Set<String> nodesID = componedContractResult.getProblemNodes();
if (null == nodesID || nodesID.isEmpty()) { // if (null == nodesID || nodesID.isEmpty()) {
return; // return;
} // }
for (String nodeID : nodesID) { // for (String nodeID : nodesID) {
LOGGER.info("结果出现问题的节点有:" + nodeID); // LOGGER.info("结果出现问题的节点有:" + nodeID);
if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID) // if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID)
== RecoverFlag.Fine) { // == RecoverFlag.Fine) {
MasterServerRecoverMechAction.recoverStatus // MasterServerRecoverMechAction.recoverStatus
.get(nodeID) // .get(nodeID)
.put(contractID, RecoverFlag.ToRecover); // .put(contractID, RecoverFlag.ToRecover);
} // }
} // }
for (String nodeID : nodesID) { // for (String nodeID : nodesID) {
if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID) // if (MasterServerRecoverMechAction.recoverStatus.get(nodeID).get(contractID)
== RecoverFlag.ToRecover) { // == RecoverFlag.ToRecover) {
LOGGER.info("问题节点开始恢复:" + nodeID); // LOGGER.info("问题节点开始恢复:" + nodeID);
//
// 因为该节点结果有误所以即时是stableMode也认为trans记录不可信 // // 因为该节点结果有误所以即时是stableMode也认为trans记录不可信
// 直接通过load别的节点来恢复 // // 直接通过load别的节点来恢复
MasterServerRecoverMechAction.restartContractFromCommonMode( // MasterServerRecoverMechAction.restartContractFromCommonMode(
nodeID, contractID); // nodeID, contractID);
} // }
} // }
} // }
// clearCache(); // // clearCache();
} catch (Exception e) { // } catch (Exception e) {
e.printStackTrace(); // e.printStackTrace();
LOGGER.info("本次执行最终结果为有异常"); // LOGGER.info("本次执行最终结果为有异常");
} // }
} // }
//
private void handleJoinInfo(ContractResult finalResult, JoinInfo joinInfo) { // private void handleJoinInfo(ContractResult finalResult, JoinInfo joinInfo) {
JsonObject jo = finalResult.result.getAsJsonObject(); // JsonObject jo = finalResult.result.getAsJsonObject();
if (joinInfo != null && joinInfo.joinRule != null) { // if (joinInfo != null && joinInfo.joinRule != null) {
//TODO 不应该是double 类型 // //TODO 不应该是double 类型
switch (joinInfo.joinRule) { // switch (joinInfo.joinRule) {
case "add": // case "add":
double val = 0; // double val = 0;
for (String key : jo.keySet()) { // for (String key : jo.keySet()) {
val += jo.get(key).getAsDouble(); // val += jo.get(key).getAsDouble();
} // }
finalResult.result = new JsonPrimitive(val); // finalResult.result = new JsonPrimitive(val);
break; // break;
case "multiply": // case "multiply":
val = 1; // val = 1;
for (String key : jo.keySet()) { // for (String key : jo.keySet()) {
val *= jo.get(key).getAsDouble(); // val *= jo.get(key).getAsDouble();
} // }
finalResult.result = new JsonPrimitive(val); // finalResult.result = new JsonPrimitive(val);
break; // break;
} // }
} // }
} // }
} // }
} //}

View File

@ -1,68 +1,68 @@
package org.bdware.server.executor.unconsistency; //package org.bdware.server.executor.unconsistency;
//
import com.google.gson.JsonObject; //import com.google.gson.JsonObject;
import com.google.gson.JsonParser; //import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager; //import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; //import org.apache.logging.log4j.Logger;
import org.bdware.sc.bean.ContractRequest; //import org.bdware.sc.bean.ContractRequest;
import org.bdware.sc.conn.OnHashCallback; //import org.bdware.sc.conn.OnHashCallback;
import org.bdware.sc.conn.ResultCallback; //import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil; //import org.bdware.sc.util.JsonUtil;
import org.bdware.server.ControllerManager; //import org.bdware.server.ControllerManager;
import org.bdware.server.action.CMActions; //import org.bdware.server.action.CMActions;
import org.bdware.server.action.p2p.MasterServerTCPAction; //import org.bdware.server.action.p2p.MasterServerTCPAction;
import org.bdware.server.trustedmodel.ContractExecutor; //import org.bdware.server.trustedmodel.ContractExecutor;
import org.bdware.server.trustedmodel.AgentManager; //import org.bdware.server.trustedmodel.AgentManager;
import org.bdware.units.NetworkManager; //import org.bdware.units.NetworkManager;
//
import java.util.HashMap; //import java.util.HashMap;
import java.util.Map; //import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; //import java.util.concurrent.atomic.AtomicInteger;
//
public class RequestOnceExecutor implements ContractExecutor { //public class RequestOnceExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(RequestOnceExecutor.class); // private static final Logger LOGGER = LogManager.getLogger(RequestOnceExecutor.class);
String contractID; // String contractID;
AtomicInteger order = new AtomicInteger(0); // AtomicInteger order = new AtomicInteger(0);
//
public RequestOnceExecutor(String contractID) { // public RequestOnceExecutor(String contractID) {
this.contractID = contractID; // this.contractID = contractID;
} // }
//
@Override // @Override
public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) { // public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) {
ResultCallback cb = // ResultCallback cb =
new ResultCallback() { // new ResultCallback() {
@Override // @Override
public void onResult(String str) { // public void onResult(String str) {
LOGGER.debug(str); // LOGGER.debug(str);
JsonObject jo = JsonParser.parseString(str).getAsJsonObject(); // JsonObject jo = JsonParser.parseString(str).getAsJsonObject();
JsonObject result = // JsonObject result =
JsonParser.parseString(jo.get("data").getAsString()) // JsonParser.parseString(jo.get("data").getAsString())
.getAsJsonObject(); // .getAsJsonObject();
for (String key : result.keySet()) jo.add(key, result.get(key)); // for (String key : result.keySet()) jo.add(key, result.get(key));
jo.remove("action"); // jo.remove("action");
jo.addProperty("action", "onExecuteResult"); // jo.addProperty("action", "onExecuteResult");
LOGGER.debug(jo.toString()); // LOGGER.debug(jo.toString());
rc.onResult(jo.toString()); // rc.onResult(jo.toString());
} // }
}; // };
MasterServerTCPAction.sync.sleep(requestID, cb); // MasterServerTCPAction.sync.sleep(requestID, cb);
String[] members = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID).getMembers(); // String[] members = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID).getMembers();
for (int i = 0; i < members.length; i++) { // for (int i = 0; i < members.length; i++) {
LOGGER.info("[members]:" + members.length); // LOGGER.info("[members]:" + members.length);
int size = members.length; // int size = members.length;
String nodeID = members[order.incrementAndGet() % size]; // String nodeID = members[order.incrementAndGet() % size];
//ADD Connect // //ADD Connect
Map<String, Object> obj = new HashMap<>(); // Map<String, Object> obj = new HashMap<>();
obj.put("action", "executeContractLocally"); // obj.put("action", "executeContractLocally");
obj.put("requestID",requestID); // obj.put("requestID",requestID);
obj.put("data", req); // obj.put("data", req);
obj.put("uniReqID", requestID); // obj.put("uniReqID", requestID);
NetworkManager.instance.sendToAgent(nodeID,JsonUtil.toJson(obj)); // NetworkManager.instance.sendToAgent(nodeID,JsonUtil.toJson(obj));
return; // return;
} // }
rc.onResult( // rc.onResult(
"{\"status\":\"Error\",\"result\":\"all nodes " // "{\"status\":\"Error\",\"result\":\"all nodes "
+ " offline\",\"action\":\"onExecuteContract\"}"); // + " offline\",\"action\":\"onExecuteContract\"}");
} // }
} //}

View File

@ -1,83 +1,83 @@
package org.bdware.server.executor.unconsistency; //package org.bdware.server.executor.unconsistency;
//
import com.google.gson.JsonObject; //import com.google.gson.JsonObject;
import com.google.gson.JsonParser; //import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager; //import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; //import org.apache.logging.log4j.Logger;
import org.bdware.sc.ContractResult; //import org.bdware.sc.ContractResult;
import org.bdware.sc.bean.ContractRequest; //import org.bdware.sc.bean.ContractRequest;
import org.bdware.sc.conn.OnHashCallback; //import org.bdware.sc.conn.OnHashCallback;
import org.bdware.sc.conn.ResultCallback; //import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.util.JsonUtil; //import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.CMActions; //import org.bdware.server.action.CMActions;
import org.bdware.server.action.p2p.MasterServerTCPAction; //import org.bdware.server.action.p2p.MasterServerTCPAction;
import org.bdware.server.trustedmodel.ContractExecutor; //import org.bdware.server.trustedmodel.ContractExecutor;
import org.bdware.units.NetworkManager; //import org.bdware.units.NetworkManager;
//
import java.util.HashMap; //import java.util.HashMap;
import java.util.Map; //import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; //import java.util.concurrent.atomic.AtomicInteger;
//
public class ResponseOnceExecutor implements ContractExecutor { //public class ResponseOnceExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(ResponseOnceExecutor.class); // private static final Logger LOGGER = LogManager.getLogger(ResponseOnceExecutor.class);
private final String contractID; // private final String contractID;
AtomicInteger order = new AtomicInteger(0); // AtomicInteger order = new AtomicInteger(0);
//
public ResponseOnceExecutor(String contractID) { // public ResponseOnceExecutor(String contractID) {
this.contractID = contractID; // this.contractID = contractID;
} // }
//
@Override // @Override
public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) { // public void execute(String requestID, ContractRequest req, ResultCallback rc, OnHashCallback hcb) {
executeInternal(requestID, rc, req, 2); // executeInternal(requestID, rc, req, 2);
} // }
//
private void executeInternal( // private void executeInternal(
String requestID, ResultCallback rc, ContractRequest req, int count) { // String requestID, ResultCallback rc, ContractRequest req, int count) {
// String contractID = req.getContractID(); // // String contractID = req.getContractID();
// TODO 标注失效节点是否选择重新迁移 // // TODO 标注失效节点是否选择重新迁移
ResultCallback cb = // ResultCallback cb =
new ResultCallback() { // new ResultCallback() {
@Override // @Override
public void onResult(String str) { // public void onResult(String str) {
LOGGER.debug(str); // LOGGER.debug(str);
JsonObject jo = JsonParser.parseString(str).getAsJsonObject(); // JsonObject jo = JsonParser.parseString(str).getAsJsonObject();
jo.remove("action"); // jo.remove("action");
jo.addProperty("action", "onExecuteResult"); // jo.addProperty("action", "onExecuteResult");
LOGGER.debug(jo.toString()); // LOGGER.debug(jo.toString());
if (jo.has("data")) { // if (jo.has("data")) {
String data = jo.get("data").getAsString(); // String data = jo.get("data").getAsString();
ContractResult cr = JsonUtil.fromJson(data, ContractResult.class); // ContractResult cr = JsonUtil.fromJson(data, ContractResult.class);
if (cr.status != ContractResult.Status.Success && count > 0) { // if (cr.status != ContractResult.Status.Success && count > 0) {
executeInternal(requestID, rc, req, count - 1); // executeInternal(requestID, rc, req, count - 1);
} else rc.onResult(jo.toString()); // } else rc.onResult(jo.toString());
} else { // } else {
JsonObject jo2 = new JsonObject(); // JsonObject jo2 = new JsonObject();
jo2.addProperty("action", "onExecuteResult"); // jo2.addProperty("action", "onExecuteResult");
jo.remove("action"); // jo.remove("action");
jo2.addProperty("data", jo.toString()); // jo2.addProperty("data", jo.toString());
rc.onResult(jo2.toString()); // rc.onResult(jo2.toString());
} // }
} // }
}; // };
MasterServerTCPAction.sync.sleepWithTimeout(requestID, cb, 5); // MasterServerTCPAction.sync.sleepWithTimeout(requestID, cb, 5);
if (!sendOnce(requestID, req)) // if (!sendOnce(requestID, req))
rc.onResult( // rc.onResult(
"{\"status\":\"Error\",\"data\":\"{\\\"status\\\":\\\"Error\\\",\\\"result\\\":\\\"all nodes offline\\\"}\",\"action\":\"onExecuteContract\"}"); // "{\"status\":\"Error\",\"data\":\"{\\\"status\\\":\\\"Error\\\",\\\"result\\\":\\\"all nodes offline\\\"}\",\"action\":\"onExecuteContract\"}");
} // }
//
private boolean sendOnce(String requestID, ContractRequest req) { // private boolean sendOnce(String requestID, ContractRequest req) {
String[] members = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID).getMembers(); // String[] members = CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID).getMembers();
for (int i = 0; i < members.length; i++) { // for (int i = 0; i < members.length; i++) {
int size = members.length; // int size = members.length;
String nodeID = members[order.incrementAndGet() % size]; // String nodeID = members[order.incrementAndGet() % size];
Map<String, Object> obj = new HashMap<>(); // Map<String, Object> obj = new HashMap<>();
obj.put("action", "executeContractLocally"); // obj.put("action", "executeContractLocally");
obj.put("data", req); // obj.put("data", req);
obj.put("uniReqID", requestID); // obj.put("uniReqID", requestID);
NetworkManager.instance.sendToAgent(nodeID, JsonUtil.toJson(obj)); // NetworkManager.instance.sendToAgent(nodeID, JsonUtil.toJson(obj));
return true; // return true;
} // }
return false; // return false;
} // }
} //}

View File

@ -1,11 +0,0 @@
package org.bdware.server.trustedmodel;
public class MultiReqSeq {
public final int seq;
public final long startTime;
public MultiReqSeq(int s){
seq = s;
startTime = System.currentTimeMillis();
}
}

View File

@ -1,305 +1,305 @@
package org.bdware.server.trustedmodel; //package org.bdware.server.trustedmodel;
//
import com.google.gson.JsonObject; //import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; //import com.google.gson.JsonPrimitive;
import org.apache.logging.log4j.LogManager; //import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; //import org.apache.logging.log4j.Logger;
import org.bdware.sc.ContractClient; //import org.bdware.sc.ContractClient;
import org.bdware.sc.ContractManager; //import org.bdware.sc.ContractManager;
import org.bdware.sc.ContractResult; //import org.bdware.sc.ContractResult;
import org.bdware.sc.bean.ContractRequest; //import org.bdware.sc.bean.ContractRequest;
import org.bdware.sc.bean.FunctionDesp; //import org.bdware.sc.bean.FunctionDesp;
import org.bdware.sc.bean.SM2Verifiable; //import org.bdware.sc.bean.SM2Verifiable;
import org.bdware.sc.conn.OnHashCallback; //import org.bdware.sc.conn.OnHashCallback;
import org.bdware.sc.conn.ResultCallback; //import org.bdware.sc.conn.ResultCallback;
import org.bdware.sc.units.MultiContractMeta; //import org.bdware.sc.units.MultiContractMeta;
import org.bdware.sc.units.RecoverFlag; //import org.bdware.sc.units.RecoverFlag;
import org.bdware.sc.util.HashUtil; //import org.bdware.sc.util.HashUtil;
import org.bdware.sc.util.JsonUtil; //import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.CMActions; //import org.bdware.server.action.CMActions;
import org.bdware.server.action.p2p.MasterServerRecoverMechAction; //import org.bdware.server.action.p2p.MasterServerRecoverMechAction;
import org.bdware.units.NetworkManager; //import org.bdware.units.NetworkManager;
//
import java.util.*; //import java.util.*;
import java.util.concurrent.*; //import java.util.concurrent.*;
import java.util.stream.Collectors; //import java.util.stream.Collectors;
//
/** ///**
* @author Kaidong Wu // * @author Kaidong Wu
*/ // */
public class SelfAdaptiveShardingExecutor implements ContractExecutor { //public class SelfAdaptiveShardingExecutor implements ContractExecutor {
private static final Logger LOGGER = LogManager.getLogger(SelfAdaptiveShardingExecutor.class); // private static final Logger LOGGER = LogManager.getLogger(SelfAdaptiveShardingExecutor.class);
private static final int SUBMIT_LIMIT = 1024; // private static final int SUBMIT_LIMIT = 1024;
private final Queue<ContractRequest> reqQueue = new ConcurrentLinkedQueue<>(); // private final Queue<ContractRequest> reqQueue = new ConcurrentLinkedQueue<>();
private final MultiContractMeta meta; // private final MultiContractMeta meta;
private final Map<String, Block> toExecuted = new ConcurrentHashMap<>(); // private final Map<String, Block> toExecuted = new ConcurrentHashMap<>();
private final Set<String> executedBlocks = ConcurrentHashMap.newKeySet(); // private final Set<String> executedBlocks = ConcurrentHashMap.newKeySet();
private final Map<String, Boolean> executedTxs = new ConcurrentHashMap<>(); // private final Map<String, Boolean> executedTxs = new ConcurrentHashMap<>();
private final Object flag = new Object(); // private final Object flag = new Object();
private final ScheduledFuture<?> future; // private final ScheduledFuture<?> future;
private boolean running = true; // private boolean running = true;
private Block b = new Block(); // private Block b = new Block();
//
public SelfAdaptiveShardingExecutor(String contractID) { // public SelfAdaptiveShardingExecutor(String contractID) {
this.meta = // this.meta =
CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID); // CMActions.manager.multiContractRecorder.getMultiContractMeta(contractID);
this.future = ContractManager.scheduledThreadPool.scheduleWithFixedDelay( // this.future = ContractManager.scheduledThreadPool.scheduleWithFixedDelay(
this::submitBlock, // this::submitBlock,
2, // 2,
2, // 2,
TimeUnit.SECONDS); // TimeUnit.SECONDS);
LOGGER.debug(String.format("ContractManager.threadPool=%d/%d", // LOGGER.debug(String.format("ContractManager.threadPool=%d/%d",
((ThreadPoolExecutor) ContractManager.threadPool).getActiveCount(), // ((ThreadPoolExecutor) ContractManager.threadPool).getActiveCount(),
((ThreadPoolExecutor) ContractManager.threadPool).getPoolSize())); // ((ThreadPoolExecutor) ContractManager.threadPool).getPoolSize()));
ContractManager.threadPool.execute(() -> { // ContractManager.threadPool.execute(() -> {
LOGGER.info( // LOGGER.info(
"[SelfAdaptiveShardingExecutor " + meta.getContractID() + "] starting service..." + running); // "[SelfAdaptiveShardingExecutor " + meta.getContractID() + "] starting service..." + running);
while (running) { // while (running) {
LOGGER.info("checking blocks to be executed, latest block=" + // LOGGER.info("checking blocks to be executed, latest block=" +
this.b.prevHash + ", to be executed size=" + toExecuted.size()); // this.b.prevHash + ", to be executed size=" + toExecuted.size());
LOGGER.debug("executed: " + JsonUtil.toJson(executedBlocks) + "\n\t" + JsonUtil.toJson(executedTxs)); // LOGGER.debug("executed: " + JsonUtil.toJson(executedBlocks) + "\n\t" + JsonUtil.toJson(executedTxs));
while (!toExecuted.isEmpty()) { // while (!toExecuted.isEmpty()) {
String key = this.b.prevHash; // String key = this.b.prevHash;
Block block = toExecuted.get(key); // Block block = toExecuted.get(key);
if (null != block) { // if (null != block) {
executeBlock(block); // executeBlock(block);
} // }
toExecuted.remove(key); // toExecuted.remove(key);
} // }
synchronized (flag) { // synchronized (flag) {
try { // try {
flag.wait(); // flag.wait();
} catch (InterruptedException e) { // } catch (InterruptedException e) {
LOGGER.warn(String.format( // LOGGER.warn(String.format(
"[SelfAdaptiveShardingExecutor %s] waiting is interrupted: %s", // "[SelfAdaptiveShardingExecutor %s] waiting is interrupted: %s",
meta.getContractID(), // meta.getContractID(),
e.getMessage())); // e.getMessage()));
} // }
} // }
} // }
}); // });
} // }
//
@Override // @Override
public void execute(String requestID, ContractRequest req, ResultCallback rcb, OnHashCallback hcb) { // public void execute(String requestID, ContractRequest req, ResultCallback rcb, OnHashCallback hcb) {
// check client // // check client
ContractClient client = CMActions.manager.getClient(meta.getContractID()); // ContractClient client = CMActions.manager.getClient(meta.getContractID());
if (null == client) { // if (null == client) {
LOGGER.error("contract " + meta.getContractID() + " not found!"); // LOGGER.error("contract " + meta.getContractID() + " not found!");
rcb.onResult(JsonUtil.toJson(new ContractResult( // rcb.onResult(JsonUtil.toJson(new ContractResult(
ContractResult.Status.Error, // ContractResult.Status.Error,
new JsonPrimitive("contract " + meta.getContractID() + " not found!")))); // new JsonPrimitive("contract " + meta.getContractID() + " not found!"))));
return; // return;
} // }
// check function // // check function
FunctionDesp funDesp = client.contractMeta.getExportedFunction(req.getAction()); // FunctionDesp funDesp = client.contractMeta.getExportedFunction(req.getAction());
if (null == funDesp) { // if (null == funDesp) {
LOGGER.warn("action " + req.getAction() + " of contract " + meta.getContractID() + " not found!"); // LOGGER.warn("action " + req.getAction() + " of contract " + meta.getContractID() + " not found!");
rcb.onResult(JsonUtil.toJson(new ContractResult( // rcb.onResult(JsonUtil.toJson(new ContractResult(
ContractResult.Status.Error, // ContractResult.Status.Error,
new JsonPrimitive( // new JsonPrimitive(
String.format("action %s of contract %s not found!", // String.format("action %s of contract %s not found!",
req.getAction(), // req.getAction(),
meta.getContractID()))))); // meta.getContractID())))));
return; // return;
} // }
// for view function, execute it // // for view function, execute it
if (funDesp.isView) { // if (funDesp.isView) {
CMActions.manager.executeLocallyAsync(req, rcb, hcb); // CMActions.manager.executeLocallyAsync(req, rcb, hcb);
return; // return;
} // }
// normal function, check if it is in blocks // // normal function, check if it is in blocks
if (executedTxs.containsKey(requestID)) { // if (executedTxs.containsKey(requestID)) {
rcb.onResult(JsonUtil.toJson(new ContractResult( // rcb.onResult(JsonUtil.toJson(new ContractResult(
ContractResult.Status.Error, // ContractResult.Status.Error,
new JsonPrimitive("this request has been packed!")))); // new JsonPrimitive("this request has been packed!"))));
return; // return;
} // }
// add blocks into request cache // // add blocks into request cache
LOGGER.debug("receive contract request " + requestID); // LOGGER.debug("receive contract request " + requestID);
executedTxs.put(requestID, false); // executedTxs.put(requestID, false);
reqQueue.add(req); // reqQueue.add(req);
rcb.onResult(JsonUtil.toJson(new ContractResult( // rcb.onResult(JsonUtil.toJson(new ContractResult(
ContractResult.Status.Executing, // ContractResult.Status.Executing,
new JsonPrimitive("this request is adding into blocks")))); // new JsonPrimitive("this request is adding into blocks"))));
// if cache is full, submit // // if cache is full, submit
if (reqQueue.size() >= SUBMIT_LIMIT) { // if (reqQueue.size() >= SUBMIT_LIMIT) {
ContractManager.threadPool.execute(this::submitBlock); // ContractManager.threadPool.execute(this::submitBlock);
} // }
} // }
//
@Override // @Override
public void close() { // public void close() {
// stop threads // // stop threads
this.future.cancel(true); // this.future.cancel(true);
this.running = false; // this.running = false;
LOGGER.info("destruct executor of contract " + meta.getContractID()); // LOGGER.info("destruct executor of contract " + meta.getContractID());
} // }
//
public void execute(String blockStr) { // public void execute(String blockStr) {
Block block = JsonUtil.fromJson(blockStr, Block.class); // Block block = JsonUtil.fromJson(blockStr, Block.class);
// the block must have not been cached or executed, and must be valid // // the block must have not been cached or executed, and must be valid
if (!toExecuted.containsKey(block.prevHash) && // if (!toExecuted.containsKey(block.prevHash) &&
!executedBlocks.contains(block.hash) && // !executedBlocks.contains(block.hash) &&
block.isValid()) { // block.isValid()) {
// add block into block cache // // add block into block cache
LOGGER.info(String.format( // LOGGER.info(String.format(
"[SelfAdaptiveShardingExecutor %s] receive block %s -> %s," + // "[SelfAdaptiveShardingExecutor %s] receive block %s -> %s," +
" %d transactions, timestamp=%d, size=%d", // " %d transactions, timestamp=%d, size=%d",
meta.getContractID(), // meta.getContractID(),
block.hash, // block.hash,
block.prevHash, // block.prevHash,
block.requests.length, // block.requests.length,
block.timestamp, // block.timestamp,
blockStr.length())); // blockStr.length()));
toExecuted.put(block.prevHash, block); // toExecuted.put(block.prevHash, block);
// notify thread to execute blocks // // notify thread to execute blocks
synchronized (flag) { // synchronized (flag) {
flag.notify(); // flag.notify();
} // }
} // }
} // }
//
private synchronized void executeBlock(Block block) { // private synchronized void executeBlock(Block block) {
// used for the thread to execute blocks // // used for the thread to execute blocks
LOGGER.debug("start"); // LOGGER.debug("start");
// check contract requests, requests must have not been executed // // check contract requests, requests must have not been executed
for (ContractRequest request : block.requests) { // for (ContractRequest request : block.requests) {
if (executedTxs.containsKey(request.getRequestID()) && executedTxs.get(request.getRequestID())) { // if (executedTxs.containsKey(request.getRequestID()) && executedTxs.get(request.getRequestID())) {
LOGGER.debug("find request " + request.getRequestID() + " has been executed!"); // LOGGER.debug("find request " + request.getRequestID() + " has been executed!");
return; // return;
} // }
} // }
// TODO check status // // TODO check status
// executed requests // // executed requests
for (ContractRequest request : block.requests) { // for (ContractRequest request : block.requests) {
String ret = CMActions.manager.executeLocally(request, null); // String ret = CMActions.manager.executeLocally(request, null);
LOGGER.debug(String.format( // LOGGER.debug(String.format(
"[SelfAdaptiveShardingExecutor %s] result of request %s: %s", // "[SelfAdaptiveShardingExecutor %s] result of request %s: %s",
meta.getContractID(), // meta.getContractID(),
request.getRequestID(), // request.getRequestID(),
ret)); // ret));
executedTxs.put(request.getRequestID(), true); // executedTxs.put(request.getRequestID(), true);
} // }
LOGGER.info(String.format( // LOGGER.info(String.format(
"[SelfAdaptiveShardingExecutor %s] execute %d transactions of block %s", // "[SelfAdaptiveShardingExecutor %s] execute %d transactions of block %s",
meta.getContractID(), // meta.getContractID(),
block.requests.length, // block.requests.length,
block.hash)); // block.hash));
// TODO create check point // // TODO create check point
this.b = new Block(block.hash, this.b.height + 1); // this.b = new Block(block.hash, this.b.height + 1);
executedBlocks.add(block.hash); // executedBlocks.add(block.hash);
} // }
//
private void submitBlock() { // private void submitBlock() {
Block block = fillBlock(); // Block block = fillBlock();
if (null != block) { // if (null != block) {
LOGGER.info("deliver block " + block.hash + "..."); // LOGGER.info("deliver block " + block.hash + "...");
LOGGER.debug(JsonUtil.toPrettyJson(block)); // LOGGER.debug(JsonUtil.toPrettyJson(block));
String[] nodes = this.meta.getMembers(); // String[] nodes = this.meta.getMembers();
JsonObject req = new JsonObject(); // JsonObject req = new JsonObject();
req.addProperty("action", "deliverBlock"); // req.addProperty("action", "deliverBlock");
req.addProperty("data", JsonUtil.toJson(block)); // req.addProperty("data", JsonUtil.toJson(block));
req.addProperty("contractID", this.meta.getContractID()); // req.addProperty("contractID", this.meta.getContractID());
String reqStr = req.toString(); // String reqStr = req.toString();
// deliver blocks // // deliver blocks
for (String node : nodes) { // for (String node : nodes) {
if (MasterServerRecoverMechAction.recoverStatus.get(node).get(this.meta.getContractID()) // if (MasterServerRecoverMechAction.recoverStatus.get(node).get(this.meta.getContractID())
== RecoverFlag.Fine) { // == RecoverFlag.Fine) {
NetworkManager.instance.sendToAgent(node, reqStr); // NetworkManager.instance.sendToAgent(node, reqStr);
} // }
} // }
} // }
} // }
//
private synchronized Block fillBlock() { // private synchronized Block fillBlock() {
// pack contract requests into a block // // pack contract requests into a block
ContractRequest[] requests = new ContractRequest[Math.min(reqQueue.size(), SUBMIT_LIMIT)]; // ContractRequest[] requests = new ContractRequest[Math.min(reqQueue.size(), SUBMIT_LIMIT)];
if (requests.length == 0) { // if (requests.length == 0) {
return null; // return null;
} // }
for (int i = 0; i < requests.length; ++i) { // for (int i = 0; i < requests.length; ++i) {
requests[i] = reqQueue.poll(); // requests[i] = reqQueue.poll();
} // }
this.b.fillBlock(requests); // this.b.fillBlock(requests);
return this.b; // return this.b;
} // }
//
static class Block extends SM2Verifiable { // static class Block extends SM2Verifiable {
String prevHash = "0"; // String prevHash = "0";
String hash; // String hash;
int height; // int height;
String checkPoint; // String checkPoint;
String body; // String body;
String nodePubKey; // String nodePubKey;
ContractRequest[] requests; // ContractRequest[] requests;
long timestamp; // long timestamp;
//
public Block() { // public Block() {
this.height = 0; // this.height = 0;
} // }
//
public Block(String prev, int height) { // public Block(String prev, int height) {
this.prevHash = prev; // this.prevHash = prev;
this.height = height; // this.height = height;
} // }
//
public void fillBlock(ContractRequest[] requests) { // public void fillBlock(ContractRequest[] requests) {
this.requests = requests; // this.requests = requests;
this.timestamp = System.currentTimeMillis(); // this.timestamp = System.currentTimeMillis();
this.body = merkle(requests); // this.body = merkle(requests);
this.hash = computeHash(); // this.hash = computeHash();
doSignature(CMActions.manager.nodeCenterConn.getNodeKeyPair()); // doSignature(CMActions.manager.nodeCenterConn.getNodeKeyPair());
} // }
//
public boolean isValid() { // public boolean isValid() {
return computeHash().equals(hash) && body.equals(merkle(this.requests)) && verifySignature(); // return computeHash().equals(hash) && body.equals(merkle(this.requests)) && verifySignature();
} // }
//
private String computeHash() { // private String computeHash() {
return HashUtil.sha3( // return HashUtil.sha3(
String.valueOf(this.height), // String.valueOf(this.height),
this.prevHash, // this.prevHash,
this.checkPoint, // this.checkPoint,
this.body); // this.body);
} // }
//
private String merkle(ContractRequest[] requests) { // private String merkle(ContractRequest[] requests) {
// manage requests as a merkle tree // // manage requests as a merkle tree
if (requests.length == 0) { // if (requests.length == 0) {
return null; // return null;
} // }
if (requests.length == 1) { // if (requests.length == 1) {
return HashUtil.sha3(requests[0].getRequestID()); // return HashUtil.sha3(requests[0].getRequestID());
} // }
Queue<String> reqQueue = // Queue<String> reqQueue =
Arrays.stream(requests).map(ContractRequest::getRequestID) // Arrays.stream(requests).map(ContractRequest::getRequestID)
.collect(Collectors.toCollection(ArrayDeque::new)); // .collect(Collectors.toCollection(ArrayDeque::new));
do { // do {
int size; // int size;
for (size = reqQueue.size(); size > 1; size -= 2) { // for (size = reqQueue.size(); size > 1; size -= 2) {
reqQueue.add(HashUtil.sha3(reqQueue.poll(), reqQueue.poll())); // reqQueue.add(HashUtil.sha3(reqQueue.poll(), reqQueue.poll()));
} // }
if (size == 1) { // if (size == 1) {
reqQueue.add(reqQueue.poll()); // reqQueue.add(reqQueue.poll());
} // }
} while (1 != reqQueue.size()); // } while (1 != reqQueue.size());
return reqQueue.poll(); // return reqQueue.poll();
} // }
//
@Override // @Override
public String getPublicKey() { // public String getPublicKey() {
return nodePubKey; // return nodePubKey;
} // }
//
@Override // @Override
public void setPublicKey(String pubkey) { // public void setPublicKey(String pubkey) {
this.nodePubKey = pubkey; // this.nodePubKey = pubkey;
} // }
//
@Override // @Override
public String getContentStr() { // public String getContentStr() {
return this.hash; // return this.hash;
} // }
} // }
} //}

View File

@ -1,63 +1,63 @@
package org.bdware.server; //package org.bdware.server;
//
import org.bdware.doip.core.doipMessage.DoipMessage; //import org.bdware.doip.core.doipMessage.DoipMessage;
import org.bdware.doip.core.doipMessage.DoipMessageFactory; //import org.bdware.doip.core.doipMessage.DoipMessageFactory;
import org.bdware.doip.core.model.operations.BasicOperations; //import org.bdware.doip.core.model.operations.BasicOperations;
import org.bdware.doip.endpoint.doipClient.DoipClientImpl; //import org.bdware.doip.endpoint.doipClient.DoipClientImpl;
import org.bdware.doip.endpoint.doipClient.DoipMessageCallback; //import org.bdware.doip.endpoint.doipClient.DoipMessageCallback;
import org.junit.Before; //import org.junit.Before;
import org.junit.Test; //import org.junit.Test;
//
import java.nio.charset.StandardCharsets; //import java.nio.charset.StandardCharsets;
import java.util.ArrayList; //import java.util.ArrayList;
import java.util.List; //import java.util.List;
//
public class DOIPTest { //public class DOIPTest {
public static String repoID = "86.5000.470/doip.localContractRepo"; // public static String repoID = "86.5000.470/doip.localContractRepo";
//
//
@Before // @Before
public void init() { // public void init() {
} // }
//
@Test // @Test
public void registryTempOD() { // public void registryTempOD() {
//
} // }
//
@Test // @Test
public void retrieve() { // public void retrieve() {
try { // try {
DoipClientImpl doipClient = new DoipClientImpl(); // DoipClientImpl doipClient = new DoipClientImpl();
doipClient.connect("tcp://127.0.0.1:18002"); // doipClient.connect("tcp://127.0.0.1:18002");
//86.5000.470/do.Yie0yPsjt4_bdw // //86.5000.470/do.Yie0yPsjt4_bdw
List<DoipMessage> ret = new ArrayList<>(); // List<DoipMessage> ret = new ArrayList<>();
DoipMessage msg = (new DoipMessageFactory.DoipMessageBuilder()).createRequest("86.5000.470/Counter", BasicOperations.Retrieve.getName()) // DoipMessage msg = (new DoipMessageFactory.DoipMessageBuilder()).createRequest("86.5000.470/Counter", BasicOperations.Retrieve.getName())
.setBody("{\"operation\":\"count\",\"arg\":\"\"}".getBytes(StandardCharsets.UTF_8)).create(); // .setBody("{\"operation\":\"count\",\"arg\":\"\"}".getBytes(StandardCharsets.UTF_8)).create();
doipClient.sendMessage(msg, new DoipMessageCallback() { // doipClient.sendMessage(msg, new DoipMessageCallback() {
@Override // @Override
public void onResult(DoipMessage doipMessage) { // public void onResult(DoipMessage doipMessage) {
ret.add(doipMessage); // ret.add(doipMessage);
synchronized (ret) { // synchronized (ret) {
ret.notify(); // ret.notify();
} // }
} // }
}); // });
synchronized (ret) { // synchronized (ret) {
ret.wait(5000); // ret.wait(5000);
} // }
DoipMessage result = null; // DoipMessage result = null;
if (ret.size() > 0) // if (ret.size() > 0)
result = ret.get(0); // result = ret.get(0);
System.out.println(result.body.getDataAsJsonString()); // System.out.println(result.body.getDataAsJsonString());
// GlobalIrpClient.getGlobalClient().reRegister(doHandleRecord); // // GlobalIrpClient.getGlobalClient().reRegister(doHandleRecord);
} catch (Exception e) { // } catch (Exception e) {
e.printStackTrace(); // e.printStackTrace();
} // }
} // }
//
@Test // @Test
public void call() { // public void call() {
//
} // }
} //}