feat: update SelfAdaptiveShardingExecutor

use merkle to manage transactions in blocks
This commit is contained in:
Frank.R.Wu 2021-11-17 09:41:07 +08:00
parent 837cf8ba70
commit 8c86d4e767

View File

@ -13,10 +13,7 @@ import org.bdware.sc.util.JsonUtil;
import org.bdware.server.action.p2p.MasterServerRecoverMechAction;
import org.bdware.server.action.p2p.MasterServerTCPAction;
import java.util.Arrays;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ScheduledFuture;
@ -97,7 +94,9 @@ public class SelfAdaptiveShardingExecutor implements ContractExecutor {
block.prevHash,
block.requests.length,
block.timestamp));
if (!executedBlocks.contains(block.hash)) {
if (!toExecuted.containsKey(block.prevHash) &&
!executedBlocks.contains(block.hash) &&
block.isValid()) {
toExecuted.put(block.prevHash, block);
synchronized (flag) {
flag.notify();
@ -149,7 +148,7 @@ public class SelfAdaptiveShardingExecutor implements ContractExecutor {
for (int i = 0; i < requests.length; ++i) {
requests[i] = reqQueue.poll();
}
this.b.fillBlock(null, requests);
this.b.fillBlock(requests);
return this.b;
}
@ -157,6 +156,7 @@ public class SelfAdaptiveShardingExecutor implements ContractExecutor {
String prevHash = "0";
String hash;
String checkPoint;
String body;
ContractRequest[] requests;
long timestamp;
@ -167,14 +167,46 @@ public class SelfAdaptiveShardingExecutor implements ContractExecutor {
this.prevHash = prev;
}
public void fillBlock(String cp, ContractRequest[] requests) {
this.checkPoint = cp;
public void fillBlock(ContractRequest[] requests) {
this.requests = requests;
this.timestamp = System.currentTimeMillis();
hash = HashUtil.sha3(
prevHash,
cp,
Arrays.stream(requests).map(ContractRequest::getRequestID).collect(Collectors.joining()));
this.body = merkle(requests);
this.hash = computeHash();
}
public boolean isValid() {
return computeHash().equals(hash) && body.equals(merkle(this.requests));
}
private String computeHash() {
return HashUtil.sha3(
this.prevHash,
this.checkPoint,
this.body);
}
private String merkle(ContractRequest[] requests) {
if (requests.length == 0) {
return null;
}
if (requests.length == 1) {
return HashUtil.sha3(requests[0].getRequestID());
}
Queue<String> reqQueue =
Arrays.stream(requests).map(ContractRequest::getRequestID)
.collect(Collectors.toCollection(ArrayDeque::new));
do {
int size;
for (size = reqQueue.size(); size > 1; size -= 2) {
reqQueue.add(HashUtil.sha3(reqQueue.poll(), reqQueue.poll()));
}
if (size == 1) {
reqQueue.add(reqQueue.poll());
}
} while (1 != reqQueue.size());
return reqQueue.poll();
}
}
}