feat: update SelfAdaptiveSharding

set delay of period task to 1s
This commit is contained in:
Frank.R.Wu 2022-01-25 20:24:39 +08:00
parent ea71e8a358
commit 78366fcb55

View File

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